diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 376ef74b1f..1c392e4bc6 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -57,17 +57,13 @@ jobs: build_linux: strategy: fail-fast: false - # Build both arches on every event (PRs included), through the same - # build_check_cache -> build_deps -> build_orca chain (the AppImage). - # aarch64 always uses the GitHub-hosted arm runner (there is no arm - # self-hosted server). amd64's empty arch is load-bearing: it keeps the - # historical 'linux-clang' deps cache key and the unsuffixed asset names. + # SELF_HOSTED skips arm64 (no arm self-hosted server). amd64's empty arch + # is load-bearing: it keeps the historical 'linux-clang' deps cache key and + # the unsuffixed asset names. matrix: - include: - - arch: "" - os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }} - - arch: "aarch64" - os: ubuntu-24.04-arm + include: ${{ fromJSON(vars.SELF_HOSTED + && '[{"arch":"","os":"orca-lnx-server"}]' + || '[{"arch":"","os":"ubuntu-24.04"},{"arch":"aarch64","os":"ubuntu-24.04-arm"}]') }} # Don't run scheduled builds on forks: if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }} uses: ./.github/workflows/build_check_cache.yml @@ -80,18 +76,16 @@ jobs: name: Build Windows ${{ matrix.arch }} strategy: fail-fast: false + # SELF_HOSTED skips arm64 (the self-hosted Windows server is x64-only). matrix: - include: - - arch: x64 - os: windows-latest - - arch: arm64 - os: windows-11-arm + include: ${{ fromJSON(vars.SELF_HOSTED + && '[{"arch":"x64","os":"orca-win-server"}]' + || '[{"arch":"x64","os":"windows-latest"},{"arch":"arm64","os":"windows-11-arm"}]') }} # Don't run scheduled builds on forks: if: ${{ !cancelled() && (github.event_name != 'schedule' || github.repository == 'OrcaSlicer/OrcaSlicer') }} uses: ./.github/workflows/build_check_cache.yml with: - # Self-hosted runner is x64-only; ARM64 always uses the GitHub-hosted runner. - os: ${{ (matrix.arch == 'x64' && vars.SELF_HOSTED) && 'orca-win-server' || matrix.os }} + os: ${{ matrix.os }} arch: ${{ matrix.arch }} build-deps-only: ${{ inputs.build-deps-only || false }} force-build: ${{ github.event_name == 'schedule' }} @@ -122,54 +116,97 @@ jobs: arch: universal macos-combine-only: true secrets: inherit - unit_tests: - name: Unit Tests - # Tests are built on the aarch64 leg by default (faster GitHub arm runner), - # so run them there; self-hosted builds them on the amd64 server instead. - runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }} + # One test job per built arch, on the runner that built it. + unit_tests_linux_x86_64: + name: Linux x86_64 needs: build_linux if: ${{ !cancelled() && success() }} + uses: ./.github/workflows/unit_tests.yml + with: + os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }} + artifact: ${{ github.sha }}-tests-linux-x86_64 + unit_tests_linux_aarch64: + name: Linux aarch64 + needs: build_linux + if: ${{ !cancelled() && success() && !vars.SELF_HOSTED }} + uses: ./.github/workflows/unit_tests.yml + with: + os: ubuntu-24.04-arm + artifact: ${{ github.sha }}-tests-linux-aarch64 + unit_tests_windows_x64: + name: Windows x64 + needs: build_windows + if: ${{ !cancelled() && success() }} + uses: ./.github/workflows/unit_tests.yml + with: + os: ${{ vars.SELF_HOSTED && 'orca-win-server' || 'windows-latest' }} + artifact: ${{ github.sha }}-tests-windows-x64 + unit_tests_windows_arm64: + name: Windows arm64 + needs: build_windows + if: ${{ !cancelled() && success() && !vars.SELF_HOSTED }} + uses: ./.github/workflows/unit_tests.yml + with: + os: windows-11-arm + artifact: ${{ github.sha }}-tests-windows-arm64 + test-dir: build-arm64/tests + unit_tests_macos_arm64: + name: macOS arm64 + needs: build_macos_arch + if: ${{ !cancelled() && success() }} + uses: ./.github/workflows/unit_tests.yml + with: + os: ${{ vars.SELF_HOSTED && 'orca-macos-arm64' || 'macos-14' }} + artifact: ${{ github.sha }}-tests-macos-arm64 + test-dir: build/arm64/tests + # Slice a two-colour cube through every shipped printer so all custom g-code + # (change_filament_gcode, machine start/end, etc.) is expanded - catches + # slicing regressions the static profile checks and unit tests can't see. + # Profile-only PRs are covered by check_profiles.yml's nightly binary; this + # covers src/engine PRs with the PR-built binary. + slice_check_linux: + name: Slice check (Linux ${{ vars.SELF_HOSTED && 'x86_64' || 'aarch64' }}) + needs: build_linux + if: ${{ !cancelled() && success() }} + # Follows whichever Linux leg built the validator. + runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }} steps: - - name: Checkout + - name: Checkout repository uses: actions/checkout@v7 - with: - sparse-checkout: | - .github - scripts - tests - - name: Apt-Install Dependencies - if: ${{ !vars.SELF_HOSTED }} - uses: ./.github/actions/apt-install-deps - - name: Restore Test Artifact + - name: Download profile validator uses: actions/download-artifact@v8 with: - name: ${{ github.sha }}-tests - - uses: lukka/get-cmake@latest - with: - cmakeVersion: "~4.3.0" # use most recent 4.3.x version - useLocalCache: true # <--= Use the local cache (default is 'false'). - useCloudCache: true - - name: Unpackage and Run Unit Tests - timeout-minutes: 20 + name: ${{ github.sha }}-profile-validator-linux-${{ vars.SELF_HOSTED && 'x86_64' || 'aarch64' }} + path: validator-bin + - name: Validate slice (expand custom g-code) + timeout-minutes: 60 run: | - tar -xvf build_tests.tar - scripts/run_unit_tests.sh - - name: Upload Test Logs - uses: actions/upload-artifact@v7 - if: ${{ failure() }} + chmod +x validator-bin/OrcaSlicer_profile_validator + ./validator-bin/OrcaSlicer_profile_validator -p "${{ github.workspace }}/resources/profiles" -s -l 2 + publish_test_results: + name: Publish Test Results + needs: [unit_tests_linux_x86_64, unit_tests_linux_aarch64, unit_tests_windows_x64, unit_tests_windows_arm64, unit_tests_macos_arm64] + if: ${{ !cancelled() }} + runs-on: ubuntu-latest + steps: + - name: Download Test Results + uses: actions/download-artifact@v8 with: - name: unit-test-logs - path: build/tests/**/*.log + pattern: test-results-* + path: test-results + # Best-effort: a read-only token (e.g. fork PRs) can't write the check, so + # don't let a publish failure fail the run. The test jobs gate correctness. - name: Publish Test Results - if: always() + continue-on-error: true uses: EnricoMi/publish-unit-test-result-action@v2 with: - files: "ctest_results.xml" - - name: Delete Test Artifact + files: "test-results/**/*.xml" + - name: Delete Test Results if: success() uses: geekyeggo/delete-artifact@v6 with: - name: ${{ github.sha }}-tests + name: test-results-* + failOnError: false flatpak: name: "Flatpak" container: diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index ffe4c35f8d..c243b94d2e 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -141,8 +141,26 @@ jobs: - name: Build slicer mac if: runner.os == 'macOS' && !inputs.macos-combine-only working-directory: ${{ github.workspace }} + # arm64 only: build the tests here; the unit_tests_macos job runs them. + env: + ORCA_TESTS_BUILD_ONLY: ${{ inputs.arch == 'arm64' && '1' || '' }} run: | - ./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 + ./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 ${{ inputs.arch == 'arm64' && '-T' || '' }} + + - name: Pack unit tests mac + if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64' + working-directory: ${{ github.workspace }} + run: tar -cvf build_tests.tar build/arm64/tests + + - name: Upload Test Artifact mac + if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64' + uses: actions/upload-artifact@v7 + with: + name: ${{ github.sha }}-tests-macos-arm64 + overwrite: true + path: build_tests.tar + retention-days: 5 + if-no-files-found: error - name: Pack macOS app bundle ${{ inputs.arch }} if: runner.os == 'macOS' && !inputs.macos-combine-only @@ -335,11 +353,28 @@ jobs: # env: # WindowsSdkDir: 'C:\Program Files (x86)\Windows Kits\10\' # WindowsSDKVersion: '10.0.26100.0\' + # "tests" builds the unit tests too; the unit_tests_windows_* jobs run them. run: | $arch = "${{ inputs.arch }}" - if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 } else { .\build_release_vs.bat slicer } + if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 tests } else { .\build_release_vs.bat slicer tests } shell: pwsh + - name: Pack unit tests Win + if: runner.os == 'Windows' + working-directory: ${{ github.workspace }} + shell: pwsh + run: tar -cvf build_tests.tar ${{ env.BUILD_DIR }}/tests + + - name: Upload Test Artifact Win + if: runner.os == 'Windows' + uses: actions/upload-artifact@v7 + with: + name: ${{ github.sha }}-tests-windows-${{ inputs.arch }} + overwrite: true + path: build_tests.tar + retention-days: 5 + if-no-files-found: error + # NSIS is x86-only; it runs (and the installer it emits runs) under ARM64's # x86 emulation, packaging the native arm64 payload from build-arm64. - name: Create installer Win @@ -452,31 +487,41 @@ jobs: if: runner.os == 'Linux' shell: bash run: | - # Build + tar the unit tests (-t) only on the leg that runs them: the - # aarch64 leg by default (faster GitHub arm runner), or amd64 when using - # self-hosted runners (no arm self-hosted server). unit_tests downloads - # this tarball. The profile validator is built with -s, so amd64 keeps it. - tests=${{ (!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64') }} - if $tests; then flags=-istrlL; else flags=-isrlL; fi - ./build_linux.sh "$flags" + # Build + tar the unit tests (-t) on both Linux legs so each arch + # (x86_64 + aarch64) gets tested by its own unit_tests_linux_* job. + ./build_linux.sh -istrlL ./scripts/check_appimage_libs.sh ./build/package ./build/package/bin/orca-slicer appimage=./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage "$appimage" chmod +x "$appimage" - if $tests; then tar -cvpf build_tests.tar build/tests; fi + tar -cvf build_tests.tar build/tests # Use tar because upload-artifacts won't always preserve directory structure # and doesn't preserve file permissions - name: Upload Test Artifact - if: runner.os == 'Linux' && ((!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64')) + if: runner.os == 'Linux' uses: actions/upload-artifact@v7 with: - name: ${{ github.sha }}-tests + name: ${{ github.sha }}-tests-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }} overwrite: true path: build_tests.tar retention-days: 5 if-no-files-found: error + # Ship the freshly-built validator so slice_check_linux (build_all.yml) + # can slice-sweep the shipped profiles with this PR's engine. Taken from + # the aarch64 leg so the sweep also exercises the arm build; x86_64 on + # SELF_HOSTED, which skips arm64. + - name: Upload profile validator (for slice check) + if: ${{ runner.os == 'Linux' && (vars.SELF_HOSTED && inputs.arch != 'aarch64' || !vars.SELF_HOSTED && inputs.arch == 'aarch64') }} + uses: actions/upload-artifact@v7 + with: + name: ${{ github.sha }}-profile-validator-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }} + overwrite: true + path: ./build/src/Release/OrcaSlicer_profile_validator + retention-days: 5 + if-no-files-found: error + - name: Run external slicer regression tests if: runner.os == 'Linux' && inputs.arch != 'aarch64' timeout-minutes: 20 diff --git a/.github/workflows/check_profiles.yml b/.github/workflows/check_profiles.yml index 5f8f3d9e07..59c92e3ec0 100644 --- a/.github/workflows/check_profiles.yml +++ b/.github/workflows/check_profiles.yml @@ -49,6 +49,15 @@ jobs: set +e ./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 2>&1 | tee ${{ runner.temp }}/validate_system.log exit ${PIPESTATUS[0]} + # Slice a two-colour cube through every printer so all custom g-code (incl. change_filament_gcode) + # is expanded - catches undefined-placeholder / invalid-flow bugs the static checks above cannot see. + - name: validate slice (expand custom g-code) + id: validate_slice + continue-on-error: true + run: | + set +e + ./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -s -l 2 2>&1 | tee ${{ runner.temp }}/validate_slice.log + exit ${PIPESTATUS[0]} # For now run filament subtype check only for BBL profiles until we fix other vendors' profiles. - name: validate filament subtype check for BBL profiles id: validate_filament_subtypes @@ -166,7 +175,7 @@ jobs: echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt - name: Prepare comment artifact - if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} + if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} run: | { # Marker matched by check_profiles_comment.yml to delete prior comments. @@ -192,6 +201,15 @@ jobs: echo "" fi + if [ "${{ steps.validate_slice.outcome }}" = "failure" ]; then + echo "### Slice Validation Failed (custom g-code expansion)" + echo "" + echo '```' + head -c 30000 ${{ runner.temp }}/validate_slice.log || echo "No output captured" + echo '```' + echo "" + fi + if [ "${{ steps.validate_filament_subtypes.outcome }}" = "failure" ]; then echo "### BBL Filament Subtype Validation Failed" echo "" @@ -223,7 +241,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_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} + if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_slice.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }} run: | echo "One or more profile checks failed. See above for details." exit 1 diff --git a/.github/workflows/dedupe-issues.yml b/.github/workflows/dedupe-issues.yml index cb0a9c0931..a8c21edd01 100644 --- a/.github/workflows/dedupe-issues.yml +++ b/.github/workflows/dedupe-issues.yml @@ -27,7 +27,7 @@ jobs: with: prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}" claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }} - claude_args: "--model claude-sonnet-4-5-20250929" + model: "claude-sonnet-4-5-20250929" claude_env: | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/pr-label-bot.yml b/.github/workflows/pr-label-bot.yml index c238c854f4..1214db0776 100644 --- a/.github/workflows/pr-label-bot.yml +++ b/.github/workflows/pr-label-bot.yml @@ -79,6 +79,92 @@ jobs: throw error; } + localization-pr: + if: github.event_name == 'pull_request_target' + permissions: + contents: read + pull-requests: write + issues: write + runs-on: ubuntu-latest + steps: + - name: Auto-label and remind about the localization glossary + uses: actions/github-script@v9 + with: + script: | + function isPermissionDenied(error) { + return error && error.status === 403 && /Resource not accessible by integration/i.test(error.message || ''); + } + + const pr = context.payload.pull_request; + + // List changed files once (mirrors the `localization/**` paths filter in check_locale.yml) + const files = await github.paginate(github.rest.pulls.listFiles, { + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: pr.number, + per_page: 100 + }); + const touchesLocalization = files.some((file) => file.filename.startsWith('localization/')); + const onlyPoFiles = files.length > 0 && files.every((file) => file.filename.endsWith('.po')); + + // If the PR changes only .po files, automatically apply the Localization label + if (onlyPoFiles) { + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + labels: ['Localization'] + }); + core.info('Applied Localization label (PR changes only .po files).'); + } catch (error) { + if (isPermissionDenied(error)) { + core.warning('Cannot add Localization label because token cannot write.'); + } else { + throw error; + } + } + } + + if (!touchesLocalization) { + core.info('No localization changes detected; skipping glossary reminder.'); + return; + } + + // Avoid posting the reminder twice (e.g. on reopen) + const marker = ''; + const comments = await github.paginate(github.rest.issues.listComments, { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + per_page: 100 + }); + if (comments.some((comment) => (comment.body || '').includes(marker))) { + core.info('Glossary reminder already present; skipping.'); + return; + } + + try { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: pr.number, + body: + `${marker}\n` + + `Hi @${pr.user.login}, this PR changes translations (\`localization/**\`).\n\n` + + `Please make sure recurring terms follow the [Localization glossary](https://www.orcaslicer.com/wiki/localization_glossary), ` + + `so the same English term is always rendered the same way within a language and terms that must stay in English ` + + `(brand/product names, acronyms, file formats, G-code, macros/variables) are not translated.` + }); + } catch (error) { + if (isPermissionDenied(error)) { + core.warning('Skipping glossary reminder because token cannot write comments.'); + return; + } + + throw error; + } + apply-label: if: github.event_name == 'issue_comment' permissions: diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml new file mode 100644 index 0000000000..5f54f6581d --- /dev/null +++ b/.github/workflows/unit_tests.yml @@ -0,0 +1,77 @@ +name: Unit Tests + +# Download a platform's test artifact, run ctest, and upload the JUnit +# results for aggregation. Called once per arch from build_all.yml. +on: + workflow_call: + inputs: + os: + required: true + type: string + artifact: + description: Test artifact uploaded by the build leg + required: true + type: string + test-dir: + description: Built tests dir; defaults to build/tests, override for arch-separated builds + required: false + type: string + default: build/tests + +jobs: + unit_tests: + # Static "Unit Tests"; the per-arch label is the caller's job name, so the + # graph shows e.g. "Windows x64 / Unit Tests". + name: Unit Tests + runs-on: ${{ inputs.os }} + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + # Tests reach outside tests/ at runtime: tests/data (TEST_DATA_DIR) and + # resources/profiles (PROFILES_DIR) by baked-in absolute path, plus + # resources/info (nozzle data) via resources_dir() during a real slice. + # Check out all of resources/ so no test hits a missing-file path. + sparse-checkout: | + .github + scripts + tests + resources + - name: Apt-Install Dependencies + if: runner.os == 'Linux' && !vars.SELF_HOSTED + uses: ./.github/actions/apt-install-deps + - name: Restore Test Artifact + uses: actions/download-artifact@v8 + with: + name: ${{ inputs.artifact }} + - uses: lukka/get-cmake@latest + with: + cmakeVersion: "~4.3.0" # use most recent 4.3.x version + useLocalCache: true + useCloudCache: true + - name: Unpackage and Run Unit Tests + timeout-minutes: 20 + shell: bash + run: | + tar -xvf build_tests.tar + # Multi-config generators (Windows/macOS) need a config; Linux is single-config. + scripts/run_unit_tests.sh "${{ inputs.test-dir }}" "${{ runner.os != 'Linux' && 'Release' || '' }}" + - name: Upload Test Logs + if: ${{ failure() }} + uses: actions/upload-artifact@v7 + with: + name: unit-test-logs-${{ inputs.artifact }} + path: ${{ inputs.test-dir }}/**/*.log + - name: Upload Test Results + if: always() + uses: actions/upload-artifact@v7 + with: + name: test-results-${{ inputs.artifact }} + path: ctest_results.xml + retention-days: 5 + if-no-files-found: warn + - name: Delete Test Artifact + if: success() + uses: geekyeggo/delete-artifact@v6 + with: + name: ${{ inputs.artifact }} diff --git a/AGENTS.md b/AGENTS.md index 3ebfccd0c0..3b5620181b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -55,3 +55,11 @@ ctest --test-dir ./tests/fff_print - Add helper functions or utilities only when existing code cannot reasonably be reused. Avoid duplication. - Keep code concise and clear. Manually simplify AI generated bloated codes before review. - Include targeted tests or documented verification for behavior changes, especially in slicing logic, profiles, formats, and GUI defaults. +- For translation changes (`localization/i18n/**/*.po`), check that recurring terms match the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) for that language. + +## Localization & translations + +- Translation catalogs live in `localization/i18n//OrcaSlicer_.po`. +- When creating or reviewing translations, use the [Localization glossary](https://github.com/OrcaSlicer/OrcaSlicer_WIKI/blob/main/guides/localization_glossary.md) as the source of truth for recurring terms, so the same English term is always rendered the same way within a language and terms that must stay in English (brand/product names, acronyms, file formats, G-code, macros/variables) are not translated. +- If a term's established translation changes, update both the affected `.po` files and the glossary so they stay in sync. +- Only edit `msgstr` (never `msgid`); keep placeholders (`%s`, `%1%`, `\n`), context (`msgctxt`), and file encoding/line endings intact. diff --git a/build_release_macos.sh b/build_release_macos.sh index 8d417695ad..1a86d2c515 100755 --- a/build_release_macos.sh +++ b/build_release_macos.sh @@ -59,7 +59,7 @@ while getopts ":dpa:snt:xbc:i:1Tuh" opt; do echo " -c: Set CMake build configuration, default is Release" echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew" echo " -1: Use single job for building" - echo " -T: Build and run tests" + echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)" exit 0 ;; * ) @@ -209,13 +209,10 @@ function build_slicer() { cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET" ) - if [ "1." == "$BUILD_TESTS". ]; then - echo "Running tests for $_ARCH..." - ( - set -x - cd "$PROJECT_BUILD_DIR" - ctest --build-config "$BUILD_CONFIG" --output-on-failure - ) + # -T also runs the tests; ORCA_TESTS_BUILD_ONLY=1 builds them without + # running, so CI can build here and run them in a dedicated job. + if [ "1." == "$BUILD_TESTS". ] && [ "1." != "$ORCA_TESTS_BUILD_ONLY". ]; then + "$PROJECT_DIR/scripts/run_unit_tests.sh" "build/$_ARCH/tests" "$BUILD_CONFIG" fi echo "Verify localization with gettext..." diff --git a/build_release_vs.bat b/build_release_vs.bat index 0c1334d5f7..3288beda4c 100644 --- a/build_release_vs.bat +++ b/build_release_vs.bat @@ -20,6 +20,12 @@ for %%a in (%*) do ( if "%%a"=="-x" set USE_NINJA=1 ) +@REM Check for unit-tests option ("tests") +set BUILD_TESTS=OFF +for %%a in (%*) do ( + if /I "%%a"=="tests" set BUILD_TESTS=ON +) + if "%USE_NINJA%"=="1" ( echo Using Ninja Multi-Config generator set CMAKE_GENERATOR="Ninja Multi-Config" @@ -145,10 +151,10 @@ cd %build_dir% echo on set CMAKE_POLICY_VERSION_MINIMUM=3.5 if "%USE_NINJA%"=="1" ( - cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type% + cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% cmake --build . --config %build_type% --target ALL_BUILD ) else ( - cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type% + cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type% cmake --build . --config %build_type% --target ALL_BUILD -- -m ) @echo off diff --git a/localization/i18n/OrcaSlicer.pot b/localization/i18n/OrcaSlicer.pot index b50789a152..3cbb4500ce 100644 --- a/localization/i18n/OrcaSlicer.pot +++ b/localization/i18n/OrcaSlicer.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -39,6 +39,24 @@ msgstr "" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -51,6 +69,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "" @@ -60,10 +81,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, possible-c-format, possible-boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, possible-c-format, possible-boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "" + +msgid "Hardened Steel" +msgstr "" + +msgid "Stainless Steel" +msgstr "" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "" @@ -94,6 +195,85 @@ msgstr "" msgid "Latest version" msgstr "" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "" + +msgid "Error" +msgstr "" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "" + +msgid "Refreshing" +msgstr "" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + msgid "Support Painting" msgstr "" @@ -163,6 +343,12 @@ msgstr "" msgid "Gap Fill" msgstr "" +msgid "Vertical" +msgstr "" + +msgid "Horizontal" +msgstr "" + #, possible-boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "" @@ -255,12 +441,6 @@ msgstr "" msgid "Height Range" msgstr "" -msgid "Vertical" -msgstr "" - -msgid "Horizontal" -msgstr "" - msgid "Remove painted color" msgstr "" @@ -325,6 +505,7 @@ msgstr "" msgid "Optimize orientation" msgstr "" +msgctxt "Verb" msgid "Scale" msgstr "" @@ -368,6 +549,9 @@ msgstr "" msgid "Object operations" msgstr "" +msgid "Scale" +msgstr "" + msgid "Volume operations" msgstr "" @@ -413,6 +597,10 @@ msgstr "" msgid "Reset current rotation to real zeros." msgstr "" +msgctxt "Noun" +msgid "Scale" +msgstr "" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "" @@ -590,9 +778,6 @@ msgstr "" msgid "Confirm connectors" msgstr "" -msgid "Cancel" -msgstr "" - msgid "Flip cut plane" msgstr "" @@ -633,10 +818,10 @@ msgstr "" msgid "Reset cutting plane and remove connectors" msgstr "" -msgid "Perform cut" +msgid "Reset Cut" msgstr "" -msgid "Warning" +msgid "Perform cut" msgstr "" msgid "Invalid connectors detected" @@ -669,6 +854,13 @@ msgstr "" msgid "Connector" msgstr "" +#, possible-boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "" @@ -715,9 +907,6 @@ msgstr "" msgid "Simplification is currently only allowed when a single part is selected" msgstr "" -msgid "Error" -msgstr "" - msgid "Extra high" msgstr "" @@ -1946,6 +2135,9 @@ msgstr "" msgid "Loading user preset" msgstr "" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, possible-c-format, possible-boost-format msgid "%s has been removed." msgstr "" @@ -1959,6 +2151,18 @@ msgstr "" msgid "Language" msgstr "" +#, possible-c-format, possible-boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "" @@ -2552,6 +2756,45 @@ msgstr "" msgid "Click the icon to shift this object to the bed" msgstr "" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "" @@ -2561,6 +2804,9 @@ msgstr "" msgid "Failed to get the model data in the current file." msgstr "" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "" @@ -2573,6 +2819,12 @@ msgstr "" msgid "Remove paint-on fuzzy skin" msgstr "" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "" + msgid "Delete connector from object which is a part of cut" msgstr "" @@ -2598,12 +2850,24 @@ msgstr "" msgid "Deleting the last solid part is not allowed." msgstr "" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "" +msgid "Split to parts" +msgstr "" + msgid "Assembly" msgstr "" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "" @@ -2634,6 +2898,9 @@ msgstr "" msgid "Settings for height range" msgstr "" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "" @@ -2655,6 +2922,9 @@ msgstr "" msgid "Choose part type" msgstr "" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "" @@ -2682,6 +2952,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "" @@ -2691,9 +2964,6 @@ msgstr "" msgid "to" msgstr "" -msgid "Remove height range" -msgstr "" - msgid "Add height range" msgstr "" @@ -2896,6 +3166,9 @@ msgstr "" msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3017,6 +3290,24 @@ msgstr "" msgid "Check filament location" msgstr "" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3068,6 +3359,62 @@ msgstr "" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3381,15 +3728,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "" - msgid "AMS Materials Setting" msgstr "" -msgid "Confirm" -msgstr "" - msgid "Close" msgstr "" @@ -3408,10 +3749,10 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "" -msgid "SN" +msgid "Factors of Flow Dynamics Calibration" msgstr "" -msgid "Factors of Flow Dynamics Calibration" +msgid "Wiki Guide" msgstr "" msgid "PA Profile" @@ -3499,6 +3840,7 @@ msgstr "" msgid "Save" msgstr "" +msgctxt "Navigation" msgid "Back" msgstr "" @@ -3573,6 +3915,19 @@ msgstr "" msgid "Nozzle" msgstr "" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, possible-c-format, possible-boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4204,9 +4559,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "" - msgid "Update successful." msgstr "" @@ -4712,9 +5064,6 @@ msgstr "" msgid "Regroup filament" msgstr "" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "" @@ -4748,7 +5097,7 @@ msgstr "" msgid "Fan speed (%)" msgstr "" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "" msgid "Volumetric flow rate (mm³/s)" @@ -4766,9 +5115,6 @@ msgstr "" msgid "Options" msgstr "" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "" @@ -4781,6 +5127,7 @@ msgstr "" msgid "Color change" msgstr "" +msgctxt "Noun" msgid "Print" msgstr "" @@ -4936,11 +5283,15 @@ msgstr "" msgid "Align to Y axis" msgstr "" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "" + +msgctxt "Camera View" msgid "Left" msgstr "" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "" @@ -4965,9 +5316,6 @@ msgstr "" msgid "Split to objects" msgstr "" -msgid "Split to parts" -msgstr "" - msgid "Assembly View" msgstr "" @@ -5257,6 +5605,10 @@ msgstr "" msgid "Export G-code file" msgstr "" +msgctxt "Verb" +msgid "Print" +msgstr "" + msgid "Export plate sliced file" msgstr "" @@ -5430,15 +5782,6 @@ msgstr "" msgid "Export" msgstr "" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "" @@ -5553,6 +5896,15 @@ msgstr "" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5670,6 +6022,9 @@ msgstr "" msgid "Select profile to load:" msgstr "" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, possible-c-format, possible-boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5824,9 +6179,6 @@ msgstr "" msgid "Batch manage files." msgstr "" -msgid "Refresh" -msgstr "" - msgid "Reload file list from printer." msgstr "" @@ -6127,6 +6479,9 @@ msgstr "" msgid "Safety Options" msgstr "" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "" @@ -6160,6 +6515,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6208,9 +6569,6 @@ msgstr "" msgid "Silent" msgstr "" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "" @@ -6244,6 +6602,12 @@ msgstr "" msgid "Delete Photo" msgstr "" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "" @@ -6417,6 +6781,9 @@ msgstr "" msgid "Don't show this dialog again" msgstr "" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "" @@ -6662,25 +7029,16 @@ msgstr "" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "" - -msgid "Stainless Steel" -msgstr "" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" +msgid "No wiki link available for this printer." msgstr "" msgid "Unavailable while heating maintenance function is on." @@ -6805,6 +7163,15 @@ msgstr "" msgid "Configuration incompatible" msgstr "" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "" + msgid "Sync printer information" msgstr "" @@ -6831,6 +7198,9 @@ msgstr "" msgid "Project Filaments" msgstr "" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "" @@ -7039,9 +7409,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "" - msgid "The file does not contain any geometry data." msgstr "" @@ -7084,9 +7451,21 @@ msgid "" "After that, model consistency can't be guaranteed." msgstr "" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7111,6 +7490,9 @@ msgstr "" msgid "File for the replacement wasn't selected" msgstr "" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7157,6 +7539,9 @@ msgstr "" msgid "Error during reload" msgstr "" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "" @@ -7886,6 +8271,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -7901,16 +8295,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8183,6 +8568,9 @@ msgstr "" msgid "My Printer" msgstr "" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8201,6 +8589,9 @@ msgstr "" msgid "Edit preset" msgstr "" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "" @@ -8231,9 +8622,6 @@ msgstr "" msgid "Create printer" msgstr "" -msgid "Empty" -msgstr "" - msgid "Incompatible" msgstr "" @@ -8456,11 +8844,41 @@ msgstr "" msgid "Error code" msgstr "" -msgid "High Flow" +msgid "Error desc" +msgstr "" + +msgid "Extra info" +msgstr "" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, possible-c-format, possible-boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, possible-c-format, possible-boost-format @@ -8523,7 +8941,37 @@ msgstr "" msgid "nozzle" msgstr "" -msgid "both extruders" +#, possible-c-format, possible-boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, possible-c-format, possible-boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8537,10 +8985,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, possible-c-format, possible-boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, possible-c-format, possible-boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, possible-c-format, possible-boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -8650,9 +9105,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -8829,6 +9281,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "" @@ -8895,9 +9350,6 @@ msgstr "" msgid "Adjust" msgstr "" -msgid "Ignore" -msgstr "" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "" @@ -9377,6 +9829,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, possible-c-format, possible-boost-format msgid "" " - %s:\n" @@ -9588,6 +10046,12 @@ msgstr "" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "" @@ -9833,11 +10297,7 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" -msgstr "" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" +msgid "Do you want to continue to sync filaments?" msgstr "" msgid "Successfully synchronized filament color from printer." @@ -9943,6 +10403,9 @@ msgstr "" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10249,6 +10712,9 @@ msgstr "" msgid "Where to find your printer's IP and Access Code?" msgstr "" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "" @@ -10311,6 +10777,9 @@ msgstr "" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "" @@ -10329,6 +10798,9 @@ msgstr "" msgid "Update successful" msgstr "" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "" @@ -10428,6 +10900,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "" @@ -11073,7 +11548,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11087,7 +11562,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11463,9 +11938,6 @@ msgid "" "0 to deactivate." msgstr "" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "" @@ -11475,9 +11947,6 @@ msgstr "" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "" -msgid "Select profiles" -msgstr "" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "" @@ -11711,6 +12180,42 @@ msgstr "" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "" @@ -11994,12 +12499,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12252,6 +12763,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "" @@ -12311,12 +12828,12 @@ msgstr "" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -12801,6 +13318,15 @@ msgstr "" msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -12860,6 +13386,12 @@ msgid "" "G-code command: M106 P3 S(0-255)" msgstr "" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "" @@ -13357,6 +13889,30 @@ msgstr "" msgid "Minimum travel speed (M205 T)" msgstr "" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "" @@ -13857,6 +14413,9 @@ msgstr "" msgid "Bowden" msgstr "" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -13890,6 +14449,12 @@ msgstr "" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "" @@ -13920,6 +14485,9 @@ msgstr "" msgid "Aligned back" msgstr "" +msgid "Back" +msgstr "" + msgid "Random" msgstr "" @@ -14169,6 +14737,12 @@ msgstr "" msgid "Traditional" msgstr "" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "" @@ -14254,6 +14828,18 @@ msgstr "" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "" @@ -14608,7 +15194,7 @@ msgid "" msgstr "" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -14657,6 +15243,45 @@ msgstr "" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "" @@ -14695,12 +15320,30 @@ msgstr "" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "" @@ -14965,6 +15608,57 @@ msgstr "" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "" +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "" @@ -15697,12 +16391,6 @@ msgstr "" msgid "Calibration not supported" msgstr "" -msgid "Error desc" -msgstr "" - -msgid "Extra info" -msgstr "" - msgid "Flow Dynamics" msgstr "" @@ -15875,6 +16563,12 @@ msgstr "" msgid "The name cannot exceed 40 characters." msgstr "" +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "" @@ -15964,9 +16658,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "" @@ -16037,6 +16728,10 @@ msgstr "" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "" +#, possible-c-format, possible-boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "" @@ -17686,6 +18381,12 @@ msgstr "" msgid "Removed" msgstr "" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -17719,12 +18420,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "" +#, possible-c-format, possible-boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -17956,9 +18670,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "" - msgid "Null Color" msgstr "" diff --git a/localization/i18n/ca/OrcaSlicer_ca.po b/localization/i18n/ca/OrcaSlicer_ca.po index 9f18508808..5e45f1a3c5 100644 --- a/localization/i18n/ca/OrcaSlicer_ca.po +++ b/localization/i18n/ca/OrcaSlicer_ca.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2025-03-15 10:55+0100\n" "Last-Translator: \n" "Language-Team: \n" @@ -40,6 +40,24 @@ msgstr "El TPU no és compatible amb AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "L'AMS no és compatible amb 'Bambu Lab PET-CF'." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Feu un cold pull abans d'imprimir TPU per evitar obstruccions. Podeu fer servir el manteniment de cold pull a la impressora." @@ -52,6 +70,9 @@ msgstr "El PVA humit és flexible i es pot encallar a l'extrusor. Assequeu-lo ab msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "La superfície rugosa del PLA Glow pot accelerar el desgast del sistema AMS, especialment dels components interns de l'AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Els filaments CF / GF són durs i trencadissos, És fàcil trencar-se o quedar-se atrapat en AMS, si us plau, utilitzeu amb precaució." @@ -61,10 +82,90 @@ msgstr "El PPS-CF és fràgil i es podria trencar al tub PTFE corbat sobre el ca msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "El PPA-CF és fràgil i es podria trencar al tub PTFE corbat sobre el capçal d'impressió." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s no és compatible amb l'extrusor %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Alt flux" + +msgid "Standard" +msgstr "Estàndard" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Desconegut" + +msgid "Hardened Steel" +msgstr "Acer Endurit" + +msgid "Stainless Steel" +msgstr "Acer Inoxidable" + +msgid "Tungsten Carbide" +msgstr "Carbur de tungstè" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Advertència" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "Actualitzar" + msgid "Current AMS humidity" msgstr "Humitat actual de l'AMS" @@ -95,6 +196,85 @@ msgstr "Versió:" msgid "Latest version" msgstr "Última versió" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Buit" + +msgid "Error" +msgstr "" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Actualitzar" + +msgid "Refreshing" +msgstr "Actualitzant" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "Cancel·lar" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Versió" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Pintar suports" @@ -167,6 +347,12 @@ msgstr "Farcir" msgid "Gap Fill" msgstr "Farcir el buit" +msgid "Vertical" +msgstr "" + +msgid "Horizontal" +msgstr "Horitzontal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Permet pintar només les facetes seleccionades per: \"%1%\"" @@ -262,12 +448,6 @@ msgstr "" msgid "Height Range" msgstr "Rang d'alçada" -msgid "Vertical" -msgstr "" - -msgid "Horizontal" -msgstr "Horitzontal" - msgid "Remove painted color" msgstr "Elimina el color pintat" @@ -332,6 +512,7 @@ msgstr "Gizmo-Rotació" msgid "Optimize orientation" msgstr "Optimitzar l'orientació" +msgctxt "Verb" msgid "Scale" msgstr "Escalar" @@ -376,6 +557,9 @@ msgstr "Ràtios d'escala" msgid "Object operations" msgstr "Operacions amb objectes" +msgid "Scale" +msgstr "Escalar" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Operacions de volum" @@ -427,6 +611,10 @@ msgstr "Restableix la rotació actual al valor d'quan s'ha obert l'eina de rotac msgid "Reset current rotation to real zeros." msgstr "Restableix la rotació actual a zeros reals." +msgctxt "Noun" +msgid "Scale" +msgstr "Escalar" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Mida" @@ -609,9 +797,6 @@ msgstr "Proporció espacial en relació al radi" msgid "Confirm connectors" msgstr "Confirmar connectors" -msgid "Cancel" -msgstr "Cancel·lar" - msgid "Flip cut plane" msgstr "Capgira el pla de tall" @@ -652,12 +837,12 @@ msgstr "Separa en parts" msgid "Reset cutting plane and remove connectors" msgstr "Restableix el pla de tall i elimina els connectors" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Realitzar tall" -msgid "Warning" -msgstr "Advertència" - msgid "Invalid connectors detected" msgstr "S'han detectat connectors no vàlids" @@ -688,6 +873,13 @@ msgstr "El pla de tall amb solc no és vàlid" msgid "Connector" msgstr "" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Tallar pel pla" @@ -735,9 +927,6 @@ msgstr "Simplificar" msgid "Simplification is currently only allowed when a single part is selected" msgstr "La simplificació de moment només es permet quan se selecciona una sola peça" -msgid "Error" -msgstr "" - msgid "Extra high" msgstr "Extra alt" @@ -2012,6 +2201,9 @@ msgstr "" msgid "Loading user preset" msgstr "Carregant perfil d'usuari" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2025,6 +2217,18 @@ msgstr "Seleccioneu l'idioma" msgid "Language" msgstr "Idioma" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2658,6 +2862,45 @@ msgstr "Feu clic a la icona per editar la pintura en color de l'objecte" msgid "Click the icon to shift this object to the bed" msgstr "Feu clic a la icona per situar aquest objecte al llit" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "S'està carregant el fitxer" @@ -2667,6 +2910,9 @@ msgstr "" msgid "Failed to get the model data in the current file." msgstr "No s'han pogut obtenir les dades del model al fitxer actual." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Genèric" @@ -2679,6 +2925,12 @@ msgstr "Canvar al mode de configuració per objecte per editar la configuració msgid "Remove paint-on fuzzy skin" msgstr "Elimina la pell difusa pintada" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Suprimir interval d'alçada" + msgid "Delete connector from object which is a part of cut" msgstr "Suprimir el connector de l'objecte que forma part del tall" @@ -2709,12 +2961,24 @@ msgstr "Suprimir tots els connectors" msgid "Deleting the last solid part is not allowed." msgstr "No es permet suprimir l'última part sòlida." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "L'objecte de destinació conté només una part i no es pot dividir." +msgid "Split to parts" +msgstr "Separar en peces" + msgid "Assembly" msgstr "Muntatge" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Informació dels connectors de tall" @@ -2748,6 +3012,9 @@ msgstr "Intervals d'alçada" msgid "Settings for height range" msgstr "Configuració de l'interval d'alçada" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Capa" @@ -2770,6 +3037,9 @@ msgstr "Tipus:" msgid "Choose part type" msgstr "Tria el tipus de peça" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Introduïu un nom nou" @@ -2797,6 +3067,9 @@ msgstr "\"%s\" superarà 1 milió de cares després d'aquesta subdivisió, cosa msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "La malla de la part \"%s\" conté errors. Repareu-la primer." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Perfil de processament addicional" @@ -2806,9 +3079,6 @@ msgstr "Suprimeix el paràmetre" msgid "to" msgstr "a" -msgid "Remove height range" -msgstr "Suprimir interval d'alçada" - msgid "Add height range" msgstr "Afegir un interval d'alçada" @@ -3020,6 +3290,9 @@ msgstr "Trieu una ranura AMS i premeu el botó \"Carregar\" o \"Descarregar\" pe msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "El tipus de filament és desconegut, però és necessari per realitzar aquesta acció. Establiu la informació del filament de destinació." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Canviar la velocitat del ventilador durant la impressió pot afectar la qualitat d'impressió, trieu amb cura." @@ -3142,6 +3415,24 @@ msgstr "Confirmació d'extrussió" msgid "Check filament location" msgstr "Comprovar la localització del filament" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "La temperatura màxima no pot superar " @@ -3195,6 +3486,62 @@ msgstr "Mode de desenvolupament" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Extruder" +msgstr "Extrusor" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "Informació del broquet" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Ignorar" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3529,15 +3876,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Versió" - msgid "AMS Materials Setting" msgstr "Configuració de materials AMS" -msgid "Confirm" -msgstr "Confirmar" - msgid "Close" msgstr "Tancar" @@ -3556,12 +3897,12 @@ msgstr "mín" msgid "The input value should be greater than %1% and less than %2%" msgstr "El valor d'entrada ha de ser superior a %1% i inferior a %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Factors de Calibratge de les Dinàmiques de Flux" +msgid "Wiki Guide" +msgstr "Guia Wiki" + msgid "PA Profile" msgstr "Perfil PA( Pressure Advance )" @@ -3652,7 +3993,7 @@ msgstr "Calibratge completat. Trobeu la línia d'extrusió més uniforme al vost msgid "Save" msgstr "Desar" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Darrera" @@ -3736,6 +4077,19 @@ msgstr "Broquet dret" msgid "Nozzle" msgstr "Broquet( nozzle )" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "Seleccioneu filament" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Nota: el tipus de filament (%s) no coincideix amb el tipus de filament (%s) del fitxer de tall. Si voleu utilitzar aquesta ranura, podeu instal·lar %s en lloc de %s i canviar la informació de la ranura a la pàgina 'Dispositiu'." @@ -4448,9 +4802,6 @@ msgstr "Mesurant superfície" msgid "Calibrating the detection position of nozzle clumping" msgstr "Calibrant la posició de detecció d'acumulació al broquet" -msgid "Unknown" -msgstr "Desconegut" - msgid "Update successful." msgstr "L'actualització s'ha realitzat correctament." @@ -4962,9 +5313,6 @@ msgstr "Estableix a l'òptim" msgid "Regroup filament" msgstr "Reagrupa filaments" -msgid "Wiki Guide" -msgstr "Guia Wiki" - msgid "up to" msgstr "fins a" @@ -5001,8 +5349,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Velocitat Ventilador ( % )" -msgid "Temperature (°C)" -msgstr "Temperatura ( °C )" +msgid "Temperature (℃)" +msgstr "Temperatura ( ℃ )" msgid "Volumetric flow rate (mm³/s)" msgstr "Taxa de flux volumètric ( mm³/seg )" @@ -5020,9 +5368,6 @@ msgstr "Canvis de filaments" msgid "Options" msgstr "Opcions" -msgid "Extruder" -msgstr "Extrusor" - msgid "Cost" msgstr "" @@ -5035,6 +5380,7 @@ msgstr "Canvis d'eina" msgid "Color change" msgstr "Canvi de color" +msgctxt "Noun" msgid "Print" msgstr "Imprimir" @@ -5198,11 +5544,15 @@ msgstr "Evitar la regió de calibratge d'extrusió" msgid "Align to Y axis" msgstr "Alinear a l'eix Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Darrera" + +msgctxt "Camera View" msgid "Left" msgstr "Esquerra" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Dreta" @@ -5227,9 +5577,6 @@ msgstr "Ordenar els objectes en plaques seleccionades" msgid "Split to objects" msgstr "Separar en objectes" -msgid "Split to parts" -msgstr "Separar en peces" - msgid "Assembly View" msgstr "Vista de muntatge" @@ -5531,6 +5878,10 @@ msgstr "Imprimir placa d'impressió" msgid "Export G-code file" msgstr "Exportar el fitxer del Codi-G" +msgctxt "Verb" +msgid "Print" +msgstr "Imprimir" + msgid "Export plate sliced file" msgstr "Exportar fitxer de la placa laminada" @@ -5704,15 +6055,6 @@ msgstr "Exportar la configuració actual a fitxers" msgid "Export" msgstr "Exportar" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Surt" @@ -5829,6 +6171,15 @@ msgstr "Vista" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5949,6 +6300,9 @@ msgstr "Resultat de l'exportació" msgid "Select profile to load:" msgstr "Seleccioneu el perfil que voleu carregar:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6113,9 +6467,6 @@ msgstr "Baixeu els fitxers seleccionats de la impressora." msgid "Batch manage files." msgstr "Gestió per lots de fitxers." -msgid "Refresh" -msgstr "Actualitzar" - msgid "Reload file list from printer." msgstr "Tornar a carregar la llista de fitxers des de la impressora." @@ -6428,6 +6779,9 @@ msgstr "Opcions d'impressió" msgid "Safety Options" msgstr "Opcions de seguretat" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Llum" @@ -6461,6 +6815,12 @@ msgstr "Quan la impressió està en pausa, la càrrega i descàrrega de filament msgid "Current extruder is busy changing filament." msgstr "L'extrusor actual està ocupat canviant el filament." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "La ranura actual ja s'ha carregat." @@ -6511,9 +6871,6 @@ msgstr "Això només té efecte durant la impressió" msgid "Silent" msgstr "Silenciós" -msgid "Standard" -msgstr "Estàndard" - msgid "Sport" msgstr "Esportiu" @@ -6547,6 +6904,12 @@ msgstr "Afegir una foto" msgid "Delete Photo" msgstr "Eliminar Foto" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Enviar" @@ -6730,6 +7093,9 @@ msgstr "Com utilitzar el mode només LAN" msgid "Don't show this dialog again" msgstr "No tornis a mostrar aquest diàleg" +msgid "Please refer to Wiki before use->" +msgstr "Consulteu la Wiki abans d'usar ->" + msgid "3D Mouse disconnected." msgstr "S'ha desconnectat el ratolí 3D." @@ -6984,27 +7350,18 @@ msgstr "Flux" msgid "Please change the nozzle settings on the printer." msgstr "Canvieu la configuració del broquet a la impressora." -msgid "Hardened Steel" -msgstr "Acer Endurit" - -msgid "Stainless Steel" -msgstr "Acer Inoxidable" - -msgid "Tungsten Carbide" -msgstr "Carbur de tungstè" - msgid "Brass" msgstr "Llautó" msgid "High flow" msgstr "Alt flux" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "No hi ha cap enllaç wiki disponible per a aquesta impressora." -msgid "Refreshing" -msgstr "Actualitzant" - msgid "Unavailable while heating maintenance function is on." msgstr "No disponible mentre la funció de manteniment d'escalfament està activada." @@ -7127,6 +7484,15 @@ msgstr "Canvia el diàmetre" msgid "Configuration incompatible" msgstr "Configuració incompatible" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Consells" + msgid "Sync printer information" msgstr "Sincronitza la informació de la impressora" @@ -7155,6 +7521,9 @@ msgstr "Feu clic per editar el perfil" msgid "Project Filaments" msgstr "Filaments del projecte" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volums de purga" @@ -7384,9 +7753,6 @@ msgstr "La impressora connectada és %s. Ha de coincidir amb el perfil del proje msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Voleu sincronitzar la informació de la impressora i canviar automàticament el perfil?" -msgid "Tips" -msgstr "Consells" - msgid "The file does not contain any geometry data." msgstr "El fitxer no conté cap dada de geometria." @@ -7437,9 +7803,21 @@ msgstr "" "Aquesta acció trencarà una correspondència de tall.\n" "Després d'això, no es podrà garantir la coherència del model." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "L'objecte seleccionat no s'ha pogut partir." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7466,6 +7844,9 @@ msgstr "Seleccioneu un fitxer nou" msgid "File for the replacement wasn't selected" msgstr "No s'ha seleccionat el fitxer per a la substitució" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Seleccioneu la carpeta des d'on substituir" @@ -7512,6 +7893,9 @@ msgstr "No es pot tornar a carregar:" msgid "Error during reload" msgstr "S'ha produït un error durant la recàrrega" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Hi ha advertències després de laminar els models:" @@ -8284,6 +8668,15 @@ msgstr "Esborra la meva elecció per sincronitzar el perfil de la impressora des msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8299,16 +8692,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8592,6 +8976,9 @@ msgstr "Perfils incompatibles" msgid "My Printer" msgstr "La meva impressora" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filaments esquerres" @@ -8611,6 +8998,9 @@ msgstr "Afegir o Suprimir perfils" msgid "Edit preset" msgstr "Editar el perfil" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "No especificat" @@ -8642,9 +9032,6 @@ msgstr "Seleccionar/eliminar impressores ( perfils del sistema )" msgid "Create printer" msgstr "Crear impressora" -msgid "Empty" -msgstr "Buit" - msgid "Incompatible" msgstr "" @@ -8876,12 +9263,42 @@ msgstr "enviament completat" msgid "Error code" msgstr "Codi d'error" -msgid "High Flow" -msgstr "Alt flux" +msgid "Error desc" +msgstr "Descripció de l'error" + +msgid "Extra info" +msgstr "Informació addicional" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "La configuració del flux del broquet de %s(%s) no coincideix amb el fitxer de tall (%s). Assegureu-vos que el broquet instal·lat coincideixi amb la configuració de la impressora i establiu el perfil d'impressora corresponent durant el tall." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8945,8 +9362,38 @@ msgstr "Costa %dg de filament i %d canvis més que l'agrupació òptima." msgid "nozzle" msgstr "broquet" -msgid "both extruders" -msgstr "ambdós extrusors" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "La configuració del flux del broquet de %s(%s) no coincideix amb el fitxer de tall (%s). Assegureu-vos que el broquet instal·lat coincideixi amb la configuració de la impressora i establiu el perfil d'impressora corresponent durant el tall." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Consell: si heu canviat el broquet de la vostra impressora recentment, aneu a 'Dispositiu -> Parts de la impressora' per canviar la configuració del broquet." @@ -8959,10 +9406,17 @@ msgstr "El diàmetre %s (%.1fmm) de la impressora actual no coincideix amb el fi msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "El diàmetre del broquet actual (%.1fmm) no coincideix amb el fitxer de tall (%.1fmm). Assegureu-vos que el broquet instal·lat coincideixi amb la configuració de la impressora i establiu el perfil d'impressora corresponent durant el tall." +msgid "both extruders" +msgstr "ambdós extrusors" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "La duresa del material actual (%s) supera la duresa de %s(%s). Verifiqueu la configuració del broquet o del material i torneu-ho a provar." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] requereix imprimir en un entorn d'alta temperatura. Tanqueu la porta." @@ -9073,9 +9527,6 @@ msgstr "El firmware actual admet un màxim de 16 materials. Podeu reduir el nomb msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "Consulteu la Wiki abans d'usar ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "El firmware actual no admet la transferència de fitxers a l'emmagatzematge intern." @@ -9259,6 +9710,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Feu clic per restablir tots els paràmetres a l'última configuració desada." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "La Torre de Purga és necessària per a un timelapse suau. Pot haver-hi defectes en el model sense Torre de Purga. Esteu segur que voleu desactivar la Torre de Purga?" @@ -9341,9 +9795,6 @@ msgstr "Voleu ajustar el rang automàticament?\n" msgid "Adjust" msgstr "Ajustar" -msgid "Ignore" -msgstr "Ignorar" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Característica experimental: Retreure i tallar el filament a major distància durant els canvis de filaments per minimitzar el flux. Tot i que pot reduir notablement el flux, també pot elevar el risc d'esclops de broquets o altres complicacions d'impressió." @@ -9847,6 +10298,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Segur que voleu %1% el perfil seleccionat?" +msgid "Select printers" +msgstr "Seleccioneu impressores" + +msgid "Select profiles" +msgstr "Seleccioneu perfils" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10074,6 +10531,12 @@ msgstr "Transfereix valors d'esquerra a dreta" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Si està habilitat, aquest diàleg es pot utilitzar per transferir els valors seleccionats del perfil esquerra cap a la dreta." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Afegir arxiu" @@ -10329,12 +10792,8 @@ msgstr "Informació del broquet sincronitzada correctament." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Informació del broquet i nombre d'AMS sincronitzats correctament." -msgid "Continue to sync filaments" -msgstr "Continua sincronitzant filaments" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Cancel·la" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Color del filament sincronitzat correctament de la impressora." @@ -10442,6 +10901,9 @@ msgstr "Iniciar sessió" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Acció necessària] " @@ -10756,6 +11218,9 @@ msgstr "Nom de la impressora" msgid "Where to find your printer's IP and Access Code?" msgstr "On podeu trobar la IP i el Codi d'Accés de la impressora?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Connecta" @@ -10820,6 +11285,9 @@ msgstr "Mòdul de tall" msgid "Auto Fire Extinguishing System" msgstr "Sistema d'extinció automàtica d'incendis" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10838,6 +11306,9 @@ msgstr "S'ha produït un error en l'actualització" msgid "Update successful" msgstr "Actualització correcta" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Segur que vols actualitzar? Trigarà uns 10 minuts. No l'apagueu mentre la impressora s'actualitza." @@ -10946,6 +11417,9 @@ msgstr "Error d'agrupació: " msgid " can not be placed in the " msgstr " no es pot col·locar al " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Pont Interior" @@ -11659,7 +12133,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11673,7 +12147,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12117,9 +12591,6 @@ msgstr "" "La geometria es simplificarà abans de detectar angles pronunciats. Aquest paràmetre indica la longitud mínima de la desviació per a la simplificació.\n" "0 per desactivar" -msgid "Select printers" -msgstr "Seleccioneu impressores" - msgid "upward compatible machine" msgstr "màquina compatible ascendent" @@ -12130,9 +12601,6 @@ msgstr "Condició" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Una expressió booleana fent servir valors de configuració d'un perfil existent. Si aquesta expressió és certa, el perfil es considera compatible amb el perfil d'impressió actiu." -msgid "Select profiles" -msgstr "Seleccioneu perfils" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Una expressió booleana que utilitza els paràmetres de configuració d'un perfil d'impressió actiu. Si aquesta expressió s'avalua com a certa, aquest perfil es considera compatible amb el perfil d'impressió actiu." @@ -12405,6 +12873,42 @@ msgstr "Densitat de la superfície superior" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Densitat de la capa de superfície superior. Un valor del 100% crea una capa superior completament sòlida i llisa. Reduir aquest valor resulta en una superfície superior texturada, segons el patró de superfície superior triat. Un valor del 0% resultarà en la creació de només les parets a la capa superior. Destinat a fins estètics o funcionals, no per solucionar problemes com la sobreextrusió." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Patró de superfície inferior" @@ -12735,12 +13239,18 @@ msgstr "Automàtic per a purga" msgid "Auto For Match" msgstr "Automàtic per a coincidència" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "Temperatura de purga" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatura durant la purga del filament. 0 indica el límit superior del rang de temperatura del broquet recomanat." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Velocitat volumètrica de purga" @@ -13008,6 +13518,12 @@ msgstr "Filament imprimible" msgid "The filament is printable in extruder." msgstr "El filament és imprimible a l'extrusor." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Temperatura d'estovament" @@ -13070,12 +13586,12 @@ msgstr "Densitat de farciment poc dens" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Densitat de farciment poc dens, converteix el 100% tu el teu farciment poc dens en farciment sòlid i s'utilitzarà el patró de farciment sòlid intern" -msgid "Align infill direction to model" -msgstr "Alinea la direcció del farciment al model" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13594,6 +14110,15 @@ msgstr "Millor auto posicionament dels objectes a l'interval [0,1] respecte a la msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Activeu aquesta opció si la màquina té ventilador auxiliar de refrigeració de peces. Comanda de Codi-G: M106 P2 S ( 0-255 )." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" @@ -13666,6 +14191,12 @@ msgstr "" "Habiliteu-lo si la impressora admet la filtració d'aire\n" "Comanda de Codi-G: M106 P3 S ( 0-255 )" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "Tipus de Codi-G" @@ -14193,6 +14724,30 @@ msgstr "Velocitat mínima de desplaçament" msgid "Minimum travel speed (M205 T)" msgstr "Velocitat mínima de desplaçament ( M205 T )" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Màxima acceleració d'extrusió" @@ -14742,6 +15297,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -14777,6 +15335,12 @@ msgstr "Velocitat de detracció" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Velocitat per recarregar el filament al broquet. Zero significa la mateixa velocitat de retracció." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Utilitza la retracció del firmware" @@ -14808,6 +15372,10 @@ msgstr "Alineat" msgid "Aligned back" msgstr "Alineat al darrere" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Darrera" + msgid "Random" msgstr "Aleatori" @@ -15079,6 +15647,12 @@ msgstr "Si se selecciona el mode suau o tradicional, es generarà un vídeo time msgid "Traditional" msgstr "Tradicional" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Variació de temperatura" @@ -15166,6 +15740,18 @@ msgstr "Purgar tots els extrusors d'impressió" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Si està habilitat, tots els extrusors d'impressió seran purgats a la vora frontal del llit d'impressió al començament de la impressió." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Radi de tancament dels buits en laminar" @@ -15557,7 +16143,7 @@ msgstr "" "Si està activat, aquest paràmetre també estableix una variable de codi g anomenada chamber_temperature, que es pot utilitzar per passar la temperatura de la cambra desitjada a la macro d'inici d'impressió, o una macro de remull tèrmic com aquesta: PRINT_START (altres variables) CHAMBER_TEMP=[chamber_temperature]. Això pot ser útil si la vostra impressora no admet les ordres M141/M191, o si voleu gestionar el remull de calor a la macro d'inici d'impressió si no hi ha instal·lat un escalfador de cambra actiu." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15612,6 +16198,45 @@ msgstr "Gruix mínim de la carcassa superior" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "El nombre de capes sòlides superiors augmenta quan es tallen si el gruix calculat per les capes de closca superior és més prim que aquest valor. Això pot evitar tenir una closca massa fina quan l'alçada de la capa és petita. 0 significa que aquesta configuració està desactivada i que el gruix de la carcassa superior està absolutament determinat per les capes de la carcassa superior" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Velocitat de desplaçament més ràpida i sense extrusió" @@ -15660,6 +16285,12 @@ msgstr "Multiplicador de neteja" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "El volum de neteja real és igual al valor del multiplicador de neteja multiplicat pels volums de neteja especificats a la taula." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Volum de purga" @@ -15667,6 +16298,18 @@ msgstr "Volum de purga" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "El volum de material que l'extrusora ha de descarregar a la Torre de Purga." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Amplada de la Torre de Purga" @@ -15960,6 +16603,57 @@ msgstr "Amplada mínima del perímetre" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Amplada del perímetre que substituirà als elements prims ( segons la mida mínima de l'element ) del model. Si l'amplada mínima del perímetre és més fina que el gruix de l'element el perímetre esdevindrà tan gruixut com el propi element. S'expressa en percentatge sobre el diàmetre del broquet" +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Detectar de farciment sòlid intern estret" @@ -16714,12 +17408,6 @@ msgstr "" msgid "Calibration not supported" msgstr "No s'admet calibratge" -msgid "Error desc" -msgstr "Descripció de l'error" - -msgid "Extra info" -msgstr "Informació addicional" - msgid "Flow Dynamics" msgstr "Dinàmiques de Flux" @@ -16926,6 +17614,12 @@ msgstr "Introduïu el nom que voleu assignar a la impressora." msgid "The name cannot exceed 40 characters." msgstr "El nom no pot superar els 40 caràcters." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Busqueu la millor línia a la placa" @@ -17016,9 +17710,6 @@ msgstr "La informació de l'AMS i del broquet estan sincronitzades" msgid "Nozzle Flow" msgstr "Flux del broquet" -msgid "Nozzle Info" -msgstr "Informació del broquet" - msgid "Filament position" msgstr "posició del filament" @@ -17093,6 +17784,10 @@ msgstr "Èxit per obtenir resultats històrics" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Actualitzar els registres històrics de Calibratge de Dinàmiques de Flux" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "Acció" @@ -18855,6 +19550,12 @@ msgstr "Impressió Fallida" msgid "Removed" msgstr "Eliminat" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "No m'ho recordis més" @@ -18888,12 +19589,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "(Sincronitza amb la impressora)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Tallarem segons aquest mètode d'agrupació:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Consell: podeu arrossegar els filaments per reassignar-los a broquets diferents." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "El mètode d'agrupació de filaments per a la placa actual està determinat per l'opció desplegable al botó de la placa de tall." @@ -19126,9 +19840,6 @@ msgstr "Aquesta acció no es pot desfer. Continuar?" msgid "Skipping objects." msgstr "Ometent objectes." -msgid "Select Filament" -msgstr "Seleccioneu filament" - msgid "Null Color" msgstr "Sense color" @@ -19647,6 +20358,19 @@ msgstr "" "Evitar la deformació( warping )\n" "Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?" +#~ msgid "Continue to sync filaments" +#~ msgstr "Continua sincronitzant filaments" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Cancel·la" + +#~ msgid "Align infill direction to model" +#~ msgstr "Alinea la direcció del farciment al model" + +#~ msgid "Print" +#~ msgstr "Imprimir" + #~ msgid "in" #~ msgstr "polç" @@ -20423,9 +21147,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "No es pot iniciar sense la targeta SD." -#~ msgid "Update" -#~ msgstr "Actualitzar" - #~ msgid "Sensitivity of pausing is" #~ msgstr "La sensibilitat de la pausa és" @@ -21103,10 +21824,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Desmarcar" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Escalar" - #~ msgid "Lift Z Enforcement" #~ msgstr "Forçar elevació Z" diff --git a/localization/i18n/cs/OrcaSlicer_cs.po b/localization/i18n/cs/OrcaSlicer_cs.po index a5bdbb3ed9..d18cc9ca4d 100644 --- a/localization/i18n/cs/OrcaSlicer_cs.po +++ b/localization/i18n/cs/OrcaSlicer_cs.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: Jakub Hencl\n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPU není podporováno AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS nepodporuje „Bambu Lab PET-CF“." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Před tiskem z TPU proveďte cold pull, abyste předešli ucpání trysky.Na tiskárně můžete provést údržbu pomocí metody cold pull." @@ -47,6 +65,9 @@ msgstr "Navlhlé (vlhké) PVA je pružné a může se zaseknout v extruderu. Př msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "Hrubý povrch PLA Glow může urychlit opotřebení systému AMSzejména vnitřních součástí AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF filamenty jsou tvrdé a křehké, snadno se lámou nebo zasekávají v AMS, používejte opatrně." @@ -56,10 +77,90 @@ msgstr "PPS-CF je křehký a může se zlomit v ohnuté PTFE trubičce nad tisko msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF je křehký a může se zlomit v ohnuté PTFE trubičce nad tiskovou hlavou." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s není podporováno extruderem %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "TPU vysoký průtok" + +msgid "Unknown" +msgstr "Neznámé" + +msgid "Hardened Steel" +msgstr "Kalená ocel" + +msgid "Stainless Steel" +msgstr "Nerezová ocel" + +msgid "Tungsten Carbide" +msgstr "Karbid wolframu" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Tisková hlava a držák hotendu se mohou pohybovat. Držte ruce mimo komoru." + +msgid "Warning" +msgstr "Varování" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Informace o hotendu mohou být nepřesné. Chcete hotend znovu načíst? (Informace o hotendu se mohou po vypnutí změnit.)" + +msgid "I confirm all" +msgstr "Potvrzuji vše" + +msgid "Re-read all" +msgstr "Znovu načíst vše" + +msgid "Reading the hotends, please wait." +msgstr "Načítání hotendů, prosím čekejte." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Během aktualizace hotendu se bude tisková hlava pohybovat. Nevkládejte ruce do komory." + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "Aktuální vlhkost AMS" @@ -90,6 +191,85 @@ msgstr "Verze:" msgid "Latest version" msgstr "Nejnovější verze" +msgid "Row A" +msgstr "Řada A" + +msgid "Row B" +msgstr "Řada B" + +msgid "Toolhead" +msgstr "Tisková hlava" + +msgid "Empty" +msgstr "Prázdné" + +msgid "Error" +msgstr "Chyba" + +msgid "Induction Hotend Rack" +msgstr "Indukční držák hotendu" + +msgid "Hotends Info" +msgstr "Informace o hotendech" + +msgid "Read All" +msgstr "Načíst vše" + +msgid "Reading " +msgstr "Načítání " + +msgid "Please wait" +msgstr "Prosím čekejte" + +msgid "Running..." +msgstr "Probíhá spouštění..." + +msgid "Raised" +msgstr "Zvednuté" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Hotend je v neobvyklém stavu a momentálně není k dispozici. Přejděte do 'Zařízení -> Upgrade' pro aktualizaci firmwaru." + +msgid "Abnormal Hotend" +msgstr "Hotend v neobvyklém stavu" + +msgid "Refresh" +msgstr "Obnovit" + +msgid "Refreshing" +msgstr "Obnovování" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Stav hotendu je abnormální a momentálně není dostupný. Aktualizujte firmware a zkuste to znovu." + +msgid "Cancel" +msgstr "Zrušit" + +msgid "Jump to the upgrade page" +msgstr "Přejít na stránku upgradu" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Verze" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Použitý čas: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Na aktuální podložce jsou přiřazeny dynamické trysky. Výběr hotendu není podpěrován." + +msgid "Hotend Rack" +msgstr "Stojan na hotend" + +msgid "ToolHead" +msgstr "Tisková hlava" + +msgid "Nozzle information needs to be read" +msgstr "Je nutné načíst informace o trysce" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Malování podpory" @@ -162,6 +342,12 @@ msgstr "Výplň" msgid "Gap Fill" msgstr "Vyplnění mezery" +msgid "Vertical" +msgstr "Vertikální" + +msgid "Horizontal" +msgstr "Vodorovně" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Umožňuje malování pouze na plochách vybraných podle: \"%1%\"" @@ -257,12 +443,6 @@ msgstr "Trojúhelník" msgid "Height Range" msgstr "Rozsah výšky" -msgid "Vertical" -msgstr "Vertikální" - -msgid "Horizontal" -msgstr "Vodorovně" - msgid "Remove painted color" msgstr "Odstranit nanesenou barvu" @@ -327,6 +507,7 @@ msgstr "Gizmo-Otočit" msgid "Optimize orientation" msgstr "Optimalizovat orientaci" +msgctxt "Verb" msgid "Scale" msgstr "Měřítko" @@ -371,6 +552,9 @@ msgstr "Poměry měřítka" msgid "Object operations" msgstr "Operace s objektem" +msgid "Scale" +msgstr "Měřítko" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Operace s hlasitostí" @@ -422,6 +606,10 @@ msgstr "Obnovit aktuální rotaci na hodnotu při otevření nástroje pro rotac msgid "Reset current rotation to real zeros." msgstr "Obnovit aktuální rotaci na skutečné nuly." +msgctxt "Noun" +msgid "Scale" +msgstr "Měřítko" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Velikost" @@ -604,9 +792,6 @@ msgstr "Podíl mezery vůči poloměru" msgid "Confirm connectors" msgstr "Potvrdit konektory" -msgid "Cancel" -msgstr "Zrušit" - msgid "Flip cut plane" msgstr "Převrátit rovinu řezu" @@ -647,12 +832,12 @@ msgstr "Rozdělit na části" msgid "Reset cutting plane and remove connectors" msgstr "Resetovat řezací rovinu a odstranit konektory" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Provést řez" -msgid "Warning" -msgstr "Varování" - msgid "Invalid connectors detected" msgstr "Zjištěny neplatné konektory" @@ -685,6 +870,13 @@ msgstr "Řezací rovina s drážkou je neplatná" msgid "Connector" msgstr "Konektor" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Řezat podle roviny" @@ -732,9 +924,6 @@ msgstr "Zjednodušit" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Zjednodušení je aktuálně povoleno pouze při výběru jednoho dílu" -msgid "Error" -msgstr "Chyba" - msgid "Extra high" msgstr "Extra vysoká" @@ -2010,6 +2199,9 @@ msgstr "Přístup k balíčku %s není autorizován." msgid "Loading user preset" msgstr "Načítání uživatelské předvolby" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s bylo odstraněno." @@ -2023,6 +2215,18 @@ msgstr "Zvolte jazyk" msgid "Language" msgstr "Jazyk" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2658,6 +2862,45 @@ msgstr "Kliknutím na ikonu upravíte barevné malování objektu." msgid "Click the icon to shift this object to the bed" msgstr "Kliknutím na ikonu přesunete tento objekt na podložku." +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Načítání souboru" @@ -2667,6 +2910,9 @@ msgstr "Chyba!" msgid "Failed to get the model data in the current file." msgstr "Nepodařilo se získat data modelu v aktuálním souboru." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Obecné" @@ -2679,6 +2925,12 @@ msgstr "Přepnout do režimu nastavení podle objektu pro úpravu nastavení pro msgid "Remove paint-on fuzzy skin" msgstr "Odstranit nanesenou fuzzy skin" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Odstranit rozsah výšky" + msgid "Delete connector from object which is a part of cut" msgstr "Smazat konektor z objektu, který je součástí řezu" @@ -2709,12 +2961,24 @@ msgstr "Smazat všechny konektory" msgid "Deleting the last solid part is not allowed." msgstr "Smazání poslední pevné části není povoleno." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Cílový objekt obsahuje pouze jednu část a nelze jej rozdělit." +msgid "Split to parts" +msgstr "Rozdělit na části" + msgid "Assembly" msgstr "Sestava" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Informace o řezacích spojích" @@ -2748,6 +3012,9 @@ msgstr "Rozsahy výšky" msgid "Settings for height range" msgstr "Nastavení pro rozsah výšky" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Vrstva" @@ -2770,6 +3037,9 @@ msgstr "Typ:" msgid "Choose part type" msgstr "Vyberte typ dílu" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Zadejte nový název" @@ -2799,6 +3069,9 @@ msgstr "„%s“ bude mít po tomto dělení více než 1 milion ploch, což mů msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "Síť části „%s“ obsahuje chyby. Nejprve ji opravte." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Další procesní předvolba" @@ -2808,9 +3081,6 @@ msgstr "Odstranit parametr" msgid "to" msgstr "do" -msgid "Remove height range" -msgstr "Odstranit rozsah výšky" - msgid "Add height range" msgstr "Přidat rozsah výšky" @@ -3021,6 +3291,9 @@ msgstr "Vyberte slot AMS a poté stiskněte tlačítko \"Načíst\" nebo \"Vysun msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Typ filamentu není znám, což je pro provedení této akce vyžadováno. Nastavte informace o cílovém filamentu." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Změna rychlosti ventilátoru během tisku může ovlivnit kvalitu tisku, proto vybírejte opatrně." @@ -3143,6 +3416,24 @@ msgstr "Potvrdit extruzi" msgid "Check filament location" msgstr "Zkontrolujte polohu filamentu" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Maximální teplota nesmí překročit " @@ -3195,6 +3486,62 @@ msgstr "Vývojářský režim" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Nastavte prosím počet trysek" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Chyba: Není možné nastavit počet trysek na nulu." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Chyba: Počet trysek nesmí překročit %d." + +msgid "Confirm" +msgstr "Potvrdit" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "Výběr trysky" + +msgid "Available Nozzles" +msgstr "Dostupné trysky" + +msgid "Nozzle Info" +msgstr "Informace o trysce" + +msgid "Sync Nozzle status" +msgstr "Synchronizovat stav trysky" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Pozor: Kombinace různých průměrů trysek v jednom tisku není podporována. Pokud je zvolená velikost pouze na jednom extruderu, bude vynucen tisk jedním extruderem." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Obnovit %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Zjištěna neznámá tryska. Proveďte aktualizaci informací (neaktualizované trysky budou při řezání vyloučeny). Ověřte průměr trysky a průtok vzhledem k zobrazeným hodnotám." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Zjištěna neznámá tryska. Proveďte aktualizaci (neaktualizované trysky budou při slicování přeskočeny)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Ověřte prosím, zda požadovaný průměr trysky a průtok odpovídají aktuálně zobrazeným hodnotám." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Vaše tiskárna má nainstalované různé trysky. Vyberte prosím trysku pro tento tisk." + +msgid "Ignore" +msgstr "Ignorovat" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3528,15 +3875,9 @@ msgstr "OrcaSlicer vznikl ve stejném duchu a vycházel z projektů PrusaSlicer, msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Dnes je OrcaSlicer nejpoužívanějším a nejaktivněji vyvíjeným open-source slicerem v komunitě 3D tisku. Mnoho jeho inovací převzaly i další slicery, díky čemuž se stal hnací silou celého odvětví." -msgid "Version" -msgstr "Verze" - msgid "AMS Materials Setting" msgstr "Nastavení materiálů AMS" -msgid "Confirm" -msgstr "Potvrdit" - msgid "Close" msgstr "Zavřít" @@ -3555,12 +3896,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "Vstupní hodnota musí být větší než %1% a menší než %2%." -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Faktory kalibrace dynamiky průtoku" +msgid "Wiki Guide" +msgstr "Wiki příručka" + msgid "PA Profile" msgstr "PA profil" @@ -3651,7 +3992,7 @@ msgstr "Kalibrace byla dokončena. Najděte na vyhřívané podložce nejrovnom msgid "Save" msgstr "Uložit" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Zpět" @@ -3735,6 +4076,19 @@ msgstr "Pravá tryska" msgid "Nozzle" msgstr "Tryska" +msgid "Select Filament && Hotends" +msgstr "Vyberte filament a hotendy" + +msgid "Select Filament" +msgstr "" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Tisk s aktuální tryskou může vyprodukovat navíc %0.2f g odpadu." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Poznámka: typ filamentu (%s) neodpovídá typu filamentu (%s) v souboru pro slicování. Pokud chcete tento slot použít, můžete místo %s nainstalovat %s a změnit informace o slotu na stránce „Zařízení“." @@ -4445,9 +4799,6 @@ msgstr "Měření povrchu" msgid "Calibrating the detection position of nozzle clumping" msgstr "Kalibrace detekční pozice usazenin na trysce" -msgid "Unknown" -msgstr "Neznámé" - msgid "Update successful." msgstr "Aktualizace proběhla úspěšně." @@ -4959,9 +5310,6 @@ msgstr "Nastavit optimální" msgid "Regroup filament" msgstr "Znovu seskupit filament" -msgid "Wiki Guide" -msgstr "Wiki příručka" - msgid "up to" msgstr "až do" @@ -4998,8 +5346,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Rychlost ventilátoru (%)" -msgid "Temperature (°C)" -msgstr "Teplota (°C)" +msgid "Temperature (℃)" +msgstr "Teplota (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Rychlost průtoku (mm³/s)" @@ -5017,9 +5365,6 @@ msgstr "Výměny filamentu" msgid "Options" msgstr "Možnosti" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "Náklady" @@ -5032,6 +5377,7 @@ msgstr "Výměny nástrojů" msgid "Color change" msgstr "Změna barvy" +msgctxt "Noun" msgid "Print" msgstr "Tisk" @@ -5195,11 +5541,15 @@ msgstr "Vyhněte se kalibrační oblasti extruze" msgid "Align to Y axis" msgstr "Zarovnat na osu Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Zpět" + +msgctxt "Camera View" msgid "Left" msgstr "Levý" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Pravý" @@ -5224,9 +5574,6 @@ msgstr "Rozložit objekty na vybraných deskách" msgid "Split to objects" msgstr "Rozdělit na objekty" -msgid "Split to parts" -msgstr "Rozdělit na části" - msgid "Assembly View" msgstr "Zobrazení sestavy" @@ -5527,6 +5874,10 @@ msgstr "Tisková deska" msgid "Export G-code file" msgstr "Exportovat G-code soubor" +msgctxt "Verb" +msgid "Print" +msgstr "Tisk" + msgid "Export plate sliced file" msgstr "Exportovat nařezaný soubor desky" @@ -5700,15 +6051,6 @@ msgstr "Exportovat aktuální konfiguraci do souborů" msgid "Export" msgstr "" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Ukončit" @@ -5825,6 +6167,15 @@ msgstr "Zobrazit" msgid "Preset Bundle" msgstr "Balík předvoleb" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5946,6 +6297,9 @@ msgstr "Exportovat výsledek" msgid "Select profile to load:" msgstr "Vyberte profil k načtení:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6115,9 +6469,6 @@ msgstr "Stáhnout vybrané soubory z tiskárny." msgid "Batch manage files." msgstr "Hromadná správa souborů." -msgid "Refresh" -msgstr "Obnovit" - msgid "Reload file list from printer." msgstr "Znovu načíst seznam souborů z tiskárny." @@ -6431,6 +6782,9 @@ msgstr "Možnosti tisku" msgid "Safety Options" msgstr "Bezpečnostní možnosti" +msgid "Hotends" +msgstr "Hotendy" + msgid "Lamp" msgstr "Osvětlení" @@ -6464,6 +6818,12 @@ msgstr "Při pozastaveném tisku je zavádění a vysouvání filamentu podporov msgid "Current extruder is busy changing filament." msgstr "Aktuální extruder právě mění filament." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Aktuální slot je již zaveden." @@ -6514,9 +6874,6 @@ msgstr "Tato volba má účinek pouze během tisku" msgid "Silent" msgstr "Tichý" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "" @@ -6550,6 +6907,12 @@ msgstr "Přidat fotografii" msgid "Delete Photo" msgstr "Smazat fotografii" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Odeslat" @@ -6731,6 +7094,9 @@ msgstr "Jak používat režim pouze LAN" msgid "Don't show this dialog again" msgstr "Tento dialog již nezobrazovat" +msgid "Please refer to Wiki before use->" +msgstr "Před použitím si přečtěte Wiki ->" + msgid "3D Mouse disconnected." msgstr "3D myš odpojena." @@ -6989,27 +7355,18 @@ msgstr "Průtok" msgid "Please change the nozzle settings on the printer." msgstr "Změňte prosím nastavení trysky na tiskárně." -msgid "Hardened Steel" -msgstr "Kalená ocel" - -msgid "Stainless Steel" -msgstr "Nerezová ocel" - -msgid "Tungsten Carbide" -msgstr "Karbid wolframu" - msgid "Brass" msgstr "Mosaz" msgid "High flow" msgstr "Vysoký průtok" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Pro tuto tiskárnu není k dispozici odkaz na wiki." -msgid "Refreshing" -msgstr "Obnovování" - msgid "Unavailable while heating maintenance function is on." msgstr "Není k dispozici, pokud je zapnutá funkce udržování ohřevu." @@ -7132,6 +7489,15 @@ msgstr "Přepnout průměr" msgid "Configuration incompatible" msgstr "Konfigurace není kompatibilní" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Tipy" + msgid "Sync printer information" msgstr "Synchronizovat informace o tiskárně" @@ -7160,6 +7526,9 @@ msgstr "Klikněte pro úpravu předvolby" msgid "Project Filaments" msgstr "" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Objemy proplachu" @@ -7382,9 +7751,6 @@ msgstr "Připojená tiskárna je %s. Musí odpovídat předvolbě projektu pro t msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Chcete synchronizovat informace o tiskárně a automaticky přepnout předvolbu?" -msgid "Tips" -msgstr "Tipy" - msgid "The file does not contain any geometry data." msgstr "Soubor neobsahuje žádná geometrická data." @@ -7435,9 +7801,21 @@ msgstr "" "Tato akce naruší vztah řezu.\n" "Poté nemůže být konzistence modelu zaručena." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Zvolený objekt nelze rozdělit." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Zakázat automatické položení pro zachování pozice v ose Z?\n" @@ -7464,6 +7842,9 @@ msgstr "Vyberte nový soubor" msgid "File for the replacement wasn't selected" msgstr "Soubor pro nahrazení nebyl vybrán" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Vyberte složku pro nahrazení" @@ -7510,6 +7891,9 @@ msgstr "Nelze znovu načíst:" msgid "Error during reload" msgstr "Chyba při opětovném načtení" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Po řezu modelů byla zjištěna varování:" @@ -8281,6 +8665,15 @@ msgstr "Vymazat mou volbu pro synchronizaci předvolby tiskárny po načtení so msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8296,16 +8689,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8586,6 +8970,9 @@ msgstr "Nekompatibilní předvolby" msgid "My Printer" msgstr "Moje tiskárna" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Levé filamenty" @@ -8605,6 +8992,9 @@ msgstr "Přidat/Odebrat předvolby" msgid "Edit preset" msgstr "Upravit předvolbu" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Nespecifikováno" @@ -8636,9 +9026,6 @@ msgstr "Vybrat/Odebrat tiskárny (systémové předvolby)" msgid "Create printer" msgstr "Vytvořit tiskárnu" -msgid "Empty" -msgstr "Prázdné" - msgid "Incompatible" msgstr "Nekompatibilní" @@ -8870,12 +9257,42 @@ msgstr "Odeslání dokončeno" msgid "Error code" msgstr "Kód chyby" -msgid "High Flow" +msgid "Error desc" +msgstr "Popis chyby" + +msgid "Extra info" +msgstr "Další informace" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "Nastavení průtoku trysky %s (%s) neodpovídá slicovacímu souboru (%s). Ujistěte se, že instalovaná tryska odpovídá nastavení v tiskárně, a při slicování zvolte odpovídající předvolbu tiskárny." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8939,8 +9356,38 @@ msgstr "Spotřebuje o %dg filamentu a o %d změn více než optimální seskupen msgid "nozzle" msgstr "tryska" -msgid "both extruders" -msgstr "oba extrudery" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "Nastavení průtoku trysky %s (%s) neodpovídá slicovacímu souboru (%s). Ujistěte se, že instalovaná tryska odpovídá nastavení v tiskárně, a při slicování zvolte odpovídající předvolbu tiskárny." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Tip: Pokud jste nedávno vyměnili trysku tiskárny, přejděte do „Zařízení -> Součásti tiskárny“ a upravte nastavení trysky." @@ -8953,10 +9400,17 @@ msgstr "Průměr %s (%.1f mm) aktuální tiskárny neodpovídá slicovacímu sou msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Aktuální průměr trysky (%.1f mm) neodpovídá slicovacímu souboru (%.1f mm). Ujistěte se, že instalovaná tryska odpovídá nastavení v tiskárně, a při slicování zvolte odpovídající předvolbu tiskárny." +msgid "both extruders" +msgstr "oba extrudery" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Tvrdost aktuálního materiálu (%s) překračuje tvrdost %s (%s). Zkontrolujte nastavení trysky nebo materiálu a zkuste to znovu." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] vyžaduje tisk ve vysokoteplotním prostředí. Zavřete prosím dvířka." @@ -9067,9 +9521,6 @@ msgstr "Aktuální firmware podporuje maximálně 16 materiálů. Na stránce P msgid "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." msgstr "Typ externího filamentu je neznámý nebo neodpovídá typu filamentu v slicovacím souboru. Ujistěte se, že je na externí cívce správný filament." -msgid "Please refer to Wiki before use->" -msgstr "Před použitím si přečtěte Wiki ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Aktuální firmware nepodporuje přenos souborů do interního úložiště." @@ -9251,6 +9702,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Kliknutím obnovíte všechna nastavení na poslední uloženou předvolbu." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Věž pro oddělení trysky je vyžadována pro výměnu trysky. Bez věže pro oddělení trysky mohou být na modelu vady. Opravdu chcete zakázat věž pro oddělení trysky?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Pro plynulý časosběr je vyžadována čistící věž. Bez čistící věže se mohou na modelu objevit vady. Opravdu chcete čistící věž zakázat?" @@ -9332,9 +9786,6 @@ msgstr "Automaticky upravit do nastaveného rozsahu?\n" msgid "Adjust" msgstr "Upravit" -msgid "Ignore" -msgstr "Ignorovat" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Experimentální funkce: Stažení a odstřižení filamentu na větší vzdálenost během výměny filamentu pro minimalizaci purge. Ačkoliv to může výrazně snížit purge, může to také zvýšit riziko ucpání trysky nebo jiných komplikací při tisku." @@ -9843,6 +10294,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Opravdu chcete %1% vybranou předvolbu?" +msgid "Select printers" +msgstr "Vyberte tiskárny" + +msgid "Select profiles" +msgstr "Vyberte profily" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10079,6 +10536,12 @@ msgstr "Přenést hodnoty zleva doprava" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Pokud je povoleno, toto dialogové okno lze použít k přenosu vybraných hodnot z levé do pravé předvolby." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Přidat soubor" @@ -10334,11 +10797,7 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" -msgstr "" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" +msgid "Do you want to continue to sync filaments?" msgstr "" msgid "Successfully synchronized filament color from printer." @@ -10444,6 +10903,9 @@ msgstr "" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10758,6 +11220,9 @@ msgstr "Název tiskárny" msgid "Where to find your printer's IP and Access Code?" msgstr "Kde najdete IP adresu a přístupový kód vaší tiskárny?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Připojit" @@ -10822,6 +11287,9 @@ msgstr "Řezací modul" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10840,6 +11308,9 @@ msgstr "Aktualizace se nezdařila" msgid "Update successful" msgstr "Aktualizace proběhla úspěšně" +msgid "Hotends on Rack" +msgstr "Hotendy na stojanu" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Opravdu chcete aktualizovat? To potrvá přibližně 10 minut. Během aktualizace tiskárny nevypínejte napájení." @@ -10949,6 +11420,9 @@ msgstr "Chyba seskupení: " msgid " can not be placed in the " msgstr " nelze umístit do " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Vnitřní most" @@ -11665,7 +12139,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11679,7 +12153,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12125,9 +12599,6 @@ msgstr "" "Geometrie bude decimována před detekcí ostrých úhlů. Tento parametr určuje minimální délku odchylky pro decimaci.\n" "0 pro deaktivaci." -msgid "Select printers" -msgstr "Vyberte tiskárny" - msgid "upward compatible machine" msgstr "stroj zpětně kompatibilní" @@ -12138,9 +12609,6 @@ msgstr "Podmínka" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Booleovský výraz využívající konfigurační hodnoty aktivního profilu tiskárny. Pokud je tento výraz pravdivý, považuje se profil za kompatibilní s aktivním profilem tiskárny." -msgid "Select profiles" -msgstr "Vyberte profily" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Booleovský výraz využívající konfigurační hodnoty aktivního tiskového profilu. Pokud je tento výraz pravdivý, považuje se profil za kompatibilní s aktivním tiskovým profilem." @@ -12409,6 +12877,42 @@ msgstr "Hustota horního povrchu" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Hustota horní povrchové vrstvy. Hodnota 100 % vytvoří zcela plnou, hladkou horní vrstvu. Snížením této hodnoty vznikne texturovaný horní povrch podle zvoleného vzoru horního povrchu. Hodnota 0 % znamená, že na horní vrstvě budou vytvořeny pouze stěny. Určeno pro estetické nebo funkční účely, nikoli k řešení problémů jako je nadměrná extruze." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Vzor spodního povrchu" @@ -12741,12 +13245,18 @@ msgstr "Automaticky pro čištění" msgid "Auto For Match" msgstr "Automaticky pro přiřazení" +msgid "Nozzle Manual" +msgstr "Ručně pro trysku" + msgid "Flush temperature" msgstr "Teplota čištění" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Teplota při čištění filamentu. Hodnota 0 označuje horní hranici doporučeného rozsahu teplot trysky." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Objemová rychlost čištění" @@ -13014,6 +13524,12 @@ msgstr "Tisknutelný filament" msgid "The filament is printable in extruder." msgstr "Filament lze tisknout v extruderu." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Teplota změknutí" @@ -13076,12 +13592,12 @@ msgstr "Hustota řídké výplně" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Hustota vnitřní řídké výplně, 100 % přemění veškerou řídkou výplň na plnou a použije se vzor vnitřní plné výplně." -msgid "Align infill direction to model" -msgstr "Zarovnat směr výplně podle modelu" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13619,6 +14135,15 @@ msgstr "Nejvhodnější automaticky uspořádaná pozice v rozsahu [0,1] vzhlede msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Povolte tuto možnost, pokud má tiskárna pomocný ventilátor chlazení dílů. G-code příkaz: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13690,6 +14215,12 @@ msgstr "" "Povolte tuto možnost, pokud tiskárna podporuje filtraci vzduchu\n" "G-code příkaz: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Použít filtr pro chlazení" + +msgid "Enable this if printer support cooling filter" +msgstr "Povolte tuto možnost, pokud tiskárna podpěruje filtr pro chlazení" + msgid "G-code flavor" msgstr "" @@ -14221,6 +14752,30 @@ msgstr "Minimální rychlost přesunu" msgid "Minimum travel speed (M205 T)" msgstr "Minimální rychlost přesunu (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Maximální zrychlení pro vytlačování" @@ -14789,6 +15344,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Hybridní" + msgid "Enable filament dynamic map" msgstr "" @@ -14824,6 +15382,12 @@ msgstr "Rychlost deretrakce" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Rychlost pro zavedení filamentu do trysky. Nula znamená stejnou rychlost jako při zatahování." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Použít zatažení pomocí firmwaru" @@ -14855,6 +15419,10 @@ msgstr "Zarovnáno" msgid "Aligned back" msgstr "Zarovnat zpět" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Zpět" + msgid "Random" msgstr "Náhodně" @@ -15128,6 +15696,12 @@ msgstr "Pokud je vybrán plynulý nebo tradiční režim, bude pro každý tisk msgid "Traditional" msgstr "Tradiční" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Kolísání teploty" @@ -15215,6 +15789,18 @@ msgstr "Připravit všechny tiskové extrudery" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Pokud je povoleno, všechny tiskové extrudery budou na začátku tisku připraveny na předním okraji tiskové podložky." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Poloměr uzavření mezery řezu" @@ -15600,7 +16186,7 @@ msgstr "" "Pokud je povoleno, tento parametr rovněž nastaví G-code proměnnou s názvem chamber_temperature, kterou lze použít k předání požadované teploty komory do makra spuštění tisku, nebo do makra pro tepelnou stabilizaci, například takto: PRINT_START (další proměnné) CHAMBER_TEMP=[chamber_temperature]. To může být užitečné, pokud vaše tiskárna nepodporuje příkazy M141/M191, nebo pokud chcete provádět tepelnou stabilizaci v makru spuštění tisku, pokud není instalováno aktivní topení komory." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15654,6 +16240,45 @@ msgstr "Tloušťka horního pláště" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Počet horních pevných vrstev bude při slicování zvýšen, pokud tloušťka vypočtená podle horních vrstev bude menší než tato hodnota. Tím lze předejít příliš tenké skořepině při malé výšce vrstvy. 0 znamená, že je nastavení vypnuté a tloušťka horní skořepiny je určena pouze počtem horních vrstev." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Rychlost přejezdu bez extruze." @@ -15702,6 +16327,12 @@ msgstr "Násobitel proplachu" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Skutečné vyplachovací objemy jsou rovny násobiči vyplachování vynásobenému objemy v tabulce." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Objem základní věže" @@ -15709,6 +16340,18 @@ msgstr "Objem základní věže" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Objem materiálu pro načerpání extruderu na základní věži." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Šířka základní věže." @@ -16001,6 +16644,57 @@ msgstr "Minimální šířka stěny" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Šířka stěny, která nahradí tenké prvky (dle minimální velikosti prvku) modelu. Pokud je minimální šířka stěny menší než tloušťka prvku, bude stěna tak silná, jako je samotný prvek. Je vyjádřena jako procento průměru trysky." +msgid "Hotend change time" +msgstr "Interval výměny hotendu" + +msgid "Time to change hotend." +msgstr "Je čas vyměnit hotend." + +msgid "Hotend change" +msgstr "Výměna hotendu" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Při výměně hotendu se doporučuje vytlačit určitou délku filamentu ze stávající trysky. To pomáhá minimalizovat vytékání trysky." + +msgid "Extruder change" +msgstr "Výměna extruderu" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Aby se zabránilo vytékání, provede tryska po dokončení natlačování po určitou dobu zpětný pohyb. Toto nastavení určuje dobu pohybu." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Aby se zabránilo vytékání, bude teplota trysky během natlačování snížena. Doba natlačování proto musí být delší než doba ochlazování. 0 znamená deaktivováno." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "Maximální objemová rychlost pro vytlačování před výměnou extruderu, kde -1 znamená použití maximální objemové rychlosti." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Aby se zabránilo vytékání, bude teplota trysky během natlačování snížena. Poznámka: provede se pouze příkaz k ochlazení a aktivace ventilátoru; dosažení cílové teploty není zaručeno. 0 znamená vypnuto." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "Maximální objemový průtok pro natlačení před výměnou hotendu, kde -1 znamená použití maximálního objemového průtoku." + +msgid "length when change hotend" +msgstr "délka při výměně hotendu" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Pokud se tato hodnota retrakce změní, použije se jako množství filamentu zataženého v hotendu před výměnou hotendů." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Objem materiálu potřebný k předplnění extruderu při výměně hotendu na věži." + +msgid "Preheat temperature delta" +msgstr "Teplotní rozdíl při předehřevu" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Teplotní rozdíl použitý během předehřevu před výměnou nástroje." + msgid "Detect narrow internal solid infills" msgstr "Detekovat úzkou vnitřní plnou výplň" @@ -16754,12 +17448,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibrace není podporována" -msgid "Error desc" -msgstr "Popis chyby" - -msgid "Extra info" -msgstr "Další informace" - msgid "Flow Dynamics" msgstr "Dynamika průtoku" @@ -16966,6 +17654,12 @@ msgstr "Zadejte název, který chcete uložit do tiskárny." msgid "The name cannot exceed 40 characters." msgstr "Název nesmí přesáhnout 40 znaků." +msgid "Nozzle ID" +msgstr "ID trysky" + +msgid "Standard Flow" +msgstr "Standardní průtok" + msgid "Please find the best line on your plate" msgstr "Najděte nejlepší čáru na své desce." @@ -17056,9 +17750,6 @@ msgstr "Informace AMS a trysky jsou synchronizovány" msgid "Nozzle Flow" msgstr "Průtok trysky" -msgid "Nozzle Info" -msgstr "Informace o trysce" - msgid "Filament position" msgstr "Pozice filamentu" @@ -17133,6 +17824,10 @@ msgstr "Historie výsledků byla úspěšně načtena" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Obnovování historických záznamů kalibrace dynamiky průtoku" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Poznámka: Číslo hotendu na %s je přiřazeno k držáku. Když je hotend přesunut do nového držáku, jeho číslo se automaticky aktualizuje." + msgid "Action" msgstr "Akce" @@ -18890,6 +19585,12 @@ msgstr "Tisk se nezdařil" msgid "Removed" msgstr "Odstraněno" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -18923,12 +19624,25 @@ msgstr "Video tutoriál" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -19160,9 +19874,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "" - msgid "Null Color" msgstr "" @@ -19681,6 +20392,12 @@ msgstr "" "Zamezte kroucení\n" "Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?" +#~ msgid "Align infill direction to model" +#~ msgstr "Zarovnat směr výplně podle modelu" + +#~ msgid "Print" +#~ msgstr "Tisk" + #~ msgid "in" #~ msgstr "v" diff --git a/localization/i18n/de/OrcaSlicer_de.po b/localization/i18n/de/OrcaSlicer_de.po index 3849457ddc..052cde4e7d 100644 --- a/localization/i18n/de/OrcaSlicer_de.po +++ b/localization/i18n/de/OrcaSlicer_de.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: Heiko Liebscher \n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPU wird vom AMS nicht unterstützt." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS unterstützt 'Bambu Lab PET-CF' nicht." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Bitte vor dem Drucken von TPU einen Cold Pull durchführen, um Verstopfungen zu vermeiden. Sie können die Cold Pull Funktion des Druckers verwenden." @@ -47,6 +65,9 @@ msgstr "Feuchtes PVA ist flexibel und kann im Extruder stecken bleiben. Trocknen msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "Die raue Oberfläche von PLA Glow kann den Verschleiß des AMS-Systems beschleunigen, insbesondere der internen Komponenten des AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF-Filamente sind hart und spröde. Sie brechen leicht oder bleiben im AMS stecken. Bitte verwenden Sie sie mit Vorsicht." @@ -56,10 +77,90 @@ msgstr "PPS-CF ist spröde und könnte im gebogenen PTFE-Schlauch über dem Werk msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF ist spröde und könnte im gebogenen PTFE-Schlauch über dem Werkzeugkopf brechen." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s wird vom %s Extruder nicht unterstützt." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Hoher Fluss" + +msgid "Standard" +msgstr "Standard" + +msgid "TPU High Flow" +msgstr "TPU-High-Flow" + +msgid "Unknown" +msgstr "Unbekannt" + +msgid "Hardened Steel" +msgstr "Gehärteter Stahl" + +msgid "Stainless Steel" +msgstr "Edelstahl" + +msgid "Tungsten Carbide" +msgstr "Wolframcarbid" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Der Werkzeugkopf und das Hotend-Magazin können sich bewegen. Bitte halten Sie Ihre Hände von der Kammer fern." + +msgid "Warning" +msgstr "Warnung" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Die Hotend-Informationen sind möglicherweise ungenau. Möchten Sie das Hotend erneut auslesen? (Die Hotend-Informationen können sich während des Ausschaltvorgangs ändern)." + +msgid "I confirm all" +msgstr "Ich bestätige alle" + +msgid "Re-read all" +msgstr "Alle neu auslesen" + +msgid "Reading the hotends, please wait." +msgstr "Hotends werden ausgelesen, bitte warten." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Während des Hotend-Upgrades bewegt sich der Werkzeugkopf. Greifen Sie nicht in die Kammer." + +msgid "Update" +msgstr "Update" + msgid "Current AMS humidity" msgstr "Aktuelle AMS-Feuchtigkeit" @@ -90,6 +191,85 @@ msgstr "Version:" msgid "Latest version" msgstr "Neueste Version" +msgid "Row A" +msgstr "Reihe A" + +msgid "Row B" +msgstr "Reihe B" + +msgid "Toolhead" +msgstr "Werkzeugkopf" + +msgid "Empty" +msgstr "Leer" + +msgid "Error" +msgstr "Fehler" + +msgid "Induction Hotend Rack" +msgstr "Induktions-Hotend-Magazin" + +msgid "Hotends Info" +msgstr "Hotend-Informationen" + +msgid "Read All" +msgstr "Alle auslesen" + +msgid "Reading " +msgstr "Wird ausgelesen " + +msgid "Please wait" +msgstr "Bitte warten" + +msgid "Running..." +msgstr "Läuft..." + +msgid "Raised" +msgstr "Angehoben" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Das Hotend befindet sich in einem abnormalen Zustand und ist derzeit nicht verfügbar. Bitte gehen Sie zu „Gerät -> Upgrade“, um die Firmware zu aktualisieren." + +msgid "Abnormal Hotend" +msgstr "Abnormales Hotend" + +msgid "Refresh" +msgstr "Aktualisieren" + +msgid "Refreshing" +msgstr "Erneuern" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Hotend-Status ist abnormal, derzeit nicht verfügbar. Bitte aktualisieren Sie die Firmware und versuchen Sie es erneut." + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Jump to the upgrade page" +msgstr "Zur Upgrade-Seite springen" + +msgid "SN" +msgstr "SN" + +msgid "Version" +msgstr "Version" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Nutzungszeit: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Dynamische Düsen sind auf der aktuellen Platte zugewiesen. Die Auswahl des Hotends wird nicht unterstützt." + +msgid "Hotend Rack" +msgstr "Hotend-Magazin" + +msgid "ToolHead" +msgstr "Werkzeugkopf" + +msgid "Nozzle information needs to be read" +msgstr "Düseninformationen müssen ausgelesen werden" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Stützen aufmalen" @@ -162,6 +342,12 @@ msgstr "Ausfüllen" msgid "Gap Fill" msgstr "Lücken füllen" +msgid "Vertical" +msgstr "Vertikal" + +msgid "Horizontal" +msgstr "Horizontal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Erlaubt das malen nur auf Seiten, welche ausgewählt wurden durch: \"%1%\"" @@ -257,12 +443,6 @@ msgstr "Dreieck" msgid "Height Range" msgstr "Höhenbereich" -msgid "Vertical" -msgstr "Vertikal" - -msgid "Horizontal" -msgstr "Horizontal" - msgid "Remove painted color" msgstr "Gemalte Farbe entfernen" @@ -327,6 +507,7 @@ msgstr "Gizmo-Drehen" msgid "Optimize orientation" msgstr "Optimiere Ausrichtung" +msgctxt "Verb" msgid "Scale" msgstr "Skalieren" @@ -371,6 +552,9 @@ msgstr "Skalierungsverhältnisse" msgid "Object operations" msgstr "Objekt-Operationen" +msgid "Scale" +msgstr "Skalieren" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Volumen Operationen" @@ -422,6 +606,10 @@ msgstr "Setze die aktuelle Rotation auf den Wert zurück, als das Rotationswerkz msgid "Reset current rotation to real zeros." msgstr "Setze die aktuelle Rotation auf die realen Nullen zurück." +msgctxt "Noun" +msgid "Scale" +msgstr "Skalieren" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Größe" @@ -604,9 +792,6 @@ msgstr "Platzverhältnis in Bezug auf den Radius" msgid "Confirm connectors" msgstr "Bestätige Verbinder" -msgid "Cancel" -msgstr "Abbrechen" - msgid "Flip cut plane" msgstr "Schnittfläche umdrehen" @@ -647,12 +832,12 @@ msgstr "In Teile schneiden" msgid "Reset cutting plane and remove connectors" msgstr "Schnittfläche zurücksetzen und Verbinder entfernen" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Schnitt ausführen" -msgid "Warning" -msgstr "Warnung" - msgid "Invalid connectors detected" msgstr "Fehlerhafte Verbinder gefunden" @@ -683,6 +868,13 @@ msgstr "Schnittfläche mit Nut ist ungültig" msgid "Connector" msgstr "Verbinder" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Schnitt durch Ebene" @@ -730,9 +922,6 @@ msgstr "Vereinfachen" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Die Vereinfachung ist derzeit nur möglich, wenn ein einzelnes Teil ausgewählt ist" -msgid "Error" -msgstr "Fehler" - msgid "Extra high" msgstr "Extra hoch" @@ -2015,6 +2204,9 @@ msgstr "Zugriff auf Bundle %s ist nicht autorisiert." msgid "Loading user preset" msgstr "Benutzerprofil wird geladen" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s wurde entfernt." @@ -2028,6 +2220,18 @@ msgstr "Sprache wählen" msgid "Language" msgstr "Sprache" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2660,6 +2864,45 @@ msgstr "Klicken Sie auf das Symbol, um die Farbgebung des Objekts zu bearbeiten" msgid "Click the icon to shift this object to the bed" msgstr "Klicken Sie auf das Symbol, um dieses Objekt auf das Bett zu verschieben." +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Lade Datei" @@ -2669,6 +2912,9 @@ msgstr "Fehler!" msgid "Failed to get the model data in the current file." msgstr "Fehler beim Abrufen der Modell-Daten in der aktuellen Datei." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Generisch" @@ -2681,6 +2927,12 @@ msgstr "Wechseln Sie in den objektbezogenen Einstellungsmodus, um die Prozessein msgid "Remove paint-on fuzzy skin" msgstr "Entferne die aufgemalte, fuzzy Außenhaut" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Höhenbereich entfernen" + msgid "Delete connector from object which is a part of cut" msgstr "Lösche den Verbinder aus dem Objekt, das Teil des Schnitts ist." @@ -2712,12 +2964,24 @@ msgstr "Lösche alle Verbinder" msgid "Deleting the last solid part is not allowed." msgstr "Das Löschen des letzten festen Teils ist nicht erlaubt." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Das Zielobjekt enthält nur ein Teil und kann nicht geteilt werden." +msgid "Split to parts" +msgstr "In Teile trennen" + msgid "Assembly" msgstr "Zusammenbau" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Informationen zu den Schnitt-Verbindern" @@ -2751,6 +3015,9 @@ msgstr "Höhenbereiche" msgid "Settings for height range" msgstr "Einstellungen für den Höhenbereich" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Schicht" @@ -2773,6 +3040,9 @@ msgstr "Typ:" msgid "Choose part type" msgstr "Bauteiltyp auswählen" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Neuen Namen eingeben" @@ -2800,6 +3070,9 @@ msgstr "\"%s\" wird nach dieser Unterteilung über 1 Million Flächen haben, was msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "\"%s\" Teilnetz enthält Fehler. Bitte zuerst reparieren." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Zusätzliche Prozesseinstellung" @@ -2809,9 +3082,6 @@ msgstr "Parameter entfernen" msgid "to" msgstr "bis" -msgid "Remove height range" -msgstr "Höhenbereich entfernen" - msgid "Add height range" msgstr "Höhenbereich hinzufügen" @@ -3023,6 +3293,9 @@ msgstr "Wählen Sie einen AMS-Steckplatz aus und drücken Sie dann die Schaltfl msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Der Filamenttyp ist unbekannt, der für diese Aktion erforderlich ist. Bitte legen Sie die Informationen des Zielfilaments fest." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Das Ändern der Lüftergeschwindigkeit während des Druckens kann die Druckqualität beeinflussen. Bitte wählen Sie sorgfältig." @@ -3145,6 +3418,24 @@ msgstr "Bestätigen es wurde extrudiert" msgid "Check filament location" msgstr "Überprüfen Sie das Filament" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Die maximale Temperatur darf nicht überschritten werden " @@ -3198,6 +3489,62 @@ msgstr "Entwicklermodus" msgid "Launch troubleshoot center" msgstr "Fehlerbehebungszentrum starten" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Bitte Düsenanzahl einstellen" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Fehler: Beide Düsenanzahlen können nicht auf Null gesetzt werden." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Fehler: Die Anzahl der Düsen darf %d nicht überschreiten." + +msgid "Confirm" +msgstr "Bestätigen" + +msgid "Extruder" +msgstr "Extruder" + +msgid "Nozzle Selection" +msgstr "Düsenauswahl" + +msgid "Available Nozzles" +msgstr "Verfügbare Düsen" + +msgid "Nozzle Info" +msgstr "Düseninfo" + +msgid "Sync Nozzle status" +msgstr "Düsenstatus synchronisieren" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Achtung: Das Mischen von Düsendurchmessern in einem Druck wird nicht unterstützt. Wenn die ausgewählte Größe nur auf einem Extruder verfügbar ist, wird der Druck mit einem einzigen Extruder durchgeführt." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Aktualisiere %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Unbekannte Düse erkannt. Aktualisieren Sie, um die Informationen zu erfassen (nicht aktualisierte Düsen werden beim Slicen ausgeschlossen). Überprüfen Sie den Düsendurchmesser und die Durchflussrate anhand der angezeigten Werte." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Unbekannte Düse erkannt. Aktualisieren Sie, um die Informationen zu erfassen (nicht aktualisierte Düsen werden beim Slicen übersprungen)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Bitte überprüfen Sie, ob der erforderliche Düsendurchmesser und die Durchflussrate mit den aktuell angezeigten Werten übereinstimmen." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Ihr Drucker verfügt über verschiedene Düsen. Bitte wählen Sie eine Düse für diesen Druck aus." + +msgid "Ignore" +msgstr "Ignorieren" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3531,15 +3878,9 @@ msgstr "OrcaSlicer begann in diesem gleichen Geist, indem es von PrusaSlicer, Ba msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Heute ist OrcaSlicer der am weitesten verbreitete und aktiv entwickelte Open-Source-Slicer in der 3D-Druck-Community. Viele seiner Innovationen wurden von anderen Slicern übernommen und treiben die gesamte Industrie voran." -msgid "Version" -msgstr "Version" - msgid "AMS Materials Setting" msgstr "AMS Material Einstellung" -msgid "Confirm" -msgstr "Bestätigen" - msgid "Close" msgstr "Schließen" @@ -3558,12 +3899,12 @@ msgstr "min" msgid "The input value should be greater than %1% and less than %2%" msgstr "Der Eingabewert sollte größer als %1% und kleiner als %2% sein" -msgid "SN" -msgstr "SN" - msgid "Factors of Flow Dynamics Calibration" msgstr "Dynamische Flusskalibrierungsfaktoren" +msgid "Wiki Guide" +msgstr "Wiki-Anleitung" + msgid "PA Profile" msgstr "PA-Profil" @@ -3654,7 +3995,7 @@ msgstr "Kalibrierung abgeschlossen. Bitte suchen Sie die gleichmäßigste Extrus msgid "Save" msgstr "Speichern" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Zurück" @@ -3738,6 +4079,19 @@ msgstr "Rechte Düse" msgid "Nozzle" msgstr "Düse" +msgid "Select Filament && Hotends" +msgstr "Filament & Hotends auswählen" + +msgid "Select Filament" +msgstr "Filament auswählen" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Drucken mit der aktuellen Düse kann zu %0.2f g zusätzlichem Abfall führen." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Hinweis: Der Filamenttyp(%s) stimmt nicht mit dem Filamenttyp(%s) in der Slicing-Datei überein. Wenn Sie diesen Slot verwenden möchten, können Sie %s anstelle von %s installieren und die Slot-Informationen auf der Seite 'Gerät' ändern." @@ -4449,9 +4803,6 @@ msgstr "Oberfläche wird vermessen" msgid "Calibrating the detection position of nozzle clumping" msgstr "Kalibrierung der Erkennungsposition der Düsenverklumpung" -msgid "Unknown" -msgstr "Unbekannt" - msgid "Update successful." msgstr "Update erfolgreich." @@ -4963,9 +5314,6 @@ msgstr "Auf optimal setzen" msgid "Regroup filament" msgstr "Filament neu gruppieren" -msgid "Wiki Guide" -msgstr "Wiki-Anleitung" - msgid "up to" msgstr "bis zu" @@ -5002,8 +5350,8 @@ msgstr "Ruck (mm/s)" msgid "Fan speed (%)" msgstr "Lüftergeschwindigkeit (%)" -msgid "Temperature (°C)" -msgstr "Temperatur (°C)" +msgid "Temperature (℃)" +msgstr "Temperatur (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Volumetrische Flussrate (mm³/s)" @@ -5021,9 +5369,6 @@ msgstr "Filamentwechsel" msgid "Options" msgstr "Optionen" -msgid "Extruder" -msgstr "Extruder" - msgid "Cost" msgstr "Kosten" @@ -5036,6 +5381,7 @@ msgstr "Werkzeugwechsel" msgid "Color change" msgstr "Farbwechsel" +msgctxt "Noun" msgid "Print" msgstr "aktuelle Platte drucken" @@ -5199,11 +5545,15 @@ msgstr "Vermeiden Sie den Bereich der Extrusionskalibrierung" msgid "Align to Y axis" msgstr "An Y-Achse ausrichten" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Zurück" + +msgctxt "Camera View" msgid "Left" msgstr "links" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "rechts" @@ -5228,9 +5578,6 @@ msgstr "Objekte auf ausgewählten Druckplatten anordnen" msgid "Split to objects" msgstr "In Objekte trennen" -msgid "Split to parts" -msgstr "In Teile trennen" - msgid "Assembly View" msgstr "Montageansicht" @@ -5529,6 +5876,10 @@ msgstr "Aktuelle Platte drucken" msgid "Export G-code file" msgstr "G-Code als Datei exportieren" +msgctxt "Verb" +msgid "Print" +msgstr "aktuelle Platte drucken" + msgid "Export plate sliced file" msgstr "Exportiere aktuelle Platte als STL Datei" @@ -5702,15 +6053,6 @@ msgstr "Aktuelle Konfiguration in Dateien exportieren" msgid "Export" msgstr "Exportieren" -msgid "Sync Presets" -msgstr "Presets synchronisieren" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Die neuesten Presets von OrcaCloud abrufen und anwenden" - -msgid "You must be logged in to sync presets from cloud." -msgstr "Sie müssen angemeldet sein, um Presets aus der Cloud zu synchronisieren." - msgid "Quit" msgstr "Beenden" @@ -5827,6 +6169,15 @@ msgstr "Ansicht" msgid "Preset Bundle" msgstr "Vorlagen-Bundle" +msgid "Sync Presets" +msgstr "Presets synchronisieren" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Die neuesten Presets von OrcaCloud abrufen und anwenden" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Sie müssen angemeldet sein, um Presets aus der Cloud zu synchronisieren." + msgid "Syncing presets from cloud…" msgstr "Synchronisiere Presets aus der Cloud…" @@ -5947,6 +6298,9 @@ msgstr "Ergebnis exportieren" msgid "Select profile to load:" msgstr "Wählen Sie das zu ladende Profil:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6116,9 +6470,6 @@ msgstr "Ausgewählte Dateien vom Drucker herunterladen." msgid "Batch manage files." msgstr "Batch-Verwaltung von Dateien." -msgid "Refresh" -msgstr "Aktualisieren" - msgid "Reload file list from printer." msgstr "Dateiliste vom Drucker neu laden." @@ -6431,6 +6782,9 @@ msgstr "Druckoptionen" msgid "Safety Options" msgstr "Sicherheitsoptionen" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Lampe" @@ -6464,6 +6818,12 @@ msgstr "Beim Pausieren des Drucks werden das Laden und Entladen von Filament nur msgid "Current extruder is busy changing filament." msgstr "Der aktuelle Extruder ist mit dem Filamentwechsel beschäftigt." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Der aktuelle Steckplatz wurde bereits geladen." @@ -6514,9 +6874,6 @@ msgstr "Diese Funktion ist nur während des Druckens wirksam." msgid "Silent" msgstr "Leise" -msgid "Standard" -msgstr "Standard" - msgid "Sport" msgstr "Sport" @@ -6550,6 +6907,12 @@ msgstr "Foto hinzufügen" msgid "Delete Photo" msgstr "Foto löschen" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Übermitteln" @@ -6733,6 +7096,9 @@ msgstr "Wie verwende ich den LAN-Only-Modus" msgid "Don't show this dialog again" msgstr "Diesen Dialog nicht erneut anzeigen" +msgid "Please refer to Wiki before use->" +msgstr "Bitte lesen Sie vor der Verwendung das Wiki->" + msgid "3D Mouse disconnected." msgstr "3D-Maus nicht angeschlossen." @@ -6987,27 +7353,18 @@ msgstr "Durchfluss" msgid "Please change the nozzle settings on the printer." msgstr "Bitte ändern Sie die Düsen-Einstellungen am Drucker." -msgid "Hardened Steel" -msgstr "Gehärteter Stahl" - -msgid "Stainless Steel" -msgstr "Edelstahl" - -msgid "Tungsten Carbide" -msgstr "Wolframcarbid" - msgid "Brass" msgstr "Messing" msgid "High flow" msgstr "Hochgeschwindigkeit" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Kein Wiki-Link für diesen Drucker verfügbar." -msgid "Refreshing" -msgstr "Erneuern" - msgid "Unavailable while heating maintenance function is on." msgstr "Nicht verfügbar während die Heizungswartungsfunktion aktiviert ist." @@ -7130,6 +7487,15 @@ msgstr "Durchmesser wechseln" msgid "Configuration incompatible" msgstr "Konfiguration nicht kompatibel" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Tipps" + msgid "Sync printer information" msgstr "Syncronisiere die Druckerinformationen" @@ -7158,6 +7524,9 @@ msgstr "Klicken Sie hier, um das Profil zu bearbeiten" msgid "Project Filaments" msgstr "Projektfilamente" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Reinigungsvolumen" @@ -7388,9 +7757,6 @@ msgstr "Der verbundene Drucker ist %s. Er muss mit dem Projektprofil zum Drucken msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Möchten Sie die Druckerinformationen synchronisieren und das Profil automatisch wechseln?" -msgid "Tips" -msgstr "Tipps" - msgid "The file does not contain any geometry data." msgstr "Die Datei enthält keine Geometriedaten." @@ -7441,9 +7807,21 @@ msgstr "" "Diese Aktion wird die Schnittstellenverbindung unterbrechen.\n" "Danach kann die Modellkonsistenz nicht garantiert werden." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Das ausgewählte Objekt konnte nicht geteilt werden." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Auto-Drop deaktivieren, um die Z-Positionierung beizubehalten?\n" @@ -7470,6 +7848,9 @@ msgstr "Wählen Sie eine neue Datei aus" msgid "File for the replacement wasn't selected" msgstr "Datei für das Ersetzen wurde nicht ausgewählt" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Wählen Sie ein Verzeichnis aus um daraus zu ersetzen" @@ -7516,6 +7897,9 @@ msgstr "Kann nicht neu geladen werden:" msgid "Error during reload" msgstr "Fehler beim Neuladen" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Es gibt Warnungen nach dem slicen des Modells:" @@ -8288,6 +8672,15 @@ msgstr "Lösche meine Auswahl zum Synchronisieren des Druckerprofils nach dem La msgid "Graphics" msgstr "Grafik" +msgid "Smooth normals" +msgstr "Glatte Normalen" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Phong-Shading" @@ -8303,20 +8696,8 @@ msgstr "Wendet SSAO in der realistischen Ansicht an." msgid "Shadows" msgstr "Schatten" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "Zeigt geworfene Schatten auf der Platte in der realistischen Ansicht an." - -msgid "Smooth normals" -msgstr "Glatte Normalen" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"Wendet glatte Normalen auf die realistische Ansicht an.\n" -"\n" -"Erfordert manuelles Neuladen der Szene, um wirksam zu werden (Rechtsklick auf 3D-Ansicht → \"Alle neu laden\")." msgid "Anti-aliasing" msgstr "Kantenglättung" @@ -8510,10 +8891,10 @@ msgid "Show incompatible/unsupported presets in the printer and filament dropdow msgstr "Zeigt inkompatible/nicht unterstützte Profile in den Dropdown-Listen für Drucker und Filament an. Diese Profile können nicht ausgewählt werden." msgid "Experimental Features" -msgstr "" +msgstr "Experimentelle Funktionen" msgid "Keep painted feature after mesh change" -msgstr "" +msgstr "Bemalte Funktionen nach Mesh-Änderung beibehalten" msgid "" "Attempt to keep painted features (color/seam/support/fuzzy etc.) after changing the object mesh (such as cut/reload from disk/simplify/fix etc.)\n" @@ -8615,6 +8996,9 @@ msgstr "Inkompatible Profile" msgid "My Printer" msgstr "Mein Drucker" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "linke Filamente" @@ -8633,6 +9017,9 @@ msgstr "Profil hinzufügen/entfernen" msgid "Edit preset" msgstr "Profil bearbeiten" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Nicht spezifiziert" @@ -8664,9 +9051,6 @@ msgstr "Systemdrucker auswählen/entfernen" msgid "Create printer" msgstr "Drucker erstellen" -msgid "Empty" -msgstr "Leer" - msgid "Incompatible" msgstr "Inkompatibel" @@ -8898,12 +9282,42 @@ msgstr "Senden abgeschlossen" msgid "Error code" msgstr "Fehlercode" -msgid "High Flow" -msgstr "Hoher Fluss" +msgid "Error desc" +msgstr "Fehlerbeschreibung" + +msgid "Extra info" +msgstr "Zusätzliche Informationen" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "Die Düsenfluss-Einstellung von %s(%s) stimmt nicht mit der Slicing-Datei(%s) überein. Bitte stellen Sie sicher, dass die installierte Düse mit den Einstellungen im Drucker übereinstimmt, und wählen Sie dann das entsprechende Druckerprofil beim Slicen aus." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8967,8 +9381,38 @@ msgstr "Kosten %dg Filament und %d Änderungen mehr als optimale Gruppierung." msgid "nozzle" msgstr "Düse" -msgid "both extruders" -msgstr "beide Extruder" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "Die Düsenfluss-Einstellung von %s(%s) stimmt nicht mit der Slicing-Datei(%s) überein. Bitte stellen Sie sicher, dass die installierte Düse mit den Einstellungen im Drucker übereinstimmt, und wählen Sie dann das entsprechende Druckerprofil beim Slicen aus." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Tipp: Wenn Sie kürzlich die Düse Ihres Druckers gewechselt haben, gehen Sie zu 'Gerät -> Druckerteile', um Ihre Düsen-Einstellung zu ändern." @@ -8981,10 +9425,17 @@ msgstr "The %s Durchmesser(%.1fmm) des aktuellen Druckers stimmt nicht mit der S msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Der aktuelle Düsendurchmesser (%.1fmm) stimmt nicht mit der Slicing-Datei (%.1fmm) überein. Bitte stellen Sie sicher, dass die installierte Düse mit den Einstellungen im Drucker übereinstimmt, und wählen Sie dann das entsprechende Druckerprofil beim Slicen aus." +msgid "both extruders" +msgstr "beide Extruder" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Die Härte des aktuellen Materials (%s) überschreitet die Härte von %s(%s). Bitte überprüfen Sie die Düsen- oder Materialeinstellungen und versuchen Sie es erneut." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -9095,9 +9546,6 @@ msgstr "Die aktuelle Firmware unterstützt maximal 16 Materialien. Sie können e msgid "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." msgstr "Der Typ des externen Filaments ist unbekannt oder stimmt nicht mit dem Filamenttyp in der Slicing-Datei überein. Bitte stellen Sie sicher, dass Sie das richtige Filament in der externen Spule installiert haben." -msgid "Please refer to Wiki before use->" -msgstr "Bitte lesen Sie vor der Verwendung das Wiki->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Die aktuelle Firmware unterstützt keine Dateiübertragung zum internen Speicher." @@ -9271,14 +9719,17 @@ msgid "Search in preset" msgstr "In Profilen suchen" msgid "Synchronization of different extruder drives or nozzle volume types is not supported." -msgstr "" +msgstr "Die Synchronisierung verschiedener Extrudertypen oder Düsenvolumentypen wird nicht unterstützt." msgid "Synchronize the modification of parameters to the corresponding parameters of another extruder." -msgstr "" +msgstr "Änderungen der Parameter mit den entsprechenden Parametern eines anderen Extruders synchronisieren." msgid "Click to reset all settings to the last saved preset." msgstr "Klicken Sie hier, um alle Einstellungen auf die zuletzt gespeicherten Parameter zurückzusetzen." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Der Reinigungsturm ist für den Düsenwechsel erforderlich. Ohne Reinigungsturm können Fehler im Modell auftreten. Möchten Sie den Reinigungsturm wirklich deaktivieren?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Ein Reinigungsturm ist für den gewählten Zeitraffer-Modus erforderlich. Ohne Reinigungsturm kann es zu Fehlern am Modell kommen. Sind Sie sicher, dass Sie den Reinigungsturm deaktivieren möchten?" @@ -9360,9 +9811,6 @@ msgstr "Automatisch an den eingestellten Bereich anpassen?\n" msgid "Adjust" msgstr "Anpassen" -msgid "Ignore" -msgstr "Ignorieren" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Experimentelle Funktion: Filament beim Filamentwechsel weiter zurückziehen und abschneiden, um den Flush zu minimieren. Obwohl dies den Flush deutlich reduzieren kann, kann es auch das Risiko von Düsenverstopfungen oder anderen Druckkomplikationen erhöhen." @@ -9570,13 +10018,13 @@ msgid "Chamber temperature" msgstr "Druckraum Temperatur" msgid "Target chamber temperature, and the minimal chamber temperature at which printing should start" -msgstr "" +msgstr "Ziel-Druckraumtemperatur und die minimale Druckraumtemperatur, bei der der Druck beginnen sollte" msgid "Target" -msgstr "" +msgstr "Ziel" msgid "Minimal" -msgstr "" +msgstr "Minimal" msgid "Print temperature" msgstr "Drucktemperatur" @@ -9599,7 +10047,7 @@ msgstr "Strukturierte kalte Druckplatte" # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the bed temperature when the Textured Cool Plate is installed. A value of 0 means the filament does not support printing on the Textured Cool Plate." -msgstr "Dies ist die Betttemperatur, wenn die kalte Druckplatte installiert ist. Ein Wert von 0 bedeutet, dass das Filament auf der texturierten kalten Druckplatte nicht unterstützt wird." +msgstr "Dies ist die Betttemperatur, wenn die texturierte kalte Druckplatte installiert ist. Ein Wert von 0 bedeutet, dass das Filament auf der texturierten kalten Druckplatte nicht unterstützt wird." # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the bed temperature when the engineering plate is installed. A value of 0 means the filament does not support printing on the Engineering Plate." @@ -9867,6 +10315,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Sind sie sicher, dass sie das ausgewählte Profil %1% wollen?" +msgid "Select printers" +msgstr "Drucker auswählen" + +msgid "Select profiles" +msgstr "Profil auswählen" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9914,21 +10368,21 @@ msgstr "Nicht erneut für dieses Profil warnen" #, c-format, boost-format msgid "%s: %s" -msgstr "" +msgstr "%s: %s" msgid "No modifications need to be copied." -msgstr "" +msgstr "Es müssen keine Änderungen kopiert werden." msgid "Copy paramters" -msgstr "" +msgstr "Parameter kopieren" #, c-format, boost-format msgid "Modify paramters of %s" -msgstr "" +msgstr "Parameter von %s ändern" #, c-format, boost-format msgid "Do you want to modify the following parameters of the %s to that of the %s?" -msgstr "" +msgstr "Möchten Sie die folgenden Parameter von %s auf die von %s ändern?" msgid "Click to reset current value and attach to the global value." msgstr "Klicken Sie hier, um den aktuellen Wert zurückzusetzen und ihn dem globalen Wert zuzuordnen." @@ -10074,10 +10528,10 @@ msgid "Capabilities" msgstr "Fähigkeiten" msgid "Left: " -msgstr "" +msgstr "Links: " msgid "Right: " -msgstr "" +msgstr "Rechts: " msgid "Show all presets (including incompatible)" msgstr "Alle Profile anzeigen (auch inkompatible)" @@ -10107,6 +10561,12 @@ msgstr "Werte von links nach rechts übertragen" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Wenn aktiviert, kann dieses Dialogfeld verwendet werden, um ausgewählte Werte von links nach rechts zu übertragen." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Datei hinzufügen" @@ -10363,12 +10823,8 @@ msgstr "Düseninformationen erfolgreich synchronisiert." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Düsen und AMS Nummer erfolgreich synchronisiert." -msgid "Continue to sync filaments" -msgstr "Weiter mit dem Synchronisieren der Filamente" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Abbrechen" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Farbe des Filaments erfolgreich vom Drucker synchronisiert." @@ -10476,6 +10932,9 @@ msgstr "Anmelden" msgid "Login failed. Please try again." msgstr "Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut." +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Aktion erforderlich] " @@ -10790,6 +11249,9 @@ msgstr "Druckername" msgid "Where to find your printer's IP and Access Code?" msgstr "Wo finde ich die IP-Adresse und den Zugriffscode meines Druckers?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Verbinden" @@ -10854,6 +11316,9 @@ msgstr "Schneidemodul" msgid "Auto Fire Extinguishing System" msgstr "Automatisches Feuerlöschsystem" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10872,6 +11337,9 @@ msgstr "Aktualisierung fehlgeschlagen" msgid "Update successful" msgstr "Erfolgreich aktualisiert" +msgid "Hotends on Rack" +msgstr "Hotends im Magazin" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Sind Sie sicher, dass Sie die Aktualisierung jetzt durchführen möchten? Dieser Vorgang dauert etwa 10 Minuten. Schalten Sie den Drucker nicht aus, während er aktualisiert wird." @@ -10981,6 +11449,9 @@ msgstr "Gruppierungsfehler: " msgid " can not be placed in the " msgstr " kann nicht platziert werden in der " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Interne Brücke" @@ -11698,19 +12169,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Externe Brückenwinkelüberschreibung.\n" -"Wenn auf Null gelassen, wird der Brückenwinkel automatisch für jede spezifische Brücke berechnet.\n" -"Ansonsten wird der angegebene Winkel wie folgt verwendet:\n" -" - Die absoluten Koordinaten\n" -" - Die absoluten Koordinaten + Modellrotation: Wenn 'Füllrichtung an Modell ausrichten' aktiviert ist\n" -" - Der optimale automatische Winkel + dieser Wert: Wenn 'Relativer Brückenwinkel' aktiviert ist\n" -"\n" -"Verwenden Sie 180° für einen absoluten Winkel von Null." msgid "Internal bridge infill direction" msgstr "Interne Brücken Füllrichtung" @@ -11720,19 +12183,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Interne Brückenwinkelüberschreibung.\n" -"Wenn auf Null gelassen, wird der Brückenwinkel automatisch für jede spezifische Brücke berechnet.\n" -"Ansonsten wird der angegebene Winkel wie folgt verwendet:\n" -" - Die absoluten Koordinaten\n" -" - Die absoluten Koordinaten + Modellrotation: Wenn 'Füllrichtung an Modell ausrichten' aktiviert ist\n" -" - Der optimale automatische Winkel + dieser Wert: Wenn 'Relativer Brückenwinkel' aktiviert ist\n" -"\n" -"Verwenden Sie 180° für einen absoluten Winkel von Null." msgid "Relative bridge angle" msgstr "Relativer Brückenwinkel" @@ -12225,9 +12680,6 @@ msgstr "" "Die Geometrie wird vor der Erkennung scharfer Winkel reduziert. Dieser Parameter ist ein Indikator für die minimale Länge der Abweichung für die Reduzierung.\n" "0 zum Deaktivieren." -msgid "Select printers" -msgstr "Drucker auswählen" - msgid "upward compatible machine" msgstr "Aufwärtskompatible Maschine" @@ -12238,9 +12690,6 @@ msgstr "Bedingung" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Eine boolesche Ausdruck, der die Konfigurationswerte eines aktiven Druckerprofils verwendet. Wenn dieser Ausdruck wahr ist, wird dieses Profil als kompatibel mit dem aktiven Druckerprofil betrachtet." -msgid "Select profiles" -msgstr "Profil auswählen" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Eine boolesche Ausdruck, der die Konfigurationswerte eines aktiven Druckerprofils verwendet. Wenn dieser Ausdruck wahr ist, wird dieses Profil als kompatibel mit dem aktiven Druckerprofil betrachtet." @@ -12515,6 +12964,42 @@ msgstr "Dichte der oberen Oberfläche" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Dichte der oberen Oberflächenschicht. Ein Wert von 100 % erzeugt eine vollständig massive, glatte obere Schicht. Eine Reduzierung dieses Wertes führt zu einer strukturierten oberen Oberfläche, abhängig vom gewählten Oberflächenmuster. Ein Wert von 0 % führt dazu, dass nur die Wände der oberen Schicht erstellt werden. Diese Einstellung dient ästhetischen oder funktionalen Zwecken und nicht zur Behebung von Problemen wie Überextrusion." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Muster der unteren Fläche" @@ -12847,12 +13332,18 @@ msgstr "Automatisch für Spülen" msgid "Auto For Match" msgstr "Automatisch für Übereinstimmung" +msgid "Nozzle Manual" +msgstr "Düsenhandbuch" + msgid "Flush temperature" msgstr "Spültemperatur" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatur beim Spülen des Filaments. 0 bedeutet die obere Grenze des empfohlenen Düsentemperaturbereichs." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Volumetrische Spülgeschwindigkeit" @@ -13118,6 +13609,12 @@ msgstr "Filament druckbar" msgid "The filament is printable in extruder." msgstr "Das Filament ist im Extruder druckbar." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Erweichungstemperatur" @@ -13180,15 +13677,13 @@ msgstr "Fülldichte" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Dichte der internen Füllung, 100% verwandelt alle interne Füllung in massive Füllung und das interne massive Füllmuster wird verwendet." -msgid "Align infill direction to model" -msgstr "Füllrichtung am Modell ausrichten" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"Richtet die Richtungen von Füllung, Brücke, Glättung und Oberflächenfüllung so aus, dass sie der Orientierung des Modells auf der Bauplatte folgen.\n" -"Wenn aktiviert, drehen sich die Richtungen mit dem Modell, um optimale Festigkeitseigenschaften zu erhalten." msgid "Insert solid layers" msgstr "Massive Schichten einfügen" @@ -13392,7 +13887,7 @@ msgid "layer" msgstr "Schicht" msgid "First layer fan speed" -msgstr "" +msgstr "Lüftergeschwindigkeit der ersten Schicht" msgid "" "Sets an exact fan speed for the first layer, overriding all other cooling settings. Useful for protecting 3D-printed toolhead parts (e.g. Voron-style ABS/ASA ducts) from a hot bed. A small amount of airflow cools the ducts down, without using full cooling that may in certain conditions hurt first-layer adhesion.\n" @@ -13401,6 +13896,11 @@ msgid "" "Only available when \"No cooling for the first\" is 0.\n" "Set to -1 to disable it." msgstr "" +"Legt eine genaue Lüftergeschwindigkeit für die erste Schicht fest und überschreibt alle anderen Kühlungseinstellungen. Nützlich zum Schutz von 3D-gedruckten Werkzeugkopfteilen (z.B. Voron-Style ABS/ASA-Düsen) vor einem heißen Bett. Eine kleine Menge Luftstrom kühlt die Düsen ab, ohne die volle Kühlung zu verwenden, die unter bestimmten Bedingungen die Haftung der ersten Schicht beeinträchtigen kann.\n" +"Ab der zweiten Schicht wird die normale Kühlung wieder aufgenommen.\n" +"Wenn auch \"Volle Lüfterdrehzahl ab Schicht\" eingestellt ist, steigt der Lüfter von diesem Wert in der ersten Schicht bis zu Ihrem Zielwert in der gewählten Schicht.\n" +"Nur verfügbar, wenn \"Keine Kühlung für die erste\" 0 ist.\n" +"Auf -1 setzen, um es zu deaktivieren." msgid "Support interface fan speed" msgstr "Stützstruktur-Schnittstelle" @@ -13725,6 +14225,15 @@ msgstr "Beste automatische Positionierung im Bereich [0,1] bezogen auf das Bett. msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Aktivieren Sie diese Option, wenn der Drucker einen zusätzlichen Lüfter für die Kühlung von Teilen hat. G-Code-Befehl: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13794,6 +14303,12 @@ msgstr "" "Aktivieren Sie diese Option, wenn der Drucker die Luft filtern kann\n" "G-Code-Befehl: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Kühlungsfilter verwenden" + +msgid "Enable this if printer support cooling filter" +msgstr "Aktivieren Sie diese Option, wenn der Drucker einen Kühlungsfilter unterstützt" + msgid "G-code flavor" msgstr "G-Code Typ" @@ -14326,6 +14841,30 @@ msgstr "Minimale Fahrgeschwindigkeit" msgid "Minimum travel speed (M205 T)" msgstr "Minimale Fahrgeschwindigkeit (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Maximale Kraft der Y-Achse" + +msgid "The allowed maximum output force of Y axis" +msgstr "Die maximal zulässige Ausgangskraft der Y-Achse" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Bettmasse der Y-Achse" + +msgid "The machine bed mass load of Y axis" +msgstr "Die Maschinenbett-Massenlast der Y-Achse" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "Die maximal zulässige gedruckte Masse" + +msgid "The allowed max printed mass on a plate" +msgstr "Die maximal zulässige gedruckte Masse auf einer Platte" + msgid "Maximum acceleration for extruding" msgstr "Maximale Beschleunigung beim Extrudieren" @@ -14896,6 +15435,9 @@ msgstr "Direktantrieb" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "Dynamische Filamentzuordnung aktivieren" @@ -14931,6 +15473,12 @@ msgstr "Wiedereinzugsgeschwindigkeit" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Geschwindigkeit für das Nachladen von Filament in die Düse. Null bedeutet die gleiche Geschwindigkeit wie beim Rückzug." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Filament Rückzug durch Firmware" @@ -14962,6 +15510,10 @@ msgstr "Ausgerichtet" msgid "Aligned back" msgstr "Ausgerichtet hinten" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Zurück" + msgid "Random" msgstr "Zufall" @@ -15247,6 +15799,12 @@ msgstr "Wenn der Modus \"Gleichmäßig\" oder \"Traditionell\" ausgewählt ist, msgid "Traditional" msgstr "Traditionell" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Temperaturvariation" @@ -15334,6 +15892,18 @@ msgstr "Reinige alle Druckextruder" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Wenn aktiviert, werden alle Druckextruder am vorderen Rand des Druckbetts am Anfang des Drucks gereinigt." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Slice-Lückenschlussradius" @@ -15726,15 +16296,20 @@ msgstr "" "Wenn diese Option aktiviert ist, wird auch eine G-Code-Variable namens chamber_temperature gesetzt, die verwendet werden kann, um die gewünschte Druckraumtemperatur an Ihr Druckstart-Makro oder ein Wärmespeicher-Makro weiterzugeben, wie z.B. PRINT_START (andere Variablen) CHAMBER_TEMP=[chamber_temperature]. Dies kann nützlich sein, wenn Ihr Drucker die Befehle M141/M191 nicht unterstützt oder wenn Sie das Wärmespeichern im Druckstart-Makro behandeln möchten, wenn kein aktiver Druckraumheizer installiert ist." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" "Unlike the \"Target\" chamber temperature, this option does not emit any M141/M191 commands; it only exposes the value to your custom G-code. It should not exceed the \"Target\" chamber temperature." msgstr "" +"Dies ist die Druckraumtemperatur, bei der der Druckvorgang beginnen soll, während der Druckraum weiterhin auf die \"Ziel\"-Druckraumtemperatur erhitzt wird. Zum Beispiel: Setzen Sie das Ziel auf 60 und das Minimum auf 50, um mit dem Drucken zu beginnen, sobald der Druckraum 50°C erreicht hat, ohne auf die vollen 60°C zu warten.\n" +"\n" +"Es wird eine G-Code-Variable namens chamber_minimal_temperature gesetzt, die an Ihr Druckstart-Makro oder ein Wärmespeicher-Makro übergeben werden kann, wie z.B.: PRINT_START (andere Variablen) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" +"\n" +"Im Gegensatz zur \"Ziel\"-Druckraumtemperatur sendet diese Option keine M141/M191-Befehle; sie stellt den Wert nur Ihrem benutzerdefinierten G-Code zur Verfügung. Sie sollte die \"Ziel\"-Druckraumtemperatur nicht überschreiten." msgid "Chamber minimal temperature" -msgstr "" +msgstr "Minimale Druckraumtemperatur" # TODO: Review, changed by lang refactor. PR 14254 msgid "Nozzle temperature after the first layer" @@ -15781,6 +16356,45 @@ msgstr "Dicke der oberen Schale" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Die Anzahl der oberen festen Schichten wird beim Slicen erhöht, wenn die obere Schalenstärke dünner als dieser Wert ist. Dies kann verhindern, dass die Schale zu dünn wird, wenn eine geringe Schichthöhe verwendet wird. 0 bedeutet, dass diese Einstellung deaktiviert ist und die Dicke der oberen Schale absolut durch die oberen Schalenschichten bestimmt wird." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Eilgeschwindigkeit, wenn nicht extrudiert wird." @@ -15829,6 +16443,12 @@ msgstr "Multiplikator der Düsenreinigung" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Das tatsächliche Reinigungsvolumen entspricht dem Wert des Reinigungsmultiplikators multipliziert mit den in der Tabelle angegebenen Reinigungsvolumen." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Reinigungsvolumen" @@ -15836,6 +16456,18 @@ msgstr "Reinigungsvolumen" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Das Volumen des Materials, das der Extruder am Turm entladen soll." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Breite des Reinigungsturms." @@ -16128,6 +16760,57 @@ msgstr "Minimale Wandbreite" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Breite der Wand, die dünne Features (entsprechend der Mindest-Featuregröße) des Modells ersetzen wird. Wenn die minimale Wandbreite dünner ist als die Dicke des Features, wird die Wand so dick wie das Feature selbst. Wird als Prozentsatz des Düsendurchmessers angegeben." +msgid "Hotend change time" +msgstr "Hotend-Wechselzeit" + +msgid "Time to change hotend." +msgstr "Zeit, um das Hotend zu wechseln." + +msgid "Hotend change" +msgstr "Hotend-Wechsel" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Beim Wechseln des Hotends wird empfohlen, eine bestimmte Länge des Filaments aus der ursprünglichen Düse zu extrudieren. Dies hilft, das Auslaufen der Düse zu minimieren." + +msgid "Extruder change" +msgstr "Extruderwechsel" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Um ein Nachtropfen zu verhindern, führt die Düse nach Abschluss des Rammvorgangs für eine bestimmte Zeit eine Rückwärtsbewegung aus. Die Einstellung definiert die Verfahrzeit." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Um ein Austreten von Material zu verhindern, wird die Düsentemperatur während des Rammens abgekühlt. Daher muss die Rammzeit länger sein als die Abkühlzeit. 0 bedeutet deaktiviert." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "Die maximale Volumengeschwindigkeit für das Rammen vor dem Extruderwechsel, wobei -1 die Verwendung der maximalen Volumengeschwindigkeit bedeutet." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Um ein Auslaufen zu verhindern, wird die Düsentemperatur während des Rammens gekühlt. Hinweis: Es wird nur ein Abkühlbefehl und die Aktivierung des Lüfters ausgelöst, das Erreichen der Zieltemperatur ist nicht garantiert. 0 bedeutet deaktiviert." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "Die maximale Volumengeschwindigkeit für das Rammen vor einem Hotend-Wechsel, wobei -1 die Verwendung der maximalen Volumengeschwindigkeit bedeutet." + +msgid "length when change hotend" +msgstr "Länge beim Wechseln des Hotends" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Wenn dieser Rückzugswert geändert wird, wird er als die Filamentmenge verwendet, die vor dem Wechsel des Hotends im Hotend zurückgezogen wird." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Das Materialvolumen, das erforderlich ist, um den Extruder für einen Hotend-Wechsel am Turm vorzubereiten." + +msgid "Preheat temperature delta" +msgstr "Vorheiztemperatur-Delta" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Temperatur-Delta, das während des Vorheizens vor dem Werkzeugwechsel angewendet wird." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Erkennen einer schmalen internen soliden Füllung" @@ -16884,12 +17567,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibrierung nicht unterstützt" -msgid "Error desc" -msgstr "Fehlerbeschreibung" - -msgid "Extra info" -msgstr "Zusätzliche Informationen" - msgid "Flow Dynamics" msgstr "Flussdynamik" @@ -17093,6 +17770,12 @@ msgstr "Bitte geben Sie den Namen ein, unter dem Sie ihn auf dem Drucker speiche msgid "The name cannot exceed 40 characters." msgstr "Der Name darf 40 Zeichen nicht überschreiten." +msgid "Nozzle ID" +msgstr "Düsen-ID" + +msgid "Standard Flow" +msgstr "Standardfluss" + msgid "Please find the best line on your plate" msgstr "Bitte finden Sie die beste Linie auf Ihrer Platte" @@ -17183,9 +17866,6 @@ msgstr "AMS- und Düseninformationen sind synchronisiert" msgid "Nozzle Flow" msgstr "Düsendurchfluss" -msgid "Nozzle Info" -msgstr "Düseninfo" - msgid "Filament position" msgstr "Filamentposition" @@ -17260,6 +17940,10 @@ msgstr "Ergebnis der Vergangenheit erfolgreich erhalten" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Erneuern der historischen Flussdynamik-Kalibrierungsdatensätze" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Hinweis: Die Hotend-Nummer auf dem %s ist an den Halter gebunden. Wenn das Hotend in einen neuen Halter bewegt wird, wird seine Nummer automatisch aktualisiert." + msgid "Action" msgstr "Aktivität" @@ -18436,130 +19120,132 @@ msgid "Connection to printers connected via the print host failed." msgstr "Die Verbindung zu den über den Druck-Host verbundenen Druckern ist fehlgeschlagen." msgid "Detect Creality K-series printer" -msgstr "" +msgstr "Creality K-Serie Drucker erkennen" msgid "Click Scan to look for K-series printers on your network." -msgstr "" +msgstr "Klicken Sie auf 'Scannen', um nach K-Serie Druckern in Ihrem Netzwerk zu suchen." msgid "Use Selected" -msgstr "" +msgstr "Ausgewählten verwenden" msgid "Scanning the LAN for K-series printers... this takes a few seconds." -msgstr "" +msgstr "Suche im LAN nach K-Serie Druckern... dies dauert einige Sekunden." msgid "No K-series printers found. Make sure the printer is on the same network and not blocked by Wi-Fi client isolation, then click Scan again." -msgstr "" +msgstr "Keine K-Serie Drucker gefunden. Stellen Sie sicher, dass der Drucker im selben Netzwerk ist und nicht durch Wi-Fi-Client-Isolation blockiert wird, und klicken Sie dann erneut auf 'Scannen'." #, c-format msgid "Found %zu Creality printer(s). Select one and click Use Selected." -msgstr "" +msgstr "Es wurden %zu Creality-Drucker gefunden. Wählen Sie einen aus und klicken Sie auf 'Ausgewählten verwenden'." msgid "Active" -msgstr "" +msgstr "Aktiv" msgid "Printers" -msgstr "" +msgstr "Drucker" msgid "Processes" -msgstr "" +msgstr "Prozesse" msgid "Show/Hide system information" -msgstr "" +msgstr "Systeminformationen anzeigen/verbergen" msgid "Copy system information to clipboard" -msgstr "" +msgstr "Systeminformationen in die Zwischenablage kopieren" msgid "We need information for diagnosing source of the issue. Check wiki page for detailed guide." -msgstr "" +msgstr "Wir benötigen Informationen zur Diagnose der Ursache des Problems. Überprüfen Sie die Wiki-Seite für eine detaillierte Anleitung." msgid "Pack button collects project file and logs of current session onto a zip file." -msgstr "" +msgstr "Die Schaltfläche „Packen“ sammelt die Projektdatei und Protokolle der aktuellen Sitzung in einer ZIP-Datei." msgid "Any additional visual examples like images or screen recordings might be helpful while reporting the issue." -msgstr "" +msgstr "Zusätzliche visuelle Beispiele wie Bilder oder Bildschirmaufnahmen könnten beim Melden des Problems hilfreich sein." msgid "Report issue" -msgstr "" +msgstr "Problem melden" msgid "Pack" -msgstr "" +msgstr "Packen" msgid "Cleans and rebuilds system profiles cache on next launch" -msgstr "" +msgstr "Bereinigt und erstellt den Systemprofil-Cache beim nächsten Start neu" msgid "Clean system profiles cache" -msgstr "" +msgstr "Systemprofil-Cache bereinigen" msgid "Clean" -msgstr "" +msgstr "Bereinigen" msgid "Loaded profiles overview" -msgstr "" +msgstr "Übersicht der geladenen Profile" msgid "This section shows information for loaded profiles" -msgstr "" +msgstr "Dieser Abschnitt zeigt Informationen zu den geladenen Profilen" msgid "Exports detailed overview of loaded profiles in json format" -msgstr "" +msgstr "Exportiert eine detaillierte Übersicht der geladenen Profile im JSON-Format" msgid "Configurations folder" -msgstr "" +msgstr "Konfigurationsordner" msgid "Opens configurations folder" -msgstr "" +msgstr "Öffnet den Konfigurationsordner" msgid "Log level" -msgstr "" +msgstr "Protokollstufe" msgid "Stored logs" -msgstr "" +msgstr "Gespeicherte Protokolle" msgid "Packs all stored logs onto a zip file." -msgstr "" +msgstr "Packt alle gespeicherten Protokolle in eine ZIP-Datei." msgid "Profiles" -msgstr "" +msgstr "Profile" msgid "Select NO to close dialog and review project" -msgstr "" +msgstr "Wählen Sie NEIN, um das Dialogfeld zu schließen und das Projekt zu überprüfen" msgid "No project file on current session. Only logs will be included to package" -msgstr "" +msgstr "Keine Projektdatei in der aktuellen Sitzung. Nur Protokolle werden in das Paket aufgenommen" msgid "Select NO to close dialog and review project." -msgstr "" +msgstr "Wählen Sie NEIN, um das Dialogfeld zu schließen und das Projekt zu überprüfen." msgid "Please make sure any instances of OrcaSlicer are not running" -msgstr "" +msgstr "Bitte stellen Sie sicher, dass keine Instanzen von OrcaSlicer ausgeführt werden." msgid "System folder cannot be deleted because some files are in use by another application. Please close any applications using these files and try again." -msgstr "" +msgstr "Der Systemordner kann nicht gelöscht werden, da einige Dateien von einer anderen Anwendung verwendet werden. Bitte schließen Sie alle Anwendungen, die diese Dateien verwenden, und versuchen Sie es erneut." msgid "Failed to delete system folder..." -msgstr "" +msgstr "Systemordner konnte nicht gelöscht werden..." msgid "Failed to determine executable path." -msgstr "" +msgstr "Konnte den Pfad zur ausführbaren Datei nicht bestimmen." msgid "Failed to launch a new instance." -msgstr "" +msgstr "Konnte keine neue Instanz starten." msgid "log(s)" -msgstr "" +msgstr "Protokoll(e)" msgid "Choose where to save the exported JSON file" -msgstr "" +msgstr "Wählen Sie, wo die exportierte JSON-Datei gespeichert werden soll" msgid "" "Export failed\n" "Please check write permissions or file in use by another application" msgstr "" +"Export fehlgeschlagen\n" +"Bitte überprüfen Sie die Schreibberechtigungen oder ob die Datei von einer anderen Anwendung verwendet wird." msgid "Choose where to save the exported ZIP file" -msgstr "" +msgstr "Wählen Sie, wo die exportierte ZIP-Datei gespeichert werden soll" msgid "File already exists. Overwrite?" -msgstr "" +msgstr "Datei existiert bereits. Überschreiben?" msgid "3DPrinterOS Cloud upload options" msgstr "3DPrinterOS Cloud-Upload-Optionen" @@ -18644,17 +19330,17 @@ msgid "Could not connect to MKS" msgstr "Konnte keine Verbindung zu MKS herstellen" msgid "Connection to Moonraker is working correctly." -msgstr "" +msgstr "Verbindung zu Moonraker funktioniert korrekt." msgid "Could not connect to Moonraker" -msgstr "" +msgstr "Konnte keine Verbindung zu Moonraker herstellen" msgid "The host responded but it doesn't look like Moonraker (missing result.klippy_state)." -msgstr "" +msgstr "Der Host hat geantwortet, sieht aber nicht wie Moonraker aus (fehlender result.klippy_state)." #, c-format, boost-format msgid "Could not parse Moonraker server response: %s" -msgstr "" +msgstr "Konnte die Moonraker-Serverantwort nicht analysieren: %s" msgid "Connection to OctoPrint is working correctly." msgstr "Verbindung zu OctoPrint funktioniert korrekt." @@ -19026,6 +19712,12 @@ msgstr "Druck fehlgeschlagen" msgid "Removed" msgstr "Entfernt" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Nicht mehr erinnern" @@ -19059,12 +19751,25 @@ msgstr "Video-Tutorial" msgid "(Sync with printer)" msgstr "(Mit Drucker synchronisieren)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Wir werden entsprechend dieser Gruppierungsmethode schneiden:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Tipps: Sie können die Filamente ziehen, um sie verschiedenen Düsen zuzuweisen." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Die Filamentgruppierungsmethode für die aktuelle Platte wird durch die Dropdown-Option an der Slicing-Platten-Schaltfläche bestimmt." @@ -19296,9 +20001,6 @@ msgstr "Diese Aktion kann nicht rückgängig gemacht werden. Fortsetzen?" msgid "Skipping objects." msgstr "Objekte werden übersprungen." -msgid "Select Filament" -msgstr "Filament auswählen" - msgid "Null Color" msgstr "Keine Farbe" @@ -19822,6 +20524,77 @@ msgstr "" "Verwerfungen vermeiden\n" "Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Zeigt geworfene Schatten auf der Platte in der realistischen Ansicht an." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "Wendet glatte Normalen auf die realistische Ansicht an.\n" +#~ "\n" +#~ "Erfordert manuelles Neuladen der Szene, um wirksam zu werden (Rechtsklick auf 3D-Ansicht → \"Alle neu laden\")." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Weiter mit dem Synchronisieren der Filamente" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Abbrechen" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Externe Brückenwinkelüberschreibung.\n" +#~ "Wenn auf Null gelassen, wird der Brückenwinkel automatisch für jede spezifische Brücke berechnet.\n" +#~ "Ansonsten wird der angegebene Winkel wie folgt verwendet:\n" +#~ " - Die absoluten Koordinaten\n" +#~ " - Die absoluten Koordinaten + Modellrotation: Wenn 'Füllrichtung an Modell ausrichten' aktiviert ist\n" +#~ " - Der optimale automatische Winkel + dieser Wert: Wenn 'Relativer Brückenwinkel' aktiviert ist\n" +#~ "\n" +#~ "Verwenden Sie 180° für einen absoluten Winkel von Null." + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Interne Brückenwinkelüberschreibung.\n" +#~ "Wenn auf Null gelassen, wird der Brückenwinkel automatisch für jede spezifische Brücke berechnet.\n" +#~ "Ansonsten wird der angegebene Winkel wie folgt verwendet:\n" +#~ " - Die absoluten Koordinaten\n" +#~ " - Die absoluten Koordinaten + Modellrotation: Wenn 'Füllrichtung an Modell ausrichten' aktiviert ist\n" +#~ " - Der optimale automatische Winkel + dieser Wert: Wenn 'Relativer Brückenwinkel' aktiviert ist\n" +#~ "\n" +#~ "Verwenden Sie 180° für einen absoluten Winkel von Null." + +#~ msgid "Align infill direction to model" +#~ msgstr "Füllrichtung am Modell ausrichten" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "Richtet die Richtungen von Füllung, Brücke, Glättung und Oberflächenfüllung so aus, dass sie der Orientierung des Modells auf der Bauplatte folgen.\n" +#~ "Wenn aktiviert, drehen sich die Richtungen mit dem Modell, um optimale Festigkeitseigenschaften zu erhalten." + +#~ msgid "Print" +#~ msgstr "aktuelle Platte drucken" + #~ msgid "in" #~ msgstr "in" @@ -20946,9 +21719,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Kann ohne SD-Karte nicht gestartet werden." -#~ msgid "Update" -#~ msgstr "Update" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Die Sensibilität der Pause ist" @@ -21730,10 +22500,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Abwählen" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Skalieren" - #~ msgid "Lift Z Enforcement" #~ msgstr "Z-Höhe einhalten" diff --git a/localization/i18n/en/OrcaSlicer_en.po b/localization/i18n/en/OrcaSlicer_en.po index 6e6628b5ce..5e10b1c81f 100644 --- a/localization/i18n/en/OrcaSlicer_en.po +++ b/localization/i18n/en/OrcaSlicer_en.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-06-17 15:44-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -47,6 +65,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "" @@ -56,10 +77,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "" + +msgid "Hardened Steel" +msgstr "" + +msgid "Stainless Steel" +msgstr "" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "" @@ -90,6 +191,85 @@ msgstr "" msgid "Latest version" msgstr "" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "" + +msgid "Error" +msgstr "" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "" + +msgid "Refreshing" +msgstr "" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + msgid "Support Painting" msgstr "" @@ -159,6 +339,12 @@ msgstr "" msgid "Gap Fill" msgstr "" +msgid "Vertical" +msgstr "" + +msgid "Horizontal" +msgstr "" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "" @@ -251,12 +437,6 @@ msgstr "" msgid "Height Range" msgstr "" -msgid "Vertical" -msgstr "" - -msgid "Horizontal" -msgstr "" - msgid "Remove painted color" msgstr "" @@ -321,6 +501,7 @@ msgstr "" msgid "Optimize orientation" msgstr "" +msgctxt "Verb" msgid "Scale" msgstr "" @@ -364,6 +545,9 @@ msgstr "" msgid "Object operations" msgstr "" +msgid "Scale" +msgstr "" + msgid "Volume operations" msgstr "" @@ -409,6 +593,10 @@ msgstr "" msgid "Reset current rotation to real zeros." msgstr "" +msgctxt "Noun" +msgid "Scale" +msgstr "" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "" @@ -586,9 +774,6 @@ msgstr "" msgid "Confirm connectors" msgstr "" -msgid "Cancel" -msgstr "" - msgid "Flip cut plane" msgstr "" @@ -629,10 +814,10 @@ msgstr "" msgid "Reset cutting plane and remove connectors" msgstr "" -msgid "Perform cut" +msgid "Reset Cut" msgstr "" -msgid "Warning" +msgid "Perform cut" msgstr "" msgid "Invalid connectors detected" @@ -665,6 +850,13 @@ msgstr "" msgid "Connector" msgstr "" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "" @@ -711,9 +903,6 @@ msgstr "" msgid "Simplification is currently only allowed when a single part is selected" msgstr "" -msgid "Error" -msgstr "" - msgid "Extra high" msgstr "" @@ -1942,6 +2131,9 @@ msgstr "" msgid "Loading user preset" msgstr "" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -1955,6 +2147,18 @@ msgstr "" msgid "Language" msgstr "" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "" @@ -2548,6 +2752,45 @@ msgstr "" msgid "Click the icon to shift this object to the bed" msgstr "" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "" @@ -2557,6 +2800,9 @@ msgstr "" msgid "Failed to get the model data in the current file." msgstr "" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "" @@ -2569,6 +2815,12 @@ msgstr "" msgid "Remove paint-on fuzzy skin" msgstr "" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "" + msgid "Delete connector from object which is a part of cut" msgstr "" @@ -2594,12 +2846,24 @@ msgstr "" msgid "Deleting the last solid part is not allowed." msgstr "" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "" +msgid "Split to parts" +msgstr "" + msgid "Assembly" msgstr "" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "" @@ -2630,6 +2894,9 @@ msgstr "" msgid "Settings for height range" msgstr "" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "" @@ -2651,6 +2918,9 @@ msgstr "" msgid "Choose part type" msgstr "" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "" @@ -2678,6 +2948,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "" @@ -2687,9 +2960,6 @@ msgstr "" msgid "to" msgstr "" -msgid "Remove height range" -msgstr "" - msgid "Add height range" msgstr "" @@ -2892,6 +3162,9 @@ msgstr "" msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3013,6 +3286,24 @@ msgstr "" msgid "Check filament location" msgstr "" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3064,6 +3355,62 @@ msgstr "" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3377,15 +3724,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "" - msgid "AMS Materials Setting" msgstr "" -msgid "Confirm" -msgstr "" - msgid "Close" msgstr "" @@ -3404,10 +3745,10 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "" -msgid "SN" +msgid "Factors of Flow Dynamics Calibration" msgstr "" -msgid "Factors of Flow Dynamics Calibration" +msgid "Wiki Guide" msgstr "" msgid "PA Profile" @@ -3495,6 +3836,7 @@ msgstr "" msgid "Save" msgstr "" +msgctxt "Navigation" msgid "Back" msgstr "" @@ -3569,6 +3911,19 @@ msgstr "" msgid "Nozzle" msgstr "" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4200,9 +4555,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "" - msgid "Update successful." msgstr "" @@ -4708,9 +5060,6 @@ msgstr "" msgid "Regroup filament" msgstr "" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "" @@ -4744,7 +5093,7 @@ msgstr "" msgid "Fan speed (%)" msgstr "" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "" msgid "Volumetric flow rate (mm³/s)" @@ -4762,9 +5111,6 @@ msgstr "" msgid "Options" msgstr "" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "" @@ -4777,6 +5123,7 @@ msgstr "" msgid "Color change" msgstr "" +msgctxt "Noun" msgid "Print" msgstr "" @@ -4932,11 +5279,15 @@ msgstr "" msgid "Align to Y axis" msgstr "" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "" + +msgctxt "Camera View" msgid "Left" msgstr "" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "" @@ -4961,9 +5312,6 @@ msgstr "" msgid "Split to objects" msgstr "" -msgid "Split to parts" -msgstr "" - msgid "Assembly View" msgstr "" @@ -5253,6 +5601,10 @@ msgstr "" msgid "Export G-code file" msgstr "" +msgctxt "Verb" +msgid "Print" +msgstr "" + msgid "Export plate sliced file" msgstr "" @@ -5426,15 +5778,6 @@ msgstr "" msgid "Export" msgstr "" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "" @@ -5549,6 +5892,15 @@ msgstr "" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5666,6 +6018,9 @@ msgstr "" msgid "Select profile to load:" msgstr "" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5820,9 +6175,6 @@ msgstr "" msgid "Batch manage files." msgstr "" -msgid "Refresh" -msgstr "" - msgid "Reload file list from printer." msgstr "" @@ -6123,6 +6475,9 @@ msgstr "" msgid "Safety Options" msgstr "" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "" @@ -6156,6 +6511,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6204,9 +6565,6 @@ msgstr "" msgid "Silent" msgstr "" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "" @@ -6240,6 +6598,12 @@ msgstr "" msgid "Delete Photo" msgstr "" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "" @@ -6413,6 +6777,9 @@ msgstr "" msgid "Don't show this dialog again" msgstr "" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "" @@ -6658,25 +7025,16 @@ msgstr "" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "" - -msgid "Stainless Steel" -msgstr "" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" +msgid "No wiki link available for this printer." msgstr "" msgid "Unavailable while heating maintenance function is on." @@ -6801,6 +7159,15 @@ msgstr "" msgid "Configuration incompatible" msgstr "" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "" + msgid "Sync printer information" msgstr "" @@ -6827,6 +7194,9 @@ msgstr "" msgid "Project Filaments" msgstr "" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "" @@ -7035,9 +7405,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "" - msgid "The file does not contain any geometry data." msgstr "" @@ -7080,9 +7447,21 @@ msgid "" "After that, model consistency can't be guaranteed." msgstr "" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7107,6 +7486,9 @@ msgstr "" msgid "File for the replacement wasn't selected" msgstr "" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7153,6 +7535,9 @@ msgstr "" msgid "Error during reload" msgstr "" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "" @@ -7882,6 +8267,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -7897,16 +8291,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8179,6 +8564,9 @@ msgstr "" msgid "My Printer" msgstr "" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8197,6 +8585,9 @@ msgstr "" msgid "Edit preset" msgstr "" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "" @@ -8227,9 +8618,6 @@ msgstr "" msgid "Create printer" msgstr "" -msgid "Empty" -msgstr "" - msgid "Incompatible" msgstr "" @@ -8452,11 +8840,41 @@ msgstr "" msgid "Error code" msgstr "" -msgid "High Flow" +msgid "Error desc" +msgstr "" + +msgid "Extra info" +msgstr "" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, c-format, boost-format @@ -8519,7 +8937,37 @@ msgstr "" msgid "nozzle" msgstr "" -msgid "both extruders" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8533,10 +8981,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -8646,9 +9101,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -8825,6 +9277,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "" @@ -8891,9 +9346,6 @@ msgstr "" msgid "Adjust" msgstr "" -msgid "Ignore" -msgstr "" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "" @@ -9373,6 +9825,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9584,6 +10042,12 @@ msgstr "" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "" @@ -9829,11 +10293,7 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" -msgstr "" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" +msgid "Do you want to continue to sync filaments?" msgstr "" msgid "Successfully synchronized filament color from printer." @@ -9939,6 +10399,9 @@ msgstr "" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10245,6 +10708,9 @@ msgstr "" msgid "Where to find your printer's IP and Access Code?" msgstr "" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "" @@ -10307,6 +10773,9 @@ msgstr "" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "" @@ -10325,6 +10794,9 @@ msgstr "" msgid "Update successful" msgstr "" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "" @@ -10424,6 +10896,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "" @@ -11069,7 +11544,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11083,7 +11558,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11459,9 +11934,6 @@ msgid "" "0 to deactivate." msgstr "" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "" @@ -11471,9 +11943,6 @@ msgstr "" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "" -msgid "Select profiles" -msgstr "" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "" @@ -11707,6 +12176,42 @@ msgstr "" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "" @@ -11990,12 +12495,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12248,6 +12759,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "" @@ -12307,12 +12824,12 @@ msgstr "" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -12797,6 +13314,15 @@ msgstr "" msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -12856,6 +13382,12 @@ msgid "" "G-code command: M106 P3 S(0-255)" msgstr "" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "" @@ -13353,6 +13885,30 @@ msgstr "" msgid "Minimum travel speed (M205 T)" msgstr "" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "" @@ -13853,6 +14409,9 @@ msgstr "" msgid "Bowden" msgstr "" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -13886,6 +14445,12 @@ msgstr "" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "" @@ -13916,6 +14481,9 @@ msgstr "" msgid "Aligned back" msgstr "" +msgid "Back" +msgstr "" + msgid "Random" msgstr "" @@ -14165,6 +14733,12 @@ msgstr "" msgid "Traditional" msgstr "" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "" @@ -14250,6 +14824,18 @@ msgstr "" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "" @@ -14604,7 +15190,7 @@ msgid "" msgstr "" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -14653,6 +15239,45 @@ msgstr "" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "" @@ -14691,12 +15316,30 @@ msgstr "" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "" @@ -14961,6 +15604,57 @@ msgstr "" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "" +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "" @@ -15693,12 +16387,6 @@ msgstr "" msgid "Calibration not supported" msgstr "" -msgid "Error desc" -msgstr "" - -msgid "Extra info" -msgstr "" - msgid "Flow Dynamics" msgstr "" @@ -15871,6 +16559,12 @@ msgstr "" msgid "The name cannot exceed 40 characters." msgstr "" +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "" @@ -15960,9 +16654,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "" @@ -16033,6 +16724,10 @@ msgstr "" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "" @@ -17682,6 +18377,12 @@ msgstr "" msgid "Removed" msgstr "" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -17715,12 +18416,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -17952,9 +18666,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "" - msgid "Null Color" msgstr "" diff --git a/localization/i18n/es/OrcaSlicer_es.po b/localization/i18n/es/OrcaSlicer_es.po index cdbe024f27..df95bdcb22 100644 --- a/localization/i18n/es/OrcaSlicer_es.po +++ b/localization/i18n/es/OrcaSlicer_es.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: Ian A. Bassi <>\n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPU no soportado por el AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "'Bambu Lab PET-CF' no soportado por el AMS." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Por favor, realice un cold pull antes de imprimir TPU para evitar obstrucciones. Puede utilizar el cold pull de mantenimiento de la impresora." @@ -47,6 +65,9 @@ msgstr "El PVA húmedo es flexible y puede atascarse en el extrusor. Séquelo an msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "La superficie rugosa del PLA Glow puede acelerar el desgaste del sistema AMS, especialmente en los componentes internos del AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Los filamentos CF/GF son duros y quebradizos. Es fácil romperlos o crear atascos en el AMS, por favor úselos con precaución." @@ -56,10 +77,90 @@ msgstr "PPS-CF es quebradizo y podría romperse en el tubo PTFE doblado por enci msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF es quebradizo y podría romperse en el tubo PTFE doblado por encima del cabezal de la herramienta." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s no es compatible con el extrusor %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Flujo alto" + +msgid "Standard" +msgstr "Estándar" + +msgid "TPU High Flow" +msgstr "TPU de alto flujo" + +msgid "Unknown" +msgstr "Desconocido" + +msgid "Hardened Steel" +msgstr "Acero endurecido" + +msgid "Stainless Steel" +msgstr "Acero inoxidable" + +msgid "Tungsten Carbide" +msgstr "Carburo de tungsteno" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Es posible que el cabezal y el rack del hotend se muevan. Mantenga las manos alejadas de la cámara." + +msgid "Warning" +msgstr "Advertencia" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "La información del hotend podría ser inexacta. ¿Desea volver a leer el hotend? (La información del hotend puede cambiar al apagar el dispositivo)." + +msgid "I confirm all" +msgstr "Confirmar todo" + +msgid "Re-read all" +msgstr "Volver a leerlo todo" + +msgid "Reading the hotends, please wait." +msgstr "Leyendo los hotends, por favor espere." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Durante la actualización del hotend, el cabezal se moverá. No meta la mano en la cámara." + +msgid "Update" +msgstr "Actualizar" + msgid "Current AMS humidity" msgstr "Humedad actual del AMS" @@ -90,6 +191,85 @@ msgstr "Versión:" msgid "Latest version" msgstr "Última versión" +msgid "Row A" +msgstr "Fila A" + +msgid "Row B" +msgstr "Fila B" + +msgid "Toolhead" +msgstr "Cabezal" + +msgid "Empty" +msgstr "Vacío" + +msgid "Error" +msgstr "Error" + +msgid "Induction Hotend Rack" +msgstr "Estante de Hotend por Inducción" + +msgid "Hotends Info" +msgstr "Información de Hotends" + +msgid "Read All" +msgstr "Leer todo" + +msgid "Reading " +msgstr "Leyendo " + +msgid "Please wait" +msgstr "Espere por favor" + +msgid "Running..." +msgstr "En ejecución..." + +msgid "Raised" +msgstr "Aumentado" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Este hotend presenta un problema y no está disponible en este momento. Por favor, vaya a \"Dispositivo -> Actualizar\" para actualizar el firmware." + +msgid "Abnormal Hotend" +msgstr "Hotend anómalo" + +msgid "Refresh" +msgstr "Actualizar" + +msgid "Refreshing" +msgstr "Actualizando" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "El estado del hotend es anormal y no está disponible actualmente. Por favor, actualice el firmware e inténtelo de nuevo." + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Jump to the upgrade page" +msgstr "Ir a la página de actualización" + +msgid "SN" +msgstr "SN" + +msgid "Version" +msgstr "Versión" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Tiempo empleado: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Las boquillas dinámicas están asignadas a la placa actual. Seleccionar hotend no está soportado." + +msgid "Hotend Rack" +msgstr "Rack del hotend" + +msgid "ToolHead" +msgstr "Cabezal" + +msgid "Nozzle information needs to be read" +msgstr "Es necesario leer la información de la boquilla" + msgid "Support Painting" msgstr "Pintar soportes" @@ -159,6 +339,12 @@ msgstr "Llenar" msgid "Gap Fill" msgstr "Rellenar huecos" +msgid "Vertical" +msgstr "Vertical" + +msgid "Horizontal" +msgstr "Horizontal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Permite pintar solo las facetas seleccionadas por: \"%1%\"" @@ -251,12 +437,6 @@ msgstr "Triángulo" msgid "Height Range" msgstr "Rango de altura" -msgid "Vertical" -msgstr "Vertical" - -msgid "Horizontal" -msgstr "Horizontal" - msgid "Remove painted color" msgstr "Eliminar color pintado" @@ -321,6 +501,7 @@ msgstr "Herramienta de rotación" msgid "Optimize orientation" msgstr "Optimizar orientación" +msgctxt "Verb" msgid "Scale" msgstr "Escalar" @@ -332,7 +513,7 @@ msgstr "Error: Por favor, cierre primero todos los menús de la barra de herrami msgctxt "inches" msgid "in" -msgstr "" +msgstr "″" msgid "mm" msgstr "mm" @@ -364,6 +545,9 @@ msgstr "Factor de escalado" msgid "Object operations" msgstr "Operaciones con objetos" +msgid "Scale" +msgstr "Escalar" + msgid "Volume operations" msgstr "Operaciones de volumen" @@ -409,6 +593,10 @@ msgstr "Restablecer la rotación actual al valor que tenía al abrir la herramie msgid "Reset current rotation to real zeros." msgstr "Restablecer la rotación actual a ceros reales." +msgctxt "Noun" +msgid "Scale" +msgstr "Escala" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Tamaño" @@ -591,9 +779,6 @@ msgstr "Proporción de espacio en relación al radio" msgid "Confirm connectors" msgstr "Confirmar conectores" -msgid "Cancel" -msgstr "Cancelar" - msgid "Flip cut plane" msgstr "Voltear plano de corte" @@ -634,12 +819,12 @@ msgstr "Cortar en piezas" msgid "Reset cutting plane and remove connectors" msgstr "Reajustar el plano de corte y retirar los conectores" +msgid "Reset Cut" +msgstr "Reiniciar corte" + msgid "Perform cut" msgstr "Realizar corte" -msgid "Warning" -msgstr "Advertencia" - msgid "Invalid connectors detected" msgstr "Conectores inválidos detectados" @@ -670,6 +855,16 @@ msgstr "El plano de corte con ranura no es válido" msgid "Connector" msgstr "Conector" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" +"Los objetos(%1%) tienen conectores duplicados. Es posible que falten algunos conectores en el resultado del laminado.\n" +"Informe al equipo de PrusaSlicer sobre el escenario en el que se produjo este problema.\n" +"Gracias." + msgid "Cut by Plane" msgstr "Corte por plano" @@ -716,9 +911,6 @@ msgstr "Simplificar" msgid "Simplification is currently only allowed when a single part is selected" msgstr "La simplificación por el momento sólo se permite cuando se selecciona una sola pieza" -msgid "Error" -msgstr "Error" - msgid "Extra high" msgstr "Extra alto" @@ -2006,6 +2198,9 @@ msgstr "El acceso al paquete %s no está autorizado." msgid "Loading user preset" msgstr "Cargando perfil de usuario" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "Hay una actualización disponible. Abra el cuadro de diálogo del paquete de perfiles para actualizarlo." + #, c-format, boost-format msgid "%s has been removed." msgstr "Se ha eliminado %s." @@ -2019,6 +2214,20 @@ msgstr "Seleccionar el idioma" msgid "Language" msgstr "Idioma" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "No se pudo cambiar Orca Slicer al idioma %s." + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" +"\n" +"Puede que necesite reconfigurar las configuraciones regionales que faltan, probablemente ejecutando los comandos \"locale-gen\" y \"dpkg-reconfigure locales\".\n" + +msgid "Orca Slicer - Switching language failed" +msgstr "Orca Slicer - Error al cambiar el idioma" + msgid "*" msgstr "*" @@ -2615,6 +2824,45 @@ msgstr "Haga clic en el icono para editar el pintado de colores del objeto" msgid "Click the icon to shift this object to the bed" msgstr "Presionar el icono para desplazar este objeto a la cama" +msgid "Rename Object" +msgstr "Renombrar objeto" + +msgid "Rename Part" +msgstr "Renombrar pieza" + +msgid "Paste settings" +msgstr "Pegar ajustes" + +msgid "Shift objects to bed" +msgstr "Desplazar objetos a la cama" + +msgid "Object order changed" +msgstr "Orden de objetos cambiado" + +msgid "Layer setting added" +msgstr "Ajuste de capa añadido" + +msgid "Part setting added" +msgstr "Ajuste de pieza añadido" + +msgid "Object setting added" +msgstr "Ajuste de objeto añadido" + +msgid "Height range settings added" +msgstr "Ajustes de rango de altura añadidos" + +msgid "Part settings added" +msgstr "Ajustes de pieza añadidos" + +msgid "Object settings added" +msgstr "Ajustes de objeto añadidos" + +msgid "Load Part" +msgstr "Cargar pieza" + +msgid "Load Modifier" +msgstr "Cargar modificador" + msgid "Loading file" msgstr "Cargando archivo" @@ -2624,6 +2872,9 @@ msgstr "¡Error!" msgid "Failed to get the model data in the current file." msgstr "Fallo recuperando los datos del modelo del archivo actual." +msgid "Add primitive" +msgstr "Añadir primitivo" + msgid "Generic" msgstr "Genérico" @@ -2636,6 +2887,12 @@ msgstr "Cambiar al modo de ajuste a modo por objeto para editar los ajustes de p msgid "Remove paint-on fuzzy skin" msgstr "Eliminar la piel rugosa pintada" +msgid "Delete Settings" +msgstr "Borrar ajustes" + +msgid "Remove height range" +msgstr "Borrar rango de altura" + msgid "Delete connector from object which is a part of cut" msgstr "Borrar conector del objeto el cual es parte del corte" @@ -2665,12 +2922,24 @@ msgstr "Borrar todos los conectores" msgid "Deleting the last solid part is not allowed." msgstr "No se permite borrar la última parte sólida." +msgid "Delete part" +msgstr "Borrar pieza" + msgid "The target object contains only one part and can not be split." msgstr "El objeto de destino contiene solo una parte y no se puede dividir." +msgid "Split to parts" +msgstr "Separar en piezas" + msgid "Assembly" msgstr "Ensamblaje" +msgid "Merge parts to an object" +msgstr "Fusionar piezas en un objeto" + +msgid "Add layers" +msgstr "Añadir capas" + msgid "Cut Connectors information" msgstr "Información de Conectores de Corte" @@ -2701,6 +2970,9 @@ msgstr "Rangos de altura" msgid "Settings for height range" msgstr "Ajustes de rango de altura" +msgid "Delete selected" +msgstr "Borrar seleccionado" + msgid "Layer" msgstr "Capa" @@ -2722,6 +2994,9 @@ msgstr "Tipo:" msgid "Choose part type" msgstr "Elija el tipo de pieza" +msgid "Instances to Separated Objects" +msgstr "Instancias a objetos separados" + msgid "Enter new name" msgstr "Introduce un nuevo nombre" @@ -2749,6 +3024,9 @@ msgstr "\"%s\" tendrá más de 1 millón de caras tras esta subdivisión, lo que msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "La malla de la pieza \"%s\" contiene errores. Por favor, repárela primero." +msgid "Change Filaments" +msgstr "Cambiar filamentos" + msgid "Additional process preset" msgstr "Perfil de proceso adicional" @@ -2758,9 +3036,6 @@ msgstr "Eliminar parámetro" msgid "to" msgstr "a" -msgid "Remove height range" -msgstr "Borrar rango de altura" - msgid "Add height range" msgstr "Añadir rango de altura" @@ -2963,6 +3238,9 @@ msgstr "Elija una ranura AMS y pulse el botón \"Cargar\" o \"Descargar\" para c msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Se desconoce el tipo de filamento necesario para realizar esta acción. Configure la información del filamento de destino." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Cambiar la velocidad del ventilador durante la impresión puede afectar a la calidad de impresión, por lo que se recomienda elegir con cuidado." @@ -3084,6 +3362,24 @@ msgstr "Confirmación de extrusión" msgid "Check filament location" msgstr "Probar localización de filamento" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "La temperatura máxima no puede superar " @@ -3135,6 +3431,62 @@ msgstr "Modo de desarrollador" msgid "Launch troubleshoot center" msgstr "Abrir el centro de resolución de problemas" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Por favor, configure el número de boquillas" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Error: No se puede establecer el conteo de boquillas a cero." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Error: La cantidad de boquillas no puede exceder de %d." + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Extruder" +msgstr "Extrusor" + +msgid "Nozzle Selection" +msgstr "Guía de selección de boquillas" + +msgid "Available Nozzles" +msgstr "Boquillas Disponibles" + +msgid "Nozzle Info" +msgstr "Información de boquilla" + +msgid "Sync Nozzle status" +msgstr "Estado de la boquilla de sincronización" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Precaución: No se incluye la combinación de diámetros de boquilla en una misma impresión. Si el tamaño seleccionado está únicamente en un extrusor, se aplicará la impresión con un solo extrusor." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Actualizar %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Se ha detectado una boquilla desconocida. Actualice para obtener información actualizada (las boquillas no actualizadas se excluirán durante el corte). Verifique el diámetro y la tasa de flujo de la boquilla con los valores mostrados." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Boquilla desconocida detectada. Actualiza para sincronizarla (las boquillas no actualizadas se omitirán durante el laminado)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Por favor, confirme si el diámetro de la boquilla y el caudal requeridos coinciden con los valores que se muestran actualmente." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Su impresora tiene diferentes boquillas instaladas. Por favor, seleccione una boquilla para esta impresión." + +msgid "Ignore" +msgstr "Ignorar" + +msgid "Done." +msgstr "Hecho." + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3458,15 +3810,9 @@ msgstr "OrcaSlicer nació con ese mismo espíritu, inspirándose en PrusaSlicer, msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Hoy en día, OrcaSlicer es el programa de corte de código abierto más utilizado y con mayor desarrollo activo en la comunidad de la impresión 3D. Muchas de sus innovaciones han sido adoptadas por otros programas de corte, lo que lo convierte en un motor impulsor de todo el sector." -msgid "Version" -msgstr "Versión" - msgid "AMS Materials Setting" msgstr "Ajustes de materiales AMS" -msgid "Confirm" -msgstr "Confirmar" - msgid "Close" msgstr "Cerrar" @@ -3487,12 +3833,12 @@ msgstr "min" msgid "The input value should be greater than %1% and less than %2%" msgstr "El valor de entrada debe ser mayor que %1% y menor que %2%" -msgid "SN" -msgstr "SN" - msgid "Factors of Flow Dynamics Calibration" msgstr "Factores de calibración de dinámicas de flujo" +msgid "Wiki Guide" +msgstr "Guía en Wiki" + msgid "PA Profile" msgstr "Perfil de «Pressure advance»" @@ -3580,6 +3926,7 @@ msgstr "Calibración completada. Por favor, observe cual es línea de extrusión msgid "Save" msgstr "Guardar" +msgctxt "Navigation" msgid "Back" msgstr "Atrás" @@ -3663,6 +4010,19 @@ msgstr "Boquilla derecha" msgid "Nozzle" msgstr "Boquilla" +msgid "Select Filament && Hotends" +msgstr "Seleccionar Filamento && Hotends" + +msgid "Select Filament" +msgstr "Seleccionar Filamento" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "La impresión con la boquilla actual puede producir un extra de %0.2f g de desperdicio." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Nota: el tipo de filamento (%s) no coincide con el tipo de filamento (%s) del archivo. Si desea utilizar esta posición, puede instalar %s en lugar de %s y cambiar la información de la ranura en la página «Dispositivo»." @@ -4350,9 +4710,6 @@ msgstr "Midiendo la superficie" msgid "Calibrating the detection position of nozzle clumping" msgstr "Calibrando la posición de detección de acumulación en la boquilla" -msgid "Unknown" -msgstr "Desconocido" - msgid "Update successful." msgstr "Actualización exitosa." @@ -4709,7 +5066,7 @@ msgid "Support interface" msgstr "Interfaz de soporte" msgid "Prime tower" -msgstr "Torre de Purga" +msgstr "Torre de purga" msgid "Bottom surface" msgstr "Relleno sólido inferior" @@ -4861,9 +5218,6 @@ msgstr "Ajustar a óptimo" msgid "Regroup filament" msgstr "Reagrupar filamentos" -msgid "Wiki Guide" -msgstr "Guía en Wiki" - msgid "up to" msgstr "hasta" @@ -4897,8 +5251,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Velocidad Ventilador (%)" -msgid "Temperature (°C)" -msgstr "Temperatura (°C)" +msgid "Temperature (℃)" +msgstr "Temperatura (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Tasa de flujo volumétrico (mm³/seg)" @@ -4915,9 +5269,6 @@ msgstr "Cambios de filamento" msgid "Options" msgstr "Opciones" -msgid "Extruder" -msgstr "Extrusor" - msgid "Cost" msgstr "Coste" @@ -4930,8 +5281,9 @@ msgstr "Cambios de herramienta" msgid "Color change" msgstr "Cambio de color" +msgctxt "Noun" msgid "Print" -msgstr "Imprimir" +msgstr "Impresión" msgid "Printer" msgstr "Impresora" @@ -5089,11 +5441,15 @@ msgstr "Evitar la zona de calibración del extrusor" msgid "Align to Y axis" msgstr "Alinear con el eje Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Posterior" + +msgctxt "Camera View" msgid "Left" msgstr "Izquierda" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Derecha" @@ -5118,9 +5474,6 @@ msgstr "Organizar los objetos en las camas seleccionadas" msgid "Split to objects" msgstr "Separar en objetos" -msgid "Split to parts" -msgstr "Separar en piezas" - msgid "Assembly View" msgstr "Vista de Emsamblado" @@ -5416,6 +5769,10 @@ msgstr "Imprimir cama" msgid "Export G-code file" msgstr "Exportar archivo G-Code" +msgctxt "Verb" +msgid "Print" +msgstr "Imprimir" + msgid "Export plate sliced file" msgstr "Exportar los objetos laminados de la cama a un archivo" @@ -5488,10 +5845,10 @@ msgid "Front View" msgstr "Vista frontal" msgid "Rear" -msgstr "Trasera" +msgstr "Posterior" msgid "Rear View" -msgstr "Vista trasera" +msgstr "Vista posterior" msgid "Left View" msgstr "Vista izquierda" @@ -5589,15 +5946,6 @@ msgstr "Exportar configuración actual a archivos" msgid "Export" msgstr "Exportar" -msgid "Sync Presets" -msgstr "Sincronizar perfiles" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Descarga y aplica los últimos ajustes preestablecidos de OrcaCloud" - -msgid "You must be logged in to sync presets from cloud." -msgstr "Debes haber iniciado sesión para sincronizar los ajustes preestablecidos desde la nube." - msgid "Quit" msgstr "Salir del programa" @@ -5712,6 +6060,15 @@ msgstr "Vista" msgid "Preset Bundle" msgstr "Paquete de perfiles" +msgid "Sync Presets" +msgstr "Sincronizar perfiles" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Descarga y aplica los últimos ajustes preestablecidos de OrcaCloud" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Debes haber iniciado sesión para sincronizar los ajustes preestablecidos desde la nube." + msgid "Syncing presets from cloud…" msgstr "Sincronizando perfiles desde la nube…" @@ -5829,6 +6186,9 @@ msgstr "Exportar resultado" msgid "Select profile to load:" msgstr "Seleccionar perfil a cargar:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "Archivos de configuración (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5995,9 +6355,6 @@ msgstr "Descargar achivos seleccionados desde la impresora." msgid "Batch manage files." msgstr "Procesado de archivo por lotes." -msgid "Refresh" -msgstr "Actualizar" - msgid "Reload file list from printer." msgstr "Recarga la lista de archivos desde la impresora." @@ -6304,6 +6661,9 @@ msgstr "Opciones de Impresora" msgid "Safety Options" msgstr "Opciones de seguridad" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Luz" @@ -6337,6 +6697,12 @@ msgstr "Cuando la impresión está en pausa, la carga y descarga de filamento so msgid "Current extruder is busy changing filament." msgstr "El extrusor actual está ocupado cambiando el filamento." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "La ranura actual ya está cargada." @@ -6385,9 +6751,6 @@ msgstr "Esto solo tendrá efecto durante la impresión" msgid "Silent" msgstr "Silencioso" -msgid "Standard" -msgstr "Estándar" - msgid "Sport" msgstr "Deportivo" @@ -6421,6 +6784,12 @@ msgstr "Añadir Foto" msgid "Delete Photo" msgstr "Borrar Foto" +msgid "Select Images" +msgstr "Seleccionar imágenes" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "Archivos de imagen (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" + msgid "Submit" msgstr "Aceptar" @@ -6604,6 +6973,9 @@ msgstr "Cómo usar el modo solo LAN" msgid "Don't show this dialog again" msgstr "No mostrar este mensaje de nuevo" +msgid "Please refer to Wiki before use->" +msgstr "Consulte la Wiki antes de usar->" + msgid "3D Mouse disconnected." msgstr "Ratón 3D desconectado." @@ -6851,27 +7223,18 @@ msgstr "Flujo" msgid "Please change the nozzle settings on the printer." msgstr "Por favor, cambie los ajustes de la boquilla en la impresora." -msgid "Hardened Steel" -msgstr "Acero endurecido" - -msgid "Stainless Steel" -msgstr "Acero inoxidable" - -msgid "Tungsten Carbide" -msgstr "Carburo de tungsteno" - msgid "Brass" msgstr "Latón" msgid "High flow" msgstr "Alto flujo" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "No hay enlace a la wiki disponible para esta impresora." -msgid "Refreshing" -msgstr "Actualizando" - msgid "Unavailable while heating maintenance function is on." msgstr "No disponible mientras la función de mantenimiento de calentamiento esté activa." @@ -6994,6 +7357,15 @@ msgstr "Cambiar diámetro" msgid "Configuration incompatible" msgstr "Configuración incompatible" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Consejos" + msgid "Sync printer information" msgstr "Sincronizar información de la impresora" @@ -7022,6 +7394,9 @@ msgstr "Click para cambiar el ajuste inicial" msgid "Project Filaments" msgstr "Filamentos del proyecto" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volúmenes de limpieza" @@ -7237,9 +7612,6 @@ msgstr "La impresora conectada es %s. Debe coincidir con el preajuste del proyec msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "¿Desea sincronizar la información de la impresora y cambiar automáticamente el preajuste?" -msgid "Tips" -msgstr "Consejos" - msgid "The file does not contain any geometry data." msgstr "El archivo no contiene ninguna información geométrica." @@ -7287,9 +7659,21 @@ msgstr "" "Esta acción romperá una correspondencia de corte.\n" "Después de eso la consistencia del modelo no puede ser garantizada." +msgid "Delete Object" +msgstr "Borrar objeto" + +msgid "Delete All Objects" +msgstr "Borrar todos los objetos" + +msgid "Reset Project" +msgstr "Reiniciar proyecto" + msgid "The selected object couldn't be split." msgstr "El objeto seleccionado no ha podido ser dividido." +msgid "Split to Objects" +msgstr "Separar en objetos" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "¿Desactivar la caída automática para mantener la posición en el eje Z?\n" @@ -7314,6 +7698,9 @@ msgstr "Seleccione un nuevo archivo" msgid "File for the replacement wasn't selected" msgstr "El archivo de reemplazo no ha sido seleccionado" +msgid "Replace with 3D file" +msgstr "Reemplazar con archivo 3D" + msgid "Select folder to replace from" msgstr "Seleccionar carpeta desde la que reemplazar" @@ -7360,6 +7747,9 @@ msgstr "No es posible recargar:" msgid "Error during reload" msgstr "Error durante la recarga" +msgid "Reload all" +msgstr "Recargar todo" + msgid "There are warnings after slicing models:" msgstr "Hay alertas después de laminar los modelos:" @@ -8128,6 +8518,18 @@ msgstr "Limpiar mi elección para sincronizar el preajuste de la impresora despu msgid "Graphics" msgstr "Gráficos" +msgid "Smooth normals" +msgstr "Suavizar normales" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" +"Aplica normales suavizadas al modelo.\n" +"\n" +"Requiere recargar manualmente la escena para que surta efecto (clic derecho en la vista 3D → «Recargar todo»)." + msgid "Phong shading" msgstr "Sombreado Phong" @@ -8143,20 +8545,8 @@ msgstr "Aplica SSAO en vista realista." msgid "Shadows" msgstr "Sombras" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "Los objetos renderizados proyectan sombras sobre la cama en la vista realista." - -msgid "Smooth normals" -msgstr "Suavizar normales" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." -msgstr "" -"Aplica normales suavizadas a la vista realista.\n" -"\n" -"Requiere recargar la escena manualmente para que surta efecto (clic derecho en la vista 3D → \"Recargar todo\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." +msgstr "Renderiza sombras proyectadas sobre la cama, sobre otros objetos y de cada objeto sobre sí mismo en la vista realista." msgid "Anti-aliasing" msgstr "Anti-aliasing" @@ -8446,6 +8836,9 @@ msgstr "Perfiles incompatibles" msgid "My Printer" msgstr "Mi impresora" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filamentos del lado izquierdo" @@ -8464,6 +8857,9 @@ msgstr "Añadir/Quitar ajustes" msgid "Edit preset" msgstr "Editar ajuste" +msgid "Change extruder color" +msgstr "Cambiar color del extrusor" + msgid "Unspecified" msgstr "No especificado" @@ -8494,9 +8890,6 @@ msgstr "Seleccionar/Borrar impresoras (perfiles del sistema)" msgid "Create printer" msgstr "Crear impresora" -msgid "Empty" -msgstr "Vacío" - msgid "Incompatible" msgstr "Incompatible" @@ -8725,12 +9118,42 @@ msgstr "Envío completo" msgid "Error code" msgstr "Código de error" -msgid "High Flow" -msgstr "Flujo alto" +msgid "Error desc" +msgstr "Error en la descripción" + +msgid "Extra info" +msgstr "Información extra" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "La configuración de flujo de la boquilla de %s(%s) no coincide con el archivo de laminado (%s). Asegúrese de que la boquilla instalada coincide con los ajustes de la impresora y, al laminar, seleccione el preajuste de impresora correspondiente." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8792,8 +9215,38 @@ msgstr "Costo %dg de filamento y %d cambios más que la agrupación óptima." msgid "nozzle" msgstr "boquilla" -msgid "both extruders" -msgstr "ambos extrusores" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "La configuración de flujo de la boquilla de %s(%s) no coincide con el archivo de laminado (%s). Asegúrese de que la boquilla instalada coincide con los ajustes de la impresora y, al laminar, seleccione el preajuste de impresora correspondiente." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Consejo: Si ha cambiado recientemente la boquilla de su impresora, vaya a 'Dispositivo -> Piezas de la impresora' para actualizar la configuración de la boquilla." @@ -8806,10 +9259,17 @@ msgstr "El diámetro %s (%.1f mm) de la impresora actual no coincide con el del msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "El diámetro actual de la boquilla (%.1f mm) no coincide con el del archivo de laminado (%.1f mm). Asegúrese de que la boquilla instalada coincide con la configuración de la impresora y seleccione el preset de impresora correspondiente al laminar." +msgid "both extruders" +msgstr "ambos extrusores" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "La dureza del material actual (%s) supera la dureza de %s(%s). Verifique la boquilla o la configuración del material e inténtelo de nuevo." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] requiere impresión en un entorno de alta temperatura. Por favor, cierre la puerta." @@ -8919,9 +9379,6 @@ msgstr "El firmware actual admite un máximo de 16 materiales. Puede reducir el msgid "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." msgstr "Se desconoce el tipo de filamento externo o no coincide con el tipo de filamento indicado en el archivo de corte. Asegúrate de haber colocado el filamento correcto en la bobina externa." -msgid "Please refer to Wiki before use->" -msgstr "Consulte la Wiki antes de usar->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "El firmware actual no admite la transferencia de archivos al almacenamiento interno." @@ -9100,6 +9557,9 @@ msgstr "Sincroniza la modificación de parámetros con los parámetros correspon msgid "Click to reset all settings to the last saved preset." msgstr "Presionar para reiniciar todos los ajustes al perfil guardado por defecto." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Se requiere una torre de purga para el cambio de boquilla. Puede haber imperfecciones en el modelo sin la torre de purga. ¿Está seguro de que desea desactivar la torre de purga?" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Se requiere una torre de purga para un timelapse suave. Puede haber defectos en los modelos si no se usa una torre de purga. ¿Está seguro de que quiere deshabilitar la torre de purgado?" @@ -9178,9 +9638,6 @@ msgstr "¿Desea ajustar el rango automáticamente?\n" msgid "Adjust" msgstr "Ajustar" -msgid "Ignore" -msgstr "Ignorar" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Función experimental: retraer y cortar el filamento a una mayor distancia durante los cambios de filamento para minimizar el purgado. Aunque puede reducir notablemente el purgado, también puede aumentar el riesgo de atascos de boquilla u otras complicaciones de impresión.Característica experimental: Retraer y cortar el filamento a mayor distancia durante los cambios de filamento para minimizar el descarte. Aunque puede reducir notablemente el descarte, también puede elevar el riesgo de atascos de boquillas u otros problemas en la impresión." @@ -9190,7 +9647,7 @@ msgstr "Característica experimental: Retraer y cortar el filamento a mayor dist msgid "" "When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n" "by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\"." -msgstr "Cuando se graba un timelapse sin cabezal, se recomienda añadir una \"Torre de Purga de Timelapse\" haciendo clic con el botón derecho del ratón en una posición vacía de la cama de impresión y seleccionando \"Añadir Primitivo\"->Torre de Purga de Timelapse\"." +msgstr "Cuando se graba un timelapse sin cabezal, se recomienda añadir una \"Torre de purga de Timelapse\" haciendo clic con el botón derecho del ratón en una posición vacía de la cama de impresión y seleccionando \"Añadir Primitivo\"->\"Torre de purga de Timelapse\"." msgid "A copy of the current system preset will be created, which will be detached from the system preset." msgstr "Se creará una copia de el perfil de sistema actual, que quedará separado del perfil de sistema." @@ -9674,6 +10131,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "¿Está seguro de %1% el perfil seleccionado?" +msgid "Select printers" +msgstr "Seleccionar impresoras" + +msgid "Select profiles" +msgstr "Seleccionar perfiles" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9918,6 +10381,12 @@ msgstr "Transferir valores de izquierda a derecha" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Si se activa, este cuadro de diálogo se puede utilizar para transferir los valores seleccionados de los perfiles de la izquierda a la los de la derecha." +msgid "One of the presets does not exist" +msgstr "Uno de los perfiles no existe" + +msgid "Compared presets has different printer technology" +msgstr "Los perfiles comparados tienen distinta tecnología de impresora" + msgid "Add File" msgstr "Añadir archivo" @@ -10173,12 +10642,8 @@ msgstr "Información de boquilla sincronizada con éxito." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Información de boquilla y número AMS sincronizada con éxito." -msgid "Continue to sync filaments" -msgstr "Continuar sincronizando filamentos" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Cancelar" +msgid "Do you want to continue to sync filaments?" +msgstr "¿Desea continuar sincronizando filamentos?" msgid "Successfully synchronized filament color from printer." msgstr "Color de filamento sincronizado desde la impresora con éxito." @@ -10283,6 +10748,9 @@ msgstr "Inicio de sesión" msgid "Login failed. Please try again." msgstr "El inicio de sesión ha fallado. Inténtalo de nuevo." +msgid "parse json failed" +msgstr "error al analizar el json" + msgid "[Action Required] " msgstr "[Acción requerida] " @@ -10589,6 +11057,9 @@ msgstr "Nombre de la impresora" msgid "Where to find your printer's IP and Access Code?" msgstr "¿Dónde encontrar la IP de su impresora y el Código de Acceso?" +msgid "How to trouble shooting" +msgstr "Cómo resolver problemas" + msgid "Connect" msgstr "Conectar" @@ -10653,6 +11124,9 @@ msgstr "Módulo de corte" msgid "Auto Fire Extinguishing System" msgstr "Sistema de extinción automática de incendios" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10671,6 +11145,9 @@ msgstr "Actualización fallida" msgid "Update successful" msgstr "Actualización exitosa" +msgid "Hotends on Rack" +msgstr "Hotends en el rack" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "¿Estás seguro que deseas actualizar? Esto puede llevar sobre 10 minutos. No apague mientras la impresora está actualizando." @@ -10774,6 +11251,9 @@ msgstr "Error de agrupación: " msgid " can not be placed in the " msgstr " no se puede colocar en el " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Puente Interior" @@ -10896,7 +11376,7 @@ msgid " is too close to clumping detection area, there may be collisions when pr msgstr " está demasiado cerca del área de detección de aglomeraciones, puede haber colisiones durante la impresión." msgid "Prime Tower" -msgstr "Torre de Purga" +msgstr "Torre de purga" msgid " is too close to others, and collisions may be caused.\n" msgstr " está demasiado cerca de otros, y se pueden producir colisiones.\n" @@ -11446,19 +11926,19 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" "Anulación del ángulo de puente externo.\n" -"Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente concreto.\n" -"De lo contrario, se utilizará el ángulo indicado según:\n" +"Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente específico.\n" +"De lo contrario, el ángulo indicado se utilizará según:\n" " - Las coordenadas absolutas\n" -" - Las coordenadas absolutas + rotación del modelo: si está activada la opción «Alinear la dirección de relleno al modelo»\n" -" - El ángulo automático óptimo + este valor: si está activada la opción «Ángulo de puente relativo»\n" +" - Las coordenadas absolutas + rotación del modelo: si «Alinear direcciones al modelo» está activado\n" +" - El ángulo automático óptimo + este valor: si «Ángulo de puente relativo» está activado\n" "\n" -"Utiliza 180° para un ángulo absoluto de cero." +"Use 180° para un ángulo absoluto de cero." msgid "Internal bridge infill direction" msgstr "Dirección de relleno de puentes internos" @@ -11468,19 +11948,19 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" "Anulación del ángulo de puente interno.\n" -"Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente concreto.\n" -"De lo contrario, se utilizará el ángulo indicado según:\n" +"Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente específico.\n" +"De lo contrario, el ángulo indicado se utilizará según:\n" " - Las coordenadas absolutas\n" -" - Las coordenadas absolutas + rotación del modelo: si está activada la opción «Alinear la dirección de relleno al modelo»\n" -" - El ángulo automático óptimo + este valor: si está activada la opción «Ángulo de puente relativo»\n" +" - Las coordenadas absolutas + rotación del modelo: si «Alinear direcciones al modelo» está activado\n" +" - El ángulo automático óptimo + este valor: si «Ángulo de puente relativo» está activado\n" "\n" -"Utiliza 180° para un ángulo absoluto de cero." +"Use 180° para un ángulo absoluto de cero." msgid "Relative bridge angle" msgstr "Ángulo de puente relativo" @@ -11974,9 +12454,6 @@ msgstr "" "La geometría se verá diezmada antes de detectar angulos agudos. Este parámetro indica la longitud mínima de desviación para el diezmado\n" "0 para desactivar." -msgid "Select printers" -msgstr "Seleccionar impresoras" - msgid "upward compatible machine" msgstr "máquina compatible ascendente" @@ -11986,9 +12463,6 @@ msgstr "Condición" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Una expresión booleana que utiliza los valores de configuración de un perfil de impresora activo. Si esta expresión es verdadera, el perfil será considerado compatible con el perfil de impresora activo." -msgid "Select profiles" -msgstr "Seleccionar perfiles" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Una expresión booleana que utiliza los valores de configuración de un perfil de impresión activo. Si el resultado de esta expresión es verdadero, se considera que este perfil es compatible con el perfil de impresión activo." @@ -12253,6 +12727,51 @@ msgstr "Densidad de la superficie superior" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Densidad de la capa superficial superior. Un valor de 100% crea una capa superior totalmente sólida y lisa. Reducir este valor produce una superficie superior texturada, según el patrón elegido. Un valor de 0% provocará que sólo se creen las paredes en la capa superior. Destinado a fines estéticos o funcionales, no para corregir problemas como la sobreextrusión." +msgid "Top surface expansion" +msgstr "Expansión de la superficie superior" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" +"Expande las superficies superiores esta distancia para conectar superficies superiores distintas y rellenar huecos.\n" +"Útil en casos en los que la superficie superior queda interrumpida por un elemento en relieve, como texto sobre un plano. Al expandirla se eliminan los huecos bajo estos elementos y se crea un trazado continuo con un mejor acabado para imprimir encima. La expansión se aplica a la superficie superior original, antes de cualquier otro procesamiento como el puenteo o la detección de salientes." + +msgid "Top expansion wall margin" +msgstr "Margen de perímetro de la expansión superior" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" +"Usar «Expansión de la superficie superior» puede hacer que una superficie que antes no tocaba los perímetros exteriores del modelo ahora sí lo haga.\n" +"Esto puede provocar marcas de contracción (como la línea del casco) en los perímetros exteriores.\n" +"Al añadir un pequeño margen, esta contracción no se producirá directamente sobre los perímetros, evitando así una marca visible." + +msgid "Top expansion direction" +msgstr "Dirección de la expansión superior" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" +"Dirección en la que crece la expansión de la superficie superior.\n" +" - Hacia dentro crece en los huecos y espacios que dejan los elementos que se elevan desde el centro de una superficie superior.\n" +" - Hacia fuera crece en el borde exterior de la superficie, conectando superficies separadas por elementos que pueden dividir una superficie, como un patrón de enrejado.\n" +" - Hacia dentro y hacia fuera hace ambas cosas." + +msgid "Inward and Outward" +msgstr "Hacia dentro y hacia fuera" + +msgid "Inward" +msgstr "Hacia dentro" + +msgid "Outward" +msgstr "Hacia fuera" + msgid "Bottom surface pattern" msgstr "Patrón de relleno de cubierta inferior" @@ -12586,12 +13105,18 @@ msgstr "Auto para Descarga" msgid "Auto For Match" msgstr "Auto para Coincidencia" +msgid "Nozzle Manual" +msgstr "Manual de la boquilla" + msgid "Flush temperature" msgstr "Temperatura de descarga" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatura al limpiar el filamento. 0 indica el límite superior del rango de temperatura recomendado para la boquilla." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Velocidad volumétrica de descarga" @@ -12750,7 +13275,7 @@ msgid "After a tool change, the exact position of the newly loaded filament insi msgstr "Tras un cambio de cabezal, es posible que no se conozca la posición exacta del filamento recién cargado dentro de la boquilla y que la presión del filamento aún no sea estable. Antes de purgar el cabezal de impresión en un relleno o en un objeto de sacrificio, OrcaSlicer siempre cebará esta cantidad de material en la torre de purga para producir sucesivas extrusiones de relleno u objetos de sacrificio de forma fiable." msgid "Wipe tower cooling" -msgstr "Refrigeración de Torre de Purga" +msgstr "Refrigeración de torre de purga" msgid "Temperature drop before entering filament tower" msgstr "Descenso de temperatura antes de entrar en la torre de filamentos" @@ -12854,6 +13379,12 @@ msgstr "Filamento imprimible" msgid "The filament is printable in extruder." msgstr "El filamento es imprimible en el extrusor." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Temperatura de ablandado" @@ -12917,15 +13448,15 @@ msgstr "Densidad de relleno de baja densidad" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Densidad del relleno de baja densidad interno, el 100% convierte el relleno de baja densidad en relleno sólido y se utilizará el patrón de relleno sólido interno." -msgid "Align infill direction to model" -msgstr "Alinear la dirección de relleno al modelo" +msgid "Align directions to model" +msgstr "Alinear direcciones al modelo" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"Alinea las direcciones de relleno, puente, alisado y relleno superficial para que sigan la orientación del modelo sobre la placa de impresión.\n" -"Cuando está activada, las direcciones giran junto con el modelo para mantener sus características de resistencia óptimas." +"Alinea las direcciones de relleno, puente, alisado y superficie superior/inferior para que sigan la orientación del modelo sobre la cama de impresión.\n" +"Cuando está activado, estas direcciones giran junto con el modelo, de modo que los elementos impresos mantienen su orientación prevista respecto a la pieza, conservando la resistencia y las características de superficie óptimas independientemente de cómo se coloque el modelo." msgid "Insert solid layers" msgstr "Insertar capas sólidas" @@ -13450,6 +13981,15 @@ msgstr "Mejor auto posicionamiento de los objetos en el rango [0,1] con respecto msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Activar esta opción si la máquina dispone de ventilador auxiliar de refrigeración de piezas. Comando G-Code: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13521,6 +14061,12 @@ msgstr "" "Active esta opción si la impresora admite filtración de aire\n" "Comando G-Code: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Usar un filtro de enfriamiento" + +msgid "Enable this if printer support cooling filter" +msgstr "Activar esta opción si la impresora soporta el filtro de enfriamiento" + msgid "G-code flavor" msgstr "Tipo de G-Code" @@ -14042,6 +14588,30 @@ msgstr "Velocidad mínima de desplazamiento" msgid "Minimum travel speed (M205 T)" msgstr "Velocidad mínima de desplazamiento (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Fuerza máxima del eje Y" + +msgid "The allowed maximum output force of Y axis" +msgstr "La fuerza máxima permitida del eje Y" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Masa de la cama del eje Y" + +msgid "The machine bed mass load of Y axis" +msgstr "La carga de la masa de la cama de la máquina del eje Y" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "Masa máxima de impresión permitida" + +msgid "The allowed max printed mass on a plate" +msgstr "Masa máxima impresa permitida en una placa" + msgid "Maximum acceleration for extruding" msgstr "Aceleración máxima para la extrusión" @@ -14594,6 +15164,9 @@ msgstr "Extrusor Directo" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Híbrido" + msgid "Enable filament dynamic map" msgstr "Habilitar mapa dinámico de filamentos" @@ -14627,6 +15200,12 @@ msgstr "Velocidad de De-retracción" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Velocidad para recargar el filamento en la boquilla. Cero significa la misma velocidad que la retracción." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Usar retracción de firmware (beta)" @@ -14657,6 +15236,9 @@ msgstr "Alineado" msgid "Aligned back" msgstr "Alineado atrás" +msgid "Back" +msgstr "Atrás" + msgid "Random" msgstr "Aleatorio" @@ -14927,6 +15509,12 @@ msgstr "Si se selecciona el modo suave o tradicional, se generará un vídeo tim msgid "Traditional" msgstr "Tradicional" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Variación de temperatura" @@ -15012,6 +15600,21 @@ msgstr "Purgar todos los extrusores" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Sí se activa, todos los extrusores serán purgados en el frontal de la cama de impresión al inicio de la impresión." +msgid "Toolchange ordering" +msgstr "Orden de cambios de herramienta" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" +"Determina el orden de los cambios de herramienta en cada capa.\n" +"- Por defecto: Comienza con el último extrusor utilizado para minimizar los cambios de herramienta.\n" +"- Cíclico: Utiliza una secuencia de herramientas fija en cada capa. Esto sacrifica velocidad a cambio de una mejor calidad de superficie, ya que los cambios de herramienta adicionales dan más tiempo a las capas para enfriarse." + +msgid "Cyclic" +msgstr "Cíclico" + msgid "Slice gap closing radius" msgstr "Radio de cierre de laminado" @@ -15394,7 +15997,7 @@ msgstr "" "Esta funciuón es útil para imrpesoras no compatibles con los comandos M141 o M191, o si prefiere realizar un precalentamiento usando un macro si no dispone de un sistema de calentamiento activo de cámara." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15448,6 +16051,57 @@ msgstr "Espesor mínimo de la cubierta superior" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "El número de capas sólidas superiores se incrementa al laminar si el espesor calculado por las capas de la cubierta es más delgado que este valor. Esto puede evitar tener una cubierta demasiado fina cuando la altura de la capa es pequeña. 0 significa que este ajuste está desactivado y el grosor de la capa superior está absolutamente determinado por las capas de la cubierta superior." +msgid "Anisotropic surfaces" +msgstr "Superficies anisótropas" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" +"Patrones anisótropos en las superficies superior e inferior.\n" +"Se aplicará el modo de impresión codireccional. Para ciertos patrones, el relleno omnidireccional proporciona dispersión del color al usar plásticos multicolor o de tipo seda.\n" +"Esta opción desactiva el relleno de huecos.\n" +"Esta opción puede aumentar el tiempo de impresión." + +msgid "Separated infills" +msgstr "Rellenos separados" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" +"Centra el relleno interno de cada pieza sobre sí misma, como si se laminara por separado, en lugar de sobre todo el conjunto. Las piezas que se tocan o se superponen se tratan como un solo cuerpo y comparten un centro; las piezas separadas (u objetos 3D distintos) tienen cada una el suyo.\n" +"Útil cuando un conjunto agrupa varios objetos que deben mantener cada uno un relleno coherente y autocentrado.\n" +"Afecta a los patrones de línea y cuadrícula y a los rellenos con plantilla de rotación.\n" +"Los patrones anclados a coordenadas globales (Giroide, Panal, TPMS, ...) no se ven afectados." + +msgid "Center surface pattern on" +msgstr "Centrar el patrón de superficie en" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" +"Elige dónde se sitúa el punto de centrado de los patrones centrados de superficie superior/inferior (Espiral de Arquímedes, Espiral Octagonal).\n" +" - Cada superficie: centra el patrón en cada región de superficie individual, de modo que cada isla es simétrica por sí misma.\n" +" - Cada modelo: centra el patrón en cada cuerpo conectado. Las piezas que se tocan o se superponen comparten un centro; las piezas separadas del resto tienen cada una el suyo.\n" +" - Cada conjunto: usa un único centro compartido para todo el objeto o conjunto." + +msgid "Each Surface" +msgstr "Cada superficie" + +msgid "Each Model" +msgstr "Cada modelo" + +msgid "Each Assembly" +msgstr "Cada conjunto" + msgid "This is the speed at which traveling is done." msgstr "Velocidad de desplazamiento más rápida y sin extrusión." @@ -15491,12 +16145,30 @@ msgstr "Multiplicador de flujo" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "El volumen de flujo real es igual al producto del multiplicador de flujo y los volúmenes de flujo de la tabla." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Volumen de purga" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "El volumen de material para purgar la extrusora en la torre." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "Ancho de la torre de purga." @@ -15784,6 +16456,57 @@ msgstr "Ancho mínimo del perímetro" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Anchura del perímetro que sustituirá a los elementos finos (según el tamaño mínimo del elemento) del modelo. Si la anchura mínima del perímetro es menor que el grosor de la característica, el perímetro será tan grueso como la propia característica. Se expresa en porcentaje en base al diámetro de la boquilla." +msgid "Hotend change time" +msgstr "Tiempo del cambio de Hotend" + +msgid "Time to change hotend." +msgstr "Es hora de cambiar el Hotend." + +msgid "Hotend change" +msgstr "Cambio del Hotend" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Al cambiar el hotend, se recomienda extruir una determinada longitud de filamento de la boquilla original. Esto ayuda a minimizar el rezumado de la boquilla." + +msgid "Extruder change" +msgstr "Cambio de extrusor" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Para evitar la exudación, la boquilla realizará un movimiento de desplazamiento inverso durante un cierto tiempo una vez finalizado el apisonado. El ajuste define el tiempo de desplazamiento." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Para evitar la supuración, la temperatura de la boquilla se enfriará durante la embestida. Por lo tanto, el tiempo de embestida debe ser mayor que el tiempo de enfriamiento. 0 significa que está desactivado." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "La velocidad volumétrica máxima para embestir antes del cambio de extrusor, donde -1 significa usar la velocidad volumétrica máxima." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Para evitar el rezumado, la temperatura de la boquilla se enfriará durante el empuje. Nota: solo se activan un comando de enfriamiento y el ventilador, no se garantiza alcanzar la temperatura objetivo. 0 significa deshabilitado." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "La velocidad volumétrica máxima para embestir antes de un cambio de Hotend, donde -1 significa usar la velocidad volumétrica máxima." + +msgid "length when change hotend" +msgstr "longitud al cambiar el hotend" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Cuando se modifique este valor de retracción, se utilizará como la cantidad de filamento retraído dentro del hotend antes de cambiar los hotends." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "El volumen de material necesario para cebar el extrusor al cambiar el Hotend en la torre." + +msgid "Preheat temperature delta" +msgstr "Diferencial de temperatura de precalentamiento" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Diferencial de temperatura aplicado durante el precalentamiento antes del cambio de herramienta." + msgid "Detect narrow internal solid infills" msgstr "Detectar relleno sólido interno estrecho" @@ -16524,12 +17247,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Calibración no soportada" -msgid "Error desc" -msgstr "Error en la descripción" - -msgid "Extra info" -msgstr "Información extra" - msgid "Flow Dynamics" msgstr "Dinámicas de Flujo" @@ -16733,6 +17450,12 @@ msgstr "Por favor, introduzca el nombre que quiera asignar a la impresora." msgid "The name cannot exceed 40 characters." msgstr "El nombre no puede exceder de 40 caracteres." +msgid "Nozzle ID" +msgstr "ID de la boquilla" + +msgid "Standard Flow" +msgstr "Flujo estándar" + msgid "Please find the best line on your plate" msgstr "Por favor encuentre la mejor línea en su cama" @@ -16822,9 +17545,6 @@ msgstr "La información de AMS y de la boquilla está sincronizada" msgid "Nozzle Flow" msgstr "Flujo de boquilla" -msgid "Nozzle Info" -msgstr "Información de boquilla" - msgid "Filament position" msgstr "Posición de filamento" @@ -16898,6 +17618,10 @@ msgstr "Éxito recuperando el historial de resultados" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Refrescar el histórico de resultados de Calibración de Dinámicas de Flujo" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Nota: El número del hotend en el %s está vinculado al soporte. Cuando el hotend se mueve a un nuevo soporte, su número se actualizará automáticamente." + msgid "Action" msgstr "Acción" @@ -18642,6 +19366,12 @@ msgstr "Error de impresión" msgid "Removed" msgstr "Eliminado" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "No me recuerdes de nuevo" @@ -18675,12 +19405,25 @@ msgstr "Vídeo tutorial" msgid "(Sync with printer)" msgstr "(Sincronizar con impresora)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Laminar según este método de agrupación:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Tip: Puedes arrastrar los filamentos para reasignarlos a diferentes boquillas." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "El método de agrupación de filamentos para la placa actual se determina por la opción desplegable en el botón de placa de laminado." @@ -18912,9 +19655,6 @@ msgstr "Esta acción no se puede deshacer. ¿Continuar?" msgid "Skipping objects." msgstr "Omitiendo objetos." -msgid "Select Filament" -msgstr "Seleccionar Filamento" - msgid "Null Color" msgstr "Color Nulo" @@ -19429,6 +20169,77 @@ msgstr "" "Evita la deformación\n" "¿Sabías que al imprimir materiales propensos a la deformación como el ABS, aumentar adecuadamente la temperatura de la cama térmica puede reducir la probabilidad de deformaciones?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Los objetos renderizados proyectan sombras sobre la cama en la vista realista." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "Aplica normales suavizadas a la vista realista.\n" +#~ "\n" +#~ "Requiere recargar la escena manualmente para que surta efecto (clic derecho en la vista 3D → \"Recargar todo\")." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Continuar sincronizando filamentos" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Anulación del ángulo de puente externo.\n" +#~ "Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente concreto.\n" +#~ "De lo contrario, se utilizará el ángulo indicado según:\n" +#~ " - Las coordenadas absolutas\n" +#~ " - Las coordenadas absolutas + rotación del modelo: si está activada la opción «Alinear la dirección de relleno al modelo»\n" +#~ " - El ángulo automático óptimo + este valor: si está activada la opción «Ángulo de puente relativo»\n" +#~ "\n" +#~ "Utiliza 180° para un ángulo absoluto de cero." + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Anulación del ángulo de puente interno.\n" +#~ "Si se deja en cero, el ángulo de puente se calculará automáticamente para cada puente concreto.\n" +#~ "De lo contrario, se utilizará el ángulo indicado según:\n" +#~ " - Las coordenadas absolutas\n" +#~ " - Las coordenadas absolutas + rotación del modelo: si está activada la opción «Alinear la dirección de relleno al modelo»\n" +#~ " - El ángulo automático óptimo + este valor: si está activada la opción «Ángulo de puente relativo»\n" +#~ "\n" +#~ "Utiliza 180° para un ángulo absoluto de cero." + +#~ msgid "Align infill direction to model" +#~ msgstr "Alinear la dirección de relleno al modelo" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "Alinea las direcciones de relleno, puente, alisado y relleno superficial para que sigan la orientación del modelo sobre la placa de impresión.\n" +#~ "Cuando está activada, las direcciones giran junto con el modelo para mantener sus características de resistencia óptimas." + +#~ msgid "Print" +#~ msgstr "Imprimir" + #~ msgid "in" #~ msgstr "pulg" @@ -20281,9 +21092,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "No puede iniciarse sin una tarjeta SD." -#~ msgid "Update" -#~ msgstr "Actualizar" - #~ msgid "Sensitivity of pausing is" #~ msgstr "La sensibilidad de pausa es" @@ -21012,10 +21820,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Deseleccionar" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Escala" - #~ msgid "Lift Z Enforcement" #~ msgstr "Forzar elevación Z" diff --git a/localization/i18n/fr/OrcaSlicer_fr.po b/localization/i18n/fr/OrcaSlicer_fr.po index c789268248..9b88ef7532 100644 --- a/localization/i18n/fr/OrcaSlicer_fr.po +++ b/localization/i18n/fr/OrcaSlicer_fr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: Guislain Cyril, Thomas Lété\n" @@ -38,6 +38,24 @@ msgstr "Le TPU n’est pas pris en charge par l’AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "L'AMS ne prend pas en charge le 'Bambu Lab PET-CF'." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Veuillez effectuer un tirage à froid avant d'imprimer du TPU pour éviter le bouchage. Vous pouvez utiliser la maintenance par tirage à froid sur l'imprimante." @@ -50,6 +68,9 @@ msgstr "Le PVA humide est souple et peut se coincer dans l'extrudeur. Séchez-le msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "La surface rugueuse du PLA Glow peut accélérer l'usure du système AMS, en particulier sur les composants internes de l'AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Les filaments CF/GF sont durs et cassants, ils peuvent se casser ou se coincer dans l’AMS, veuillez les utiliser avec prudence." @@ -59,10 +80,90 @@ msgstr "Le PPS-CF est cassant et pourrait se briser dans le tube PTFE courbé au msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "Le PPA-CF est cassant et pourrait se briser dans le tube PTFE courbé au-dessus de la tête d'outil." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s n'est pas pris en charge par l'extrudeur %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Haut débit" + +msgid "Standard" +msgstr "Standard" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Inconnu" + +msgid "Hardened Steel" +msgstr "Acier trempé" + +msgid "Stainless Steel" +msgstr "Acier inoxydable" + +msgid "Tungsten Carbide" +msgstr "Carbure de tungstène" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "La tête d'outil et le rack hotend peuvent se déplacer. Veuillez garder vos mains hors de la chambre." + +msgid "Warning" +msgstr "Avertissement" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Les informations du Hotend peuvent être inexactes. Souhaitez-vous relire le Hotend ? (Les informations du Hotend peuvent changer lors de la coupure d'alimentation)." + +msgid "I confirm all" +msgstr "Tout confirmer" + +msgid "Re-read all" +msgstr "Relire tout" + +msgid "Reading the hotends, please wait." +msgstr "Lecture des hotends, veuillez patienter." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Pendant la mise à niveau du hotend, la tête d’outil va se déplacer. Ne mettez pas vos mains dans la chambre." + +msgid "Update" +msgstr "Mise à jour" + msgid "Current AMS humidity" msgstr "Humidité actuelle de l’AMS" @@ -93,6 +194,85 @@ msgstr "Version :" msgid "Latest version" msgstr "Dernière version" +msgid "Row A" +msgstr "Rang A" + +msgid "Row B" +msgstr "Rang B" + +msgid "Toolhead" +msgstr "Tête d'Outil" + +msgid "Empty" +msgstr "Vide" + +msgid "Error" +msgstr "Erreur" + +msgid "Induction Hotend Rack" +msgstr "Rack Hotend Induction" + +msgid "Hotends Info" +msgstr "Infos Hotends" + +msgid "Read All" +msgstr "Tout Lire" + +msgid "Reading " +msgstr "Lecture " + +msgid "Please wait" +msgstr "Veuillez patienter" + +msgid "Running..." +msgstr "En cours..." + +msgid "Raised" +msgstr "Soulevée" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Cet hotend est dans un état anormal et est actuellement indisponible. Veuillez aller dans \"Appareil -> Mise à jour\" pour mettre à jour le firmware." + +msgid "Abnormal Hotend" +msgstr "Hotend Anormal" + +msgid "Refresh" +msgstr "Actualiser" + +msgid "Refreshing" +msgstr "Actualisation" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "État du hotend anormal, il est indisponible pour le moment. Veuillez mettre à jour le firmware et réessayer." + +msgid "Cancel" +msgstr "Annuler" + +msgid "Jump to the upgrade page" +msgstr "Aller à la page de Mise à jour" + +msgid "SN" +msgstr "Numéro de série" + +msgid "Version" +msgstr "Version" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Temps d'Usage: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Les buses dynamiques sont attribuées sur la plaque actuelle. La sélection du hotend n'est pas prise en charge." + +msgid "Hotend Rack" +msgstr "Rack Hotends" + +msgid "ToolHead" +msgstr "Tête d'Outil" + +msgid "Nozzle information needs to be read" +msgstr "Les informations de la buse doivent être lues" + msgid "Support Painting" msgstr "Peindre les supports" @@ -162,6 +342,12 @@ msgstr "Remplir" msgid "Gap Fill" msgstr "Remplissage des espaces" +msgid "Vertical" +msgstr "Vertical" + +msgid "Horizontal" +msgstr "Horizontal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Permet de peindre uniquement sur les facettes sélectionnées par : \"%1%\"" @@ -254,12 +440,6 @@ msgstr "Triangle" msgid "Height Range" msgstr "Plage de hauteur" -msgid "Vertical" -msgstr "Vertical" - -msgid "Horizontal" -msgstr "Horizontal" - msgid "Remove painted color" msgstr "Supprimer la couleur peinte" @@ -324,6 +504,7 @@ msgstr "Gizmo-Pivoter" msgid "Optimize orientation" msgstr "Optimiser l'orientation" +msgctxt "Verb" msgid "Scale" msgstr "Redimensionner" @@ -367,6 +548,9 @@ msgstr "Rapports d'échelle" msgid "Object operations" msgstr "Opérations sur les objets" +msgid "Scale" +msgstr "Redimensionner" + msgid "Volume operations" msgstr "Opérations sur les volumes" @@ -389,7 +573,7 @@ msgid "Reset rotation" msgstr "Réinitialiser la rotation" msgid "World" -msgstr "" +msgstr "Monde" msgid "Object" msgstr "Objet" @@ -398,13 +582,13 @@ msgid "Part" msgstr "Pièce" msgid "Relative" -msgstr "" +msgstr "Relatif" msgid "Coordinate system used for transform actions." -msgstr "" +msgstr "Système de coordonnées utilisé pour les actions de transformation." msgid "Absolute" -msgstr "" +msgstr "Absolu" msgid "Reset current rotation to the value when open the rotation tool." msgstr "Réinitialiser la rotation actuelle à la valeur lors de l'ouverture de l'outil de rotation." @@ -412,6 +596,10 @@ msgstr "Réinitialiser la rotation actuelle à la valeur lors de l'ouverture de msgid "Reset current rotation to real zeros." msgstr "Réinitialiser la rotation actuelle à zéro." +msgctxt "Noun" +msgid "Scale" +msgstr "Redimensionner" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Taille" @@ -594,9 +782,6 @@ msgstr "Proportion de l’espace par rapport au rayon" msgid "Confirm connectors" msgstr "Confirmer les connecteurs" -msgid "Cancel" -msgstr "Annuler" - msgid "Flip cut plane" msgstr "Retourner le plan de coupe" @@ -637,12 +822,12 @@ msgstr "Couper en plusieurs pièces" msgid "Reset cutting plane and remove connectors" msgstr "Réinitialiser le plan de coupe et retirer les connecteurs" +msgid "Reset Cut" +msgstr "Réinitialiser la découpe" + msgid "Perform cut" msgstr "Effectuer la coupe" -msgid "Warning" -msgstr "Avertissement" - msgid "Invalid connectors detected" msgstr "Connecteurs invalides détectés" @@ -673,6 +858,16 @@ msgstr "Le plan de coupe avec rainure est invalide" msgid "Connector" msgstr "Connecteur" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" +"Les objets (%1%) ont des connecteurs dupliqués. Certains connecteurs risquent d’être absents du résultat du découpage.\n" +"Veuillez signaler à l’équipe PrusaSlicer dans quel scénario ce problème est survenu.\n" +"Merci." + msgid "Cut by Plane" msgstr "Coupe par plan" @@ -719,9 +914,6 @@ msgstr "Simplifier" msgid "Simplification is currently only allowed when a single part is selected" msgstr "La simplification n'est actuellement autorisée que lorsqu'une seule pièce est sélectionnée" -msgid "Error" -msgstr "Erreur" - msgid "Extra high" msgstr "Très haut" @@ -1854,31 +2046,39 @@ msgid "The version of Orca Slicer is too low and needs to be updated to the late msgstr "La version de OrcaSlicer est trop ancienne et doit être mise à jour vers la dernière version afin qu’il puisse être utilisé normalement." msgid "Cloud sync conflict:" -msgstr "" +msgstr "Conflit de synchronisation cloud :" #, c-format, boost-format msgid "Cloud sync conflict for preset \"%s\":" -msgstr "" +msgstr "Conflit de synchronisation cloud pour le préréglage « %s » :" msgid "" "This preset has a newer version in OrcaCloud.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"Ce préréglage possède une version plus récente dans OrcaCloud.\n" +"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local." msgid "" "A preset with this name already exists in OrcaCloud.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"Un préréglage de ce nom existe déjà dans OrcaCloud.\n" +"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local." msgid "" "A preset with the same name was previously deleted from the cloud.\n" "Delete will delete your local preset. Force push overwrites it with your local preset." msgstr "" +"Un préréglage du même nom a été précédemment supprimé du cloud.\n" +"Supprimer effacera votre préréglage local. Forcer l’envoi l’écrase avec votre préréglage local." msgid "" "There was an unexpected or unidentified preset conflict.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"Un conflit de préréglage inattendu ou non identifié s’est produit.\n" +"Récupérer télécharge la copie du cloud. Forcer l’envoi l’écrase avec votre préréglage local." msgid "" "Force push will overwrite the cloud copy with your local preset changes.\n" @@ -1892,6 +2092,8 @@ msgid "" "Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n" "Do you want to continue?" msgstr "" +"Forcer l’envoi écrasera la copie cloud du préréglage « %s » avec vos modifications locales.\n" +"Voulez-vous continuer ?" msgid "Resolve cloud sync conflict" msgstr "Résoudre le conflit de synchronisation cloud" @@ -1974,7 +2176,7 @@ msgstr "Synchroniser les réglages prédéfinis de l’utilisateur" #, c-format, boost-format msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only." -msgstr "" +msgstr "Le préréglage « %s » est trop volumineux pour être synchronisé vers le cloud (dépasse 1 Mo). Veuillez réduire sa taille en supprimant des configurations personnalisées, ou l’utiliser uniquement en local." #, c-format, boost-format msgid "%s updated from %s to %s" @@ -1995,6 +2197,9 @@ msgstr "L’accès au paquet %s n’est pas autorisé." msgid "Loading user preset" msgstr "Chargement du préréglage utilisateur" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "Une mise à jour est disponible. Ouvrez la boîte de dialogue du paquet de préréglages pour l’installer." + #, c-format, boost-format msgid "%s has been removed." msgstr "%s a été supprimé." @@ -2008,6 +2213,20 @@ msgstr "Sélectionner la langue" msgid "Language" msgstr "Langue" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "Le passage d’Orca Slicer à la langue %s a échoué." + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" +"\n" +"Vous devrez peut-être reconfigurer les paramètres régionaux manquants, probablement en exécutant les commandes « locale-gen » et « dpkg-reconfigure locales ».\n" + +msgid "Orca Slicer - Switching language failed" +msgstr "Orca Slicer — Échec du changement de langue" + msgid "*" msgstr "*" @@ -2184,7 +2403,7 @@ msgid "OrcaSliced Combo" msgstr "OrcaSliced Combo" msgid "Orca Badge" -msgstr "" +msgstr "Orca Badge" msgid "Orca Tolerance Test" msgstr "Test de tolérance Orca" @@ -2604,6 +2823,46 @@ msgstr "Cliquez sur l'icône pour modifier la couleur de peinture de l'objet" msgid "Click the icon to shift this object to the bed" msgstr "Cliquez sur l'icône pour déplacer cet objet vers le plateau" +# Orca: hardcoded GUI strings extracted (i18n FR pass) +msgid "Rename Object" +msgstr "Renommer l’objet" + +msgid "Rename Part" +msgstr "Renommer la pièce" + +msgid "Paste settings" +msgstr "Coller les réglages" + +msgid "Shift objects to bed" +msgstr "Déplacer les objets sur le plateau" + +msgid "Object order changed" +msgstr "Ordre des objets modifié" + +msgid "Layer setting added" +msgstr "Réglage de couche ajouté" + +msgid "Part setting added" +msgstr "Réglage de pièce ajouté" + +msgid "Object setting added" +msgstr "Réglage d’objet ajouté" + +msgid "Height range settings added" +msgstr "Réglages de plage de hauteur ajoutés" + +msgid "Part settings added" +msgstr "Réglages de pièce ajoutés" + +msgid "Object settings added" +msgstr "Réglages d’objet ajoutés" + +msgid "Load Part" +msgstr "Charger une pièce" + +msgid "Load Modifier" +msgstr "Charger un modificateur" + msgid "Loading file" msgstr "Chargement du fichier" @@ -2613,6 +2872,9 @@ msgstr "Erreur !" msgid "Failed to get the model data in the current file." msgstr "Impossible d’obtenir les données du modèle dans le fichier actuel." +msgid "Add primitive" +msgstr "Ajouter une primitive" + msgid "Generic" msgstr "Générique" @@ -2625,6 +2887,12 @@ msgstr "Passez en mode de réglage \"par objet\" pour modifier les paramètres d msgid "Remove paint-on fuzzy skin" msgstr "Retirer la surface irrégulière peinte" +msgid "Delete Settings" +msgstr "Supprimer les réglages" + +msgid "Remove height range" +msgstr "Supprimer la plage de hauteur" + msgid "Delete connector from object which is a part of cut" msgstr "Supprimer le connecteur de l'objet qui fait partie de la découpe" @@ -2654,12 +2922,24 @@ msgstr "Supprimer tous les connecteurs" msgid "Deleting the last solid part is not allowed." msgstr "La suppression de la dernière partie pleine n'est pas autorisée." +msgid "Delete part" +msgstr "Supprimer la pièce" + msgid "The target object contains only one part and can not be split." msgstr "L'objet cible ne contient qu'une seule pièce et ne peut pas être divisé." +msgid "Split to parts" +msgstr "Scinder en pièces" + msgid "Assembly" msgstr "Assemblé" +msgid "Merge parts to an object" +msgstr "Fusionner les pièces en un objet" + +msgid "Add layers" +msgstr "Ajouter des couches" + msgid "Cut Connectors information" msgstr "Informations sur les connecteurs de coupe" @@ -2690,6 +2970,9 @@ msgstr "Plages de hauteur" msgid "Settings for height range" msgstr "Réglages de la plage de hauteur" +msgid "Delete selected" +msgstr "Supprimer la sélection" + msgid "Layer" msgstr "Couche" @@ -2711,6 +2994,9 @@ msgstr "Type :" msgid "Choose part type" msgstr "Choisissez le type de pièce" +msgid "Instances to Separated Objects" +msgstr "Séparer les instances en objets" + msgid "Enter new name" msgstr "Entrer un nouveau nom" @@ -2738,6 +3024,9 @@ msgstr "\"%s\" dépassera 1 million de faces après cette subdivision, ce qui pe msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "Le maillage de la pièce \"%s\" contient des erreurs. Veuillez le réparer d'abord." +msgid "Change Filaments" +msgstr "Changer les filaments" + msgid "Additional process preset" msgstr "Préréglage de traitement supplémentaire" @@ -2747,9 +3036,6 @@ msgstr "Supprimer le paramètre" msgid "to" msgstr "à" -msgid "Remove height range" -msgstr "Supprimer la plage de hauteur" - msgid "Add height range" msgstr "Ajouter une plage de hauteur" @@ -2952,6 +3238,9 @@ msgstr "Choisissez un emplacement AMS puis appuyez sur le bouton « Charger » o msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Le type de filament est inconnu, ce qui est nécessaire pour effectuer cette action. Veuillez définir les informations du filament cible." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Changer la vitesse du ventilateur pendant l'impression peut affecter la qualité d'impression, veuillez choisir avec précaution." @@ -3073,6 +3362,24 @@ msgstr "Confirmation de l'extrusion" msgid "Check filament location" msgstr "Vérification de la position du filament" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "La température maximale ne peut pas dépasser " @@ -3124,6 +3431,62 @@ msgstr "Mode développeur" msgid "Launch troubleshoot center" msgstr "Ouvrir le centre de dépannage" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Veuillez définir le nombre de buses" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Erreur : impossible de définir le nombre de buses à zéro." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Erreur : Le nombre de buses ne peut pas dépasser %d." + +msgid "Confirm" +msgstr "Confirmer" + +msgid "Extruder" +msgstr "Extrudeur" + +msgid "Nozzle Selection" +msgstr "Sélection de Buse" + +msgid "Available Nozzles" +msgstr "Buses Disponibles" + +msgid "Nozzle Info" +msgstr "Info buse" + +msgid "Sync Nozzle status" +msgstr "Synchroniser Buse" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Attention : Le mélange de diamètres de buses dans une même impression n'est pas pris en charge. Si la taille sélectionnée se trouve uniquement sur un extrudeur, l'impression mono-extrudeur sera appliquée." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Actualisation %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Buse inconnue détectée. Actualisez pour mettre à jour les informations (les buses non actualisées seront exclues lors du découpage). Vérifiez le diamètre de la buse et le débit par rapport aux valeurs affichées." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Buse inconnue détectée. Actualisez pour mettre à jour (les buses non actualisées seront ignorées lors de la découpe)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Veuillez confirmer si le diamètre de la buse requis et le débit correspondent aux valeurs actuellement affichées." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Votre imprimante est équipée de  différentes buses . Veuillez sélectionner une buse pour cette impression." + +msgid "Ignore" +msgstr "Ignorer" + +msgid "Done." +msgstr "Terminé." + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3447,15 +3810,9 @@ msgstr "OrcaSlicer est né dans ce même esprit, en s’inspirant de PrusaSlicer msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Aujourd’hui, OrcaSlicer est le slicer open-source le plus utilisé et le plus activement développé de la communauté de l’impression 3D. Beaucoup de ses innovations ont été adoptées par d’autres slicers, ce qui en fait une force motrice pour toute l’industrie." -msgid "Version" -msgstr "Version" - msgid "AMS Materials Setting" msgstr "Réglage des matériaux AMS" -msgid "Confirm" -msgstr "Confirmer" - msgid "Close" msgstr "Fermer" @@ -3476,12 +3833,12 @@ msgstr "min" msgid "The input value should be greater than %1% and less than %2%" msgstr "La valeur saisie doit être supérieure à %1% et inférieure à %2%" -msgid "SN" -msgstr "Numéro de série" - msgid "Factors of Flow Dynamics Calibration" msgstr "Facteurs de calibration dynamique du débit" +msgid "Wiki Guide" +msgstr "Guide wiki" + msgid "PA Profile" msgstr "Profil PA" @@ -3569,6 +3926,7 @@ msgstr "Calibrage terminé. Veuillez trouver la ligne d'extrusion la plus unifor msgid "Save" msgstr "Enregistrer" +msgctxt "Navigation" msgid "Back" msgstr "Arrière" @@ -3652,6 +4010,19 @@ msgstr "Buse droite" msgid "Nozzle" msgstr "Buse" +msgid "Select Filament && Hotends" +msgstr "Sélectionnez Filament && Hotends" + +msgid "Select Filament" +msgstr "Sélectionner le filament" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Imprimer avec la buse actuelle peut générer %0.2f g de déchets supplémentaires." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Note : le type de filament (%s) ne correspond pas au type de filament (%s) dans le fichier de tranchage. Si vous souhaitez utiliser cet emplacement, vous pouvez installer %s à la place de %s et modifier les informations de l'emplacement sur la page 'Appareil'." @@ -4336,9 +4707,6 @@ msgstr "Mesure de la surface" msgid "Calibrating the detection position of nozzle clumping" msgstr "Calibration de la position de détection de l'agglomération de la buse" -msgid "Unknown" -msgstr "Inconnu" - msgid "Update successful." msgstr "Mise à jour réussie." @@ -4847,9 +5215,6 @@ msgstr "Définir comme optimal" msgid "Regroup filament" msgstr "Regrouper les filaments" -msgid "Wiki Guide" -msgstr "Guide wiki" - msgid "up to" msgstr "jusqu’à" @@ -4883,8 +5248,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Vitesse du ventilateur (%)" -msgid "Temperature (°C)" -msgstr "Température (°C)" +msgid "Temperature (℃)" +msgstr "Température (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Débit volumétrique (mm³/s)" @@ -4901,9 +5266,6 @@ msgstr "Changements de filaments" msgid "Options" msgstr "Options" -msgid "Extruder" -msgstr "Extrudeur" - msgid "Cost" msgstr "Coût" @@ -4916,6 +5278,7 @@ msgstr "Changements d’outil" msgid "Color change" msgstr "Changement de couleur" +msgctxt "Noun" msgid "Print" msgstr "Imprimer" @@ -5075,11 +5438,15 @@ msgstr "Éviter la région de calibration de l'extrusion" msgid "Align to Y axis" msgstr "Aligner sur l’axe Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Arrière" + +msgctxt "Camera View" msgid "Left" msgstr "Gauche" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Droite" @@ -5104,9 +5471,6 @@ msgstr "Organiser les objets sur les plaques sélectionnées" msgid "Split to objects" msgstr "Diviser en objets individuels" -msgid "Split to parts" -msgstr "Scinder en pièces" - msgid "Assembly View" msgstr "Vue de l'assemblage" @@ -5159,7 +5523,7 @@ msgid "Outline" msgstr "Contour" msgid "Wireframe" -msgstr "" +msgstr "Fil de fer" msgid "Realistic View" msgstr "Vue réaliste" @@ -5402,6 +5766,10 @@ msgstr "Imprimer le plateau" msgid "Export G-code file" msgstr "Exporter le fichier G-code" +msgctxt "Verb" +msgid "Print" +msgstr "Imprimer" + msgid "Export plate sliced file" msgstr "Exporter le fichier découpé du plateau" @@ -5575,15 +5943,6 @@ msgstr "Exporter la configuration actuelle vers des fichiers" msgid "Export" msgstr "Exporter" -msgid "Sync Presets" -msgstr "Synchroniser les préréglages" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Récupérer et appliquer les derniers préréglages depuis OrcaCloud" - -msgid "You must be logged in to sync presets from cloud." -msgstr "Vous devez être connecté pour synchroniser les préréglages depuis le cloud." - msgid "Quit" msgstr "Quitter" @@ -5698,6 +6057,15 @@ msgstr "Affichage" msgid "Preset Bundle" msgstr "Paquet de préréglages" +msgid "Sync Presets" +msgstr "Synchroniser les préréglages" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Récupérer et appliquer les derniers préréglages depuis OrcaCloud" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Vous devez être connecté pour synchroniser les préréglages depuis le cloud." + msgid "Syncing presets from cloud…" msgstr "Synchronisation des préréglages depuis le cloud…" @@ -5815,6 +6183,9 @@ msgstr "Exporter le Résultat" msgid "Select profile to load:" msgstr "Sélectionnez le profil à charger :" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "Fichiers de configuration (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5981,9 +6352,6 @@ msgstr "Téléchargez les fichiers sélectionnés depuis l'imprimante." msgid "Batch manage files." msgstr "Gérer les fichiers par lots." -msgid "Refresh" -msgstr "Actualiser" - msgid "Reload file list from printer." msgstr "Recharger la liste des fichiers de l’imprimante." @@ -6290,6 +6658,9 @@ msgstr "Options d'impression" msgid "Safety Options" msgstr "Options de sécurité" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Lampe" @@ -6323,6 +6694,12 @@ msgstr "Lorsque l'impression est en pause, le chargement et le déchargement de msgid "Current extruder is busy changing filament." msgstr "L'extrudeur actuel est occupé à changer de filament." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "L'emplacement actuel est déjà chargé." @@ -6371,9 +6748,6 @@ msgstr "Cela ne prend effet que pendant l'impression" msgid "Silent" msgstr "Silencieux" -msgid "Standard" -msgstr "Standard" - msgid "Sport" msgstr "Sport" @@ -6407,6 +6781,12 @@ msgstr "Ajouter une image" msgid "Delete Photo" msgstr "Supprimer l’image" +msgid "Select Images" +msgstr "Sélectionner des images" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "Fichiers image (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" + msgid "Submit" msgstr "Envoyer" @@ -6590,6 +6970,9 @@ msgstr "Comment utiliser le mode LAN uniquement" msgid "Don't show this dialog again" msgstr "Ne plus afficher cette boîte de dialogue" +msgid "Please refer to Wiki before use->" +msgstr "Veuillez consulter le Wiki avant utilisation ->" + msgid "3D Mouse disconnected." msgstr "Souris 3D déconnectée." @@ -6837,27 +7220,18 @@ msgstr "Débit" msgid "Please change the nozzle settings on the printer." msgstr "Veuillez changer les paramètres de buse sur l'imprimante." -msgid "Hardened Steel" -msgstr "Acier trempé" - -msgid "Stainless Steel" -msgstr "Acier inoxydable" - -msgid "Tungsten Carbide" -msgstr "Carbure de tungstène" - msgid "Brass" msgstr "Laiton" msgid "High flow" msgstr "Haut débit" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Aucun lien wiki disponible pour cette imprimante." -msgid "Refreshing" -msgstr "Actualisation" - msgid "Unavailable while heating maintenance function is on." msgstr "Indisponible pendant que la fonction de maintenance par chauffage est activée." @@ -6980,6 +7354,15 @@ msgstr "Changer le diamètre" msgid "Configuration incompatible" msgstr "Configuration incompatible" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Astuces" + msgid "Sync printer information" msgstr "Synchroniser les informations de l'imprimante" @@ -7008,6 +7391,9 @@ msgstr "Cliquez pour éditer le préréglage" msgid "Project Filaments" msgstr "Filaments du projet" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volumes de purge" @@ -7223,9 +7609,6 @@ msgstr "L'imprimante connectée est %s. Elle doit correspondre au préréglage d msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Voulez-vous synchroniser les informations de l'imprimante et changer automatiquement le préréglage ?" -msgid "Tips" -msgstr "Astuces" - msgid "The file does not contain any geometry data." msgstr "Le fichier ne contient pas de données géométriques." @@ -7273,9 +7656,21 @@ msgstr "" "Cette action va rompre la correspondance entre les objets coupés.\n" "Après cela, la cohérence du modèle ne peut plus être garantie." +msgid "Delete Object" +msgstr "Supprimer l’objet" + +msgid "Delete All Objects" +msgstr "Supprimer tous les objets" + +msgid "Reset Project" +msgstr "Réinitialiser le projet" + msgid "The selected object couldn't be split." msgstr "L'objet sélectionné n'a pas pu être divisé." +msgid "Split to Objects" +msgstr "Scinder en objets" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Désactiver le dépôt automatique pour préserver le positionnement en Z ?\n" @@ -7300,6 +7695,9 @@ msgstr "Sélectionnez un nouveau fichier" msgid "File for the replacement wasn't selected" msgstr "Le fichier de remplacement n'a pas été sélectionné" +msgid "Replace with 3D file" +msgstr "Remplacer par un fichier 3D" + msgid "Select folder to replace from" msgstr "Sélectionner le dossier source pour le remplacement" @@ -7346,6 +7744,9 @@ msgstr "Impossible de recharger :" msgid "Error during reload" msgstr "Erreur lors du rechargement" +msgid "Reload all" +msgstr "Tout recharger" + msgid "There are warnings after slicing models:" msgstr "Il y a des avertissements après le découpage des modèles :" @@ -7893,7 +8294,7 @@ msgid "If enabled, a parameter settings dialog will appear during STEP file impo msgstr "Si activé, une boîte de dialogue de paramètres apparaîtra lors de l'importation d'un fichier STEP." msgid "STEP importing: linear deflection" -msgstr "" +msgstr "Import STEP : déviation linéaire" msgid "" "Linear deflection used when meshing imported STEP files.\n" @@ -7901,9 +8302,13 @@ msgid "" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: 0.003 mm." msgstr "" +"Déviation linéaire utilisée lors du maillage des fichiers STEP importés.\n" +"Des valeurs plus petites produisent des maillages de meilleure qualité mais augmentent le temps de traitement.\n" +"Utilisée par défaut dans la fenêtre d’import, ou directement lorsque la fenêtre d’import est désactivée.\n" +"Par défaut : 0,003 mm." msgid "STEP importing: angle deflection" -msgstr "" +msgstr "Import STEP : déviation angulaire" msgid "" "Angle deflection used when meshing imported STEP files.\n" @@ -7911,15 +8316,22 @@ msgid "" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: 0.5." msgstr "" +"Déviation angulaire utilisée lors du maillage des fichiers STEP importés.\n" +"Des valeurs plus petites produisent des maillages de meilleure qualité mais augmentent le temps de traitement.\n" +"Utilisée par défaut dans la fenêtre d’import, ou directement lorsque la fenêtre d’import est désactivée.\n" +"Par défaut : 0,5." msgid "STEP importing: Split into multiple objects" -msgstr "" +msgstr "Import STEP : diviser en plusieurs objets" msgid "" "If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: disabled." msgstr "" +"Si activé, les formes compound et compsolid des fichiers STEP importés sont divisées en plusieurs objets.\n" +"Utilisé par défaut dans la fenêtre d’import, ou directement lorsque la fenêtre d’import est désactivée.\n" +"Par défaut : désactivé." msgid "Quality level for Draco export" msgstr "Niveau de qualité pour l'exportation Draco" @@ -7937,10 +8349,10 @@ msgstr "" "Des valeurs plus basses produisent des fichiers plus petits mais perdent plus de détails géométriques ; des valeurs plus élevées préservent plus de détails au prix de fichiers plus volumineux." msgid "Store full source file paths in projects" -msgstr "" +msgstr "Stocker les chemins complets des fichiers source dans les projets" msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths." -msgstr "" +msgstr "Si activé, les projets enregistrés stockent le chemin absolu des fichiers source importés (STEP/STL/…), afin que « Recharger à partir du disque » fonctionne toujours lorsque le fichier source est conservé dans un dossier différent du projet. Si désactivé, seul le nom du fichier est stocké, ce qui garde les projets portables et évite d’intégrer des chemins absolus." msgid "Preset" msgstr "Préréglage" @@ -8101,6 +8513,15 @@ msgstr "Effacer mon choix pour la synchronisation du préréglage d'imprimante a msgid "Graphics" msgstr "Graphismes" +msgid "Smooth normals" +msgstr "Normales lissées" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Ombrage de Phong" @@ -8116,20 +8537,8 @@ msgstr "Applique le SSAO dans la vue réaliste." msgid "Shadows" msgstr "Ombres" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "Affiche les ombres portées sur la plaque dans la vue réaliste." - -msgid "Smooth normals" -msgstr "Normales lissées" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"Applique les normales lissées à la vue réaliste.\n" -"\n" -"Nécessite un rechargement manuel de la scène pour prendre effet (clic droit sur la vue 3D → « Tout recharger »)." msgid "Anti-aliasing" msgstr "Anticrénelage" @@ -8419,6 +8828,9 @@ msgstr "Préréglages incompatibles" msgid "My Printer" msgstr "Mon imprimante" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filaments gauche" @@ -8437,6 +8849,9 @@ msgstr "Ajouter/Supprimer des préréglages" msgid "Edit preset" msgstr "Modifier le préréglage" +msgid "Change extruder color" +msgstr "Changer la couleur de l’extrudeur" + msgid "Unspecified" msgstr "Non spécifié" @@ -8467,9 +8882,6 @@ msgstr "Sélectionner/supprimer des imprimantes (préréglages du système)" msgid "Create printer" msgstr "Créer une imprimante" -msgid "Empty" -msgstr "Vide" - msgid "Incompatible" msgstr "Incompatible" @@ -8698,12 +9110,42 @@ msgstr "Envoi terminé" msgid "Error code" msgstr "Code d'erreur" -msgid "High Flow" -msgstr "Haut débit" +msgid "Error desc" +msgstr "Description" + +msgid "Extra info" +msgstr "Informations" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "Le réglage de débit de la buse de %s(%s) ne correspond pas au fichier de tranchage (%s). Veuillez vous assurer que la buse installée correspond aux paramètres de l'imprimante, puis définir le préréglage d'imprimante correspondant lors du tranchage." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8765,8 +9207,38 @@ msgstr "Coût de %dg de filament et %d changements de plus que le regroupement o msgid "nozzle" msgstr "buse" -msgid "both extruders" -msgstr "les deux extrudeurs" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "Le réglage de débit de la buse de %s(%s) ne correspond pas au fichier de tranchage (%s). Veuillez vous assurer que la buse installée correspond aux paramètres de l'imprimante, puis définir le préréglage d'imprimante correspondant lors du tranchage." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Conseil : Si vous avez récemment changé la buse de votre imprimante, veuillez aller dans 'Appareil -> Pièces de l'imprimante' pour modifier les paramètres de buse." @@ -8779,10 +9251,17 @@ msgstr "Le diamètre %s (%.1fmm) de l'imprimante actuelle ne correspond pas au f msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Le diamètre de buse actuel (%.1fmm) ne correspond pas au fichier de tranchage (%.1fmm). Veuillez vous assurer que la buse installée correspond aux paramètres de l'imprimante, puis définir le préréglage d'imprimante correspondant lors du tranchage." +msgid "both extruders" +msgstr "les deux extrudeurs" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "La dureté du matériau actuel (%s) dépasse la dureté de %s(%s). Veuillez vérifier les paramètres de buse ou de matériau et réessayer." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] nécessite une impression dans un environnement à haute température. Veuillez fermer la porte." @@ -8892,9 +9371,6 @@ msgstr "Le firmware actuel prend en charge un maximum de 16 matériaux. Vous pou msgid "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." msgstr "Le type de filament externe est inconnu ou ne correspond pas au type de filament du fichier de découpe. Veuillez vérifier que vous avez installé le bon filament sur la bobine externe." -msgid "Please refer to Wiki before use->" -msgstr "Veuillez consulter le Wiki avant utilisation ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Le firmware actuel ne prend pas en charge le transfert de fichiers vers le stockage interne." @@ -9073,6 +9549,9 @@ msgstr "Synchroniser la modification des paramètres avec les paramètres corres msgid "Click to reset all settings to the last saved preset." msgstr "Cliquez pour rétablir tous les paramètres au dernier préréglage enregistré." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Une tour d'amorçage est requise pour le changement de buse. Il peut y avoir des défauts sur le modèle sans cette tour. Êtes-vous sûr de vouloir désactiver la tour d'amorçage ?" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Une tour d’amorçage est requise pour le mode timelapse fluide. Le modèle peut présenter des défauts sans tour d’amorçage. Voulez-vous vraiment la désactiver ?" @@ -9151,9 +9630,6 @@ msgstr "S’ajuster automatiquement à la plage définie ?\n" msgid "Adjust" msgstr "Ajuster" -msgid "Ignore" -msgstr "Ignorer" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Fonction expérimentale : Rétracter et couper le filament à une plus grande distance lors des changements de filament afin de minimiser le rinçage. Bien que cela puisse réduire considérablement le rinçage, cela peut également augmenter le risque de bouchage des buses ou d’autres complications d’impression." @@ -9649,6 +10125,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Voulez-vous vraiment %1% le préréglage sélectionné ?" +msgid "Select printers" +msgstr "Sélectionner les imprimantes" + +msgid "Select profiles" +msgstr "Sélectionner les profils" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9893,6 +10375,12 @@ msgstr "Transférer les valeurs de gauche à droite" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Si elle est activée, cette boîte de dialogue peut être utilisée pour convertir les valeurs sélectionnées de gauche à droite." +msgid "One of the presets does not exist" +msgstr "L’un des préréglages n’existe pas." + +msgid "Compared presets has different printer technology" +msgstr "Les préréglages comparés utilisent une technologie d’imprimante différente." + msgid "Add File" msgstr "Ajouter un Fichier" @@ -10148,12 +10636,8 @@ msgstr "Informations de buse synchronisées avec succès." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Informations de buse et de nombre d'AMS synchronisées avec succès." -msgid "Continue to sync filaments" -msgstr "Continuer la synchronisation des filaments" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Annuler" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Couleur de filament synchronisée avec succès depuis l'imprimante." @@ -10261,6 +10745,9 @@ msgstr "Connexion" msgid "Login failed. Please try again." msgstr "Échec de la connexion. Veuillez réessayer." +msgid "parse json failed" +msgstr "Échec de l’analyse du JSON" + msgid "[Action Required] " msgstr "[Action requise] " @@ -10567,6 +11054,9 @@ msgstr "Nom de l’imprimante" msgid "Where to find your printer's IP and Access Code?" msgstr "Où trouver l'adresse IP et le code d'accès de votre imprimante ?" +msgid "How to trouble shooting" +msgstr "Comment résoudre les problèmes ?" + msgid "Connect" msgstr "Se connecter" @@ -10631,6 +11121,9 @@ msgstr "Module de découpe" msgid "Auto Fire Extinguishing System" msgstr "Système d'extinction automatique" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Bêta" @@ -10649,6 +11142,9 @@ msgstr "La mise à jour a échoué" msgid "Update successful" msgstr "Mise à jour réussie" +msgid "Hotends on Rack" +msgstr "Hotends sur le Rack" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Voulez-vous vraiment effectuer la mise à jour ? Cela prendra environ 10 minutes. Ne mettez pas l'imprimante hors tension durant la mise à jour." @@ -10752,6 +11248,9 @@ msgstr "Erreur de regroupement : " msgid " can not be placed in the " msgstr " ne peut pas être placé dans le/la " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Pont interne" @@ -11430,19 +11929,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Remplacement de l’angle des ponts externes.\n" -"Si laissé à zéro, l’angle des ponts est calculé automatiquement pour chaque pont.\n" -"Sinon, l’angle fourni est utilisé selon :\n" -" - les coordonnées absolues\n" -" - les coordonnées absolues + la rotation du modèle : si « Aligner la direction du remplissage sur le modèle » est activé\n" -" - l’angle automatique optimal + cette valeur : si « Angle de pont relatif » est activé\n" -"\n" -"Utilisez 180° pour un angle absolu nul." msgid "Internal bridge infill direction" msgstr "Direction du remplissage du pont interne" @@ -11452,19 +11943,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Remplacement de l’angle des ponts internes.\n" -"Si laissé à zéro, l’angle des ponts est calculé automatiquement pour chaque pont.\n" -"Sinon, l’angle fourni est utilisé selon :\n" -" - les coordonnées absolues\n" -" - les coordonnées absolues + la rotation du modèle : si « Aligner la direction du remplissage sur le modèle » est activé\n" -" - l’angle automatique optimal + cette valeur : si « Angle de pont relatif » est activé\n" -"\n" -"Utilisez 180° pour un angle absolu nul." msgid "Relative bridge angle" msgstr "Angle de pont relatif" @@ -11954,9 +12437,6 @@ msgstr "" "La géométrie sera décimée avant de détecter les angles vifs. Ce paramètre indique la longueur minimale de l’écart pour la décimation.\n" "0 pour désactiver" -msgid "Select printers" -msgstr "Sélectionner les imprimantes" - msgid "upward compatible machine" msgstr "machine à compatibilité ascendante" @@ -11966,9 +12446,6 @@ msgstr "Condition" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Expression booléenne utilisant les valeurs de configuration d’un profil d’imprimante actif. Si cette expression vaut true, ce profil est considéré comme compatible avec le profil d’imprimante actif." -msgid "Select profiles" -msgstr "Sélectionner les profils" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Expression booléenne utilisant les valeurs de configuration d’un profil d’impression actif. Si cette expression vaut true, ce profil est considéré comme compatible avec le profil d’impression actif." @@ -12234,6 +12711,42 @@ msgstr "Densité de la surface supérieure" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Densité de la couche de surface supérieure. Une valeur de 100 % crée une couche supérieure entièrement solide et lisse. Réduire cette valeur donne une surface supérieure texturée, selon le motif de surface supérieure choisi. Une valeur de 0 % ne créera que les parois sur la couche supérieure. Destiné à des fins esthétiques ou fonctionnelles, pas pour corriger des problèmes comme la surextrusion." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Motif de surface inférieure" @@ -12260,7 +12773,7 @@ msgid "Line width of outer wall. If expressed as a %, it will be computed over t msgstr "Largeur de la ligne de la paroi extérieure. Si elle est exprimée en %, elle sera calculée sur le diamètre de la buse." msgid "This is the printing speed for the outer walls of parts. These are generally printed slower than inner walls for higher quality." -msgstr "Vitesse de paroi extérieure qui est la plus à l'extérieur et visible. Elle est généralement plus lente que la vitesse de la paroi interne pour obtenir une meilleure qualité." +msgstr "Vitesse de paroi extérieure qui est la plus à l'extérieur et visible. Elle est généralement plus lente que la vitesse de la paroi intérieure pour obtenir une meilleure qualité." msgid "Small perimeters" msgstr "Petits périmètres" @@ -12275,16 +12788,16 @@ msgid "This sets the threshold for small perimeter length. Default threshold is msgstr "Cela définit le seuil pour une petite longueur de périmètre. Le seuil par défaut est de 0 mm" msgid "Small support perimeters" -msgstr "" +msgstr "Petits périmètres de support" msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto." -msgstr "" +msgstr "Comme « Petits périmètres », mais pour les supports. Ce réglage distinct affecte la vitesse des supports pour les zones <= `small_support_perimeter_threshold`. S’il est exprimé en pourcentage (par exemple : 80 %), il est calculé à partir du réglage de vitesse des supports ou de l’interface de support ci-dessus. Réglez sur zéro pour automatique." msgid "Small support perimeters threshold" -msgstr "" +msgstr "Seuil des petits périmètres de support" msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm." -msgstr "" +msgstr "Définit le seuil de longueur des petits périmètres de support. Le seuil par défaut est 0 mm." msgid "Walls printing order" msgstr "Ordre d’impression des parois" @@ -12472,7 +12985,7 @@ msgstr "" "3 Entrez les triplets de valeurs PA, de débit et d’accélérations dans la zone de texte ici et sauvegardez votre profil de filament." msgid "Enable adaptive pressure advance within features (beta)" -msgstr "" +msgstr "Activer l’avance de pression adaptative au sein des structures (bêta)" msgid "" "Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n" @@ -12481,9 +12994,14 @@ msgid "" "\n" "This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues." msgstr "" +"Activer le PA adaptatif dès qu’il y a des changements de débit dans une structure, comme des variations de largeur de ligne dans un angle ou des surplombs.\n" +"\n" +"Incompatible avec les imprimantes Prusa, car elles marquent une pause pour traiter les changements de PA, ce qui cause des retards et des défauts.\n" +"\n" +"Il s’agit d’une option expérimentale : si le profil de PA n’est pas réglé avec précision, elle provoquera des problèmes d’uniformité." msgid "Static pressure advance for bridges" -msgstr "" +msgstr "Avance de pression statique pour les ponts" msgid "" "Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n" @@ -12491,6 +13009,10 @@ msgid "" "\n" "A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this." msgstr "" +"Valeur d’avance de pression statique pour les ponts. Réglez sur 0 pour appliquer la même avance de pression que \n" +"pour les parois équivalentes (en utilisant les réglages adaptatifs si activés).\n" +"\n" +"Une valeur de PA plus faible lors de l’impression des ponts aide à réduire l’apparition d’une légère sous-extrusion juste après les ponts. Elle est causée par la chute de pression dans la buse lors de l’impression dans le vide, et un PA plus faible aide à la contrer." msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Largeur de ligne par défaut si les autres largeurs de ligne sont fixées à 0. Si elle est exprimée en %, elle sera calculée sur le diamètre de la buse." @@ -12558,12 +13080,18 @@ msgstr "Auto pour la purge" msgid "Auto For Match" msgstr "Auto pour la correspondance" +msgid "Nozzle Manual" +msgstr "Manuel de Buse" + msgid "Flush temperature" msgstr "Température de purge" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Température lors de la purge du filament. 0 indique la limite supérieure de la plage de température de buse recommandée." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Vitesse volumétrique de purge" @@ -12826,6 +13354,12 @@ msgstr "Filament imprimable" msgid "The filament is printable in extruder." msgstr "Le filament est imprimable dans l'extrudeur." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Température de vitrification" @@ -12863,20 +13397,24 @@ msgid "Angle for solid infill pattern, which controls the start or main directio msgstr "Angle pour le motif de remplissage, qui contrôle le début ou la direction principale de la ligne" msgid "Top layer direction" -msgstr "" +msgstr "Direction de la couche supérieure" msgid "" "Fixed angle for the top solid infill and ironing lines.\n" "Set to -1 to follow the default solid infill direction." msgstr "" +"Angle fixe pour le remplissage plein supérieur et les lignes de lissage.\n" +"Réglez sur -1 pour suivre la direction de remplissage plein par défaut." msgid "Bottom layer direction" -msgstr "" +msgstr "Direction de la couche inférieure" msgid "" "Fixed angle for the bottom solid infill lines.\n" "Set to -1 to follow the default solid infill direction." msgstr "" +"Angle fixe pour les lignes de remplissage plein inférieur.\n" +"Réglez sur -1 pour suivre la direction de remplissage plein par défaut." msgid "Sparse infill density" msgstr "Densité de remplissage" @@ -12885,15 +13423,13 @@ msgstr "Densité de remplissage" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Densité du remplissage interne, 100% transforme tous les remplissages en remplissages pleins et le modèle de remplissage interne sera utilisé" -msgid "Align infill direction to model" -msgstr "Aligner la direction du remplissage sur le modèle" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"Aligne les directions du remplissage, des ponts, du lissage et des surfaces sur l’orientation du modèle sur le plateau.\n" -"Lorsque cette option est activée, les directions pivotent avec le modèle afin de conserver des caractéristiques de résistance optimales." msgid "Insert solid layers" msgstr "Insérer des couches solides" @@ -13419,6 +13955,15 @@ msgstr "Meilleure position d’organisation automatique dans la plage [0,1] par msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Activer cette option si l’imprimante est équipée d'un ventilateur de refroidissement auxiliaire. Commande G-code : M106 P2 S (0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13492,6 +14037,12 @@ msgstr "" "Activez cette option si l’imprimante prend en charge la filtration de l’air\n" "Commande G-code : M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Utiliser le filtre de refroidissement" + +msgid "Enable this if printer support cooling filter" +msgstr "Activez cette option si l'imprimante prend en charge le filtre de refroidissement" + msgid "G-code flavor" msgstr "Version du G-code" @@ -14013,6 +14564,30 @@ msgstr "Vitesse de déplacement minimale" msgid "Minimum travel speed (M205 T)" msgstr "Vitesse de déplacement minimale (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Force maximale de l'axe Y" + +msgid "The allowed maximum output force of Y axis" +msgstr "Force de sortie maximale autorisée sur l'axe Y" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Masse du plateau de l'axe Y" + +msgid "The machine bed mass load of Y axis" +msgstr "Charge massique du plateau de la machine sur l'axe Y" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "Masse maximale imprimée autorisée" + +msgid "The allowed max printed mass on a plate" +msgstr "Masse maximale imprimée autorisée sur une plaque" + msgid "Maximum acceleration for extruding" msgstr "Accélération maximale pour l'extrusion" @@ -14350,7 +14925,7 @@ msgid "This detects the overhang percentage relative to line width and uses a di msgstr "Détectez le pourcentage de surplomb par rapport à la largeur de la ligne et utilisez une vitesse différente pour imprimer. Pour un surplomb de 100%% la vitesse du pont est utilisée." msgid "Outer walls" -msgstr "Parois externes" +msgstr "Parois extérieures" msgid "" "Filament to print outer walls.\n" @@ -14360,7 +14935,7 @@ msgstr "" "\"Défaut\" utilise le filament actif de l’objet ou de la pièce." msgid "Inner walls" -msgstr "Parois internes" +msgstr "Parois intérieures" msgid "" "Filament to print inner walls.\n" @@ -14565,6 +15140,9 @@ msgstr "Entraînement direct" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Hybride" + msgid "Enable filament dynamic map" msgstr "Activer le mappage dynamique des filaments" @@ -14598,6 +15176,12 @@ msgstr "Vitesse de réinsertion" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Vitesse de rechargement du filament dans la buse. Zéro signifie la même vitesse que la rétraction." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Utiliser la rétraction firmware" @@ -14628,6 +15212,9 @@ msgstr "Alignée" msgid "Aligned back" msgstr "Aligné à l'arrière" +msgid "Back" +msgstr "Arrière" + msgid "Random" msgstr "Aléatoire" @@ -14717,7 +15304,7 @@ msgid "Minimum number of segments of each scarf." msgstr "Nombre minimum de segments de chaque biseau." msgid "Scarf joint for inner walls" -msgstr "Joint en biseau pour les parois internes" +msgstr "Joint en biseau pour les parois intérieures" msgid "Use scarf joint for inner walls as well." msgstr "Utiliser également un joint en biseau pour les parois intérieures." @@ -14900,6 +15487,12 @@ msgstr "Si le mode fluide ou traditionnel est sélectionné, une vidéo en timel msgid "Traditional" msgstr "Traditionnel" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Variation de température" @@ -14985,6 +15578,18 @@ msgstr "Amorcer tous les extrudeurs d’impression" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Si cette option est activée, tous les extrudeurs d’impression seront amorcés sur le bord avant du plateau au début de l’impression." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Rayon de fermeture de l’écart des tranches" @@ -15363,7 +15968,7 @@ msgstr "" "S’il est activé, ce paramètre définit également une variable gcode nommée chamber_temperature, qui peut être utilisée pour transmettre la température de caisson souhaitée à votre macro de démarrage de l’impression, ou à une macro de trempe thermique comme celle-ci : PRINT_START (autres variables) CHAMBER_TEMP=[chamber_temperature]. Cela peut être utile si votre imprimante ne prend pas en charge les commandes M141/M191, ou si vous souhaitez gérer le préchauffage dans la macro de démarrage de l’impression si aucun chauffage de caisson actif n’est installé." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15417,6 +16022,45 @@ msgstr "Épaisseur de la coque supérieure" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Le nombre de couches solides supérieures est augmenté lors du découpage si l'épaisseur calculée par les couches de coque supérieures est inférieure à cette valeur. Cela peut éviter d'avoir une coque trop fine lorsque la hauteur de couche est faible. 0 signifie que ce paramètre est désactivé et que l'épaisseur de la coque supérieure est simplement déterminée par le nombre de couches de coque supérieures." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "Vitesse de déplacement plus rapide et sans extrusion" @@ -15460,12 +16104,30 @@ msgstr "Multiplicateur de purge" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Les volumes de purge actuels sont égaux à la valeur du multiplicateur de purge multiplié par les volumes de purge dans le tableau." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Volume d’amorçage" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Le volume de matériau pour amorcer l'extrudeur sur la tour." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "Largeur de la tour d’amorçage" @@ -15654,12 +16316,14 @@ msgid "Rotate the polyhole every layer." msgstr "Faites pivoter le trou polygone à chaque couche." msgid "Maximum Polyhole edge count" -msgstr "" +msgstr "Nombre maximal d’arêtes de polyhole" msgid "" "Maximum number of polyhole edges\n" "This setting limits the amount of edges a polyhole can have" msgstr "" +"Nombre maximal d’arêtes de polyhole\n" +"Ce réglage limite le nombre d’arêtes qu’un polyhole peut avoir" msgid "G-code thumbnails" msgstr "Vignette G-code" @@ -15751,6 +16415,57 @@ msgstr "Largeur minimale de la paroi" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Largeur de la paroi qui remplacera les éléments fins (selon la taille minimale des éléments) du modèle. Si la largeur minimale de la paroi est inférieure à l'épaisseur de l'élément, la paroi deviendra aussi épaisse que l'élément lui-même. Elle est exprimée en pourcentage par rapport au diamètre de la buse" +msgid "Hotend change time" +msgstr "Temps de changement du Hotend" + +msgid "Time to change hotend." +msgstr "Il est temps de changer le Hotend." + +msgid "Hotend change" +msgstr "Changement de Hotend" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Lors du remplacement du hotend, il est recommandé d'extruder une certaine longueur de filament à partir de la buse d'origine. Cela permet de minimiser la bavure de la buse." + +msgid "Extruder change" +msgstr "Changement d'extrudeur" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Pour éviter le suintement, la buse effectue un mouvement inverse pendant un certain temps après la fin de l'éperonnage. Le réglage définit le temps de déplacement." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Pour éviter tout suintement, la température de la buse sera réduite pendant l'éperonnage. Par conséquent, le temps d'éperonnage doit être supérieur au temps de refroidissement. 0 signifie désactivé." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "La vitesse volumétrique maximale pour l'éperonnage avant le changement d'extrudeuse, où -1 signifie utiliser la vitesse volumétrique maximale." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Pour éviter les coulures, la température de la buse sera refroidie pendant l'éperonnage. Remarque : seule une commande de refroidissement et l'activation du ventilateur sont déclenchées, l'obtention de la température cible n'est pas garantie. 0 signifie désactivé." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "La vitesse volumétrique maximale pour l'éperonnage avant un changement de Hotend, où -1 signifie utiliser la vitesse volumétrique maximale." + +msgid "length when change hotend" +msgstr "longueur lors du changement de hotend" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Lorsque cette valeur de rétraction est modifiée, elle sera utilisée comme la quantité de filament rétractée à l'intérieur du hotend avant de changer de hotend." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Le volume de matériau nécessaire pour amorcer l'extrudeur lors d'un changement de hotend sur la tourelle." + +msgid "Preheat temperature delta" +msgstr "Écart de température de préchauffage" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Écart de température appliqué lors du préchauffage avant un changement d'outil." + msgid "Detect narrow internal solid infills" msgstr "Détecter les remplissages solides internes étroits" @@ -16491,12 +17206,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Calibration non prise en charge" -msgid "Error desc" -msgstr "Description" - -msgid "Extra info" -msgstr "Informations" - msgid "Flow Dynamics" msgstr "Calibration dynamique" @@ -16699,6 +17408,12 @@ msgstr "Veuillez saisir le nom que vous souhaitez enregistrer sur l’imprimante msgid "The name cannot exceed 40 characters." msgstr "Le nom ne peut pas dépasser 40 caractères." +msgid "Nozzle ID" +msgstr "ID de Buse" + +msgid "Standard Flow" +msgstr "Débit Standard" + msgid "Please find the best line on your plate" msgstr "Veuillez trouver la meilleure ligne sur votre plateau" @@ -16788,9 +17503,6 @@ msgstr "Les informations de l'AMS et de la buse sont synchronisées" msgid "Nozzle Flow" msgstr "Débit de buse" -msgid "Nozzle Info" -msgstr "Info buse" - msgid "Filament position" msgstr "position du filament" @@ -16864,6 +17576,10 @@ msgstr "Récupération de l'historique réussie" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Actualisation de historique des calibrations dynamiques du débit" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Remarque : Le numéro du hotend sur le %s est lié au support. Lorsque le hotend est déplacé vers un nouveau support, son numéro sera mis à jour automatiquement." + msgid "Action" msgstr "Action" @@ -18610,6 +19326,12 @@ msgstr "Échec de l’impression" msgid "Removed" msgstr "Supprimé" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Ne plus me rappeler" @@ -18643,12 +19365,25 @@ msgstr "Tutoriel vidéo" msgid "(Sync with printer)" msgstr "(Synchroniser avec l'imprimante)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Nous allons trancher selon cette méthode de regroupement :" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Astuce : Vous pouvez faire glisser les filaments pour les réassigner à différentes buses." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "La méthode de regroupement des filaments pour la plaque actuelle est déterminée par l'option déroulante du bouton de la plaque de tranchage." @@ -18880,9 +19615,6 @@ msgstr "Cette action ne peut pas être annulée. Continuer ?" msgid "Skipping objects." msgstr "Ignorer des objets." -msgid "Select Filament" -msgstr "Sélectionner le filament" - msgid "Null Color" msgstr "Couleur nulle" @@ -18991,10 +19723,10 @@ msgid "Calculating, please wait..." msgstr "Calcul en cours, veuillez patienter…" msgid "Save these settings as default" -msgstr "" +msgstr "Enregistrer ces réglages par défaut" msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)." -msgstr "" +msgstr "Si activé, les valeurs ci-dessus sont stockées comme valeurs par défaut pour les futurs imports STEP (et affichées dans les Préférences)." msgid "PresetBundle" msgstr "Paquet de préréglages" @@ -19397,6 +20129,77 @@ msgstr "" "Éviter la déformation\n" "Saviez-vous que lors de l’impression de matériaux susceptibles de se déformer, tels que l’ABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Affiche les ombres portées sur la plaque dans la vue réaliste." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "Applique les normales lissées à la vue réaliste.\n" +#~ "\n" +#~ "Nécessite un rechargement manuel de la scène pour prendre effet (clic droit sur la vue 3D → « Tout recharger »)." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Continuer la synchronisation des filaments" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Annuler" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Remplacement de l’angle des ponts externes.\n" +#~ "Si laissé à zéro, l’angle des ponts est calculé automatiquement pour chaque pont.\n" +#~ "Sinon, l’angle fourni est utilisé selon :\n" +#~ " - les coordonnées absolues\n" +#~ " - les coordonnées absolues + la rotation du modèle : si « Aligner la direction du remplissage sur le modèle » est activé\n" +#~ " - l’angle automatique optimal + cette valeur : si « Angle de pont relatif » est activé\n" +#~ "\n" +#~ "Utilisez 180° pour un angle absolu nul." + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Remplacement de l’angle des ponts internes.\n" +#~ "Si laissé à zéro, l’angle des ponts est calculé automatiquement pour chaque pont.\n" +#~ "Sinon, l’angle fourni est utilisé selon :\n" +#~ " - les coordonnées absolues\n" +#~ " - les coordonnées absolues + la rotation du modèle : si « Aligner la direction du remplissage sur le modèle » est activé\n" +#~ " - l’angle automatique optimal + cette valeur : si « Angle de pont relatif » est activé\n" +#~ "\n" +#~ "Utilisez 180° pour un angle absolu nul." + +#~ msgid "Align infill direction to model" +#~ msgstr "Aligner la direction du remplissage sur le modèle" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "Aligne les directions du remplissage, des ponts, du lissage et des surfaces sur l’orientation du modèle sur le plateau.\n" +#~ "Lorsque cette option est activée, les directions pivotent avec le modèle afin de conserver des caractéristiques de résistance optimales." + +#~ msgid "Print" +#~ msgstr "Imprimer" + #~ msgid "in" #~ msgstr "dans" @@ -20388,9 +21191,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Impossible de démarrer sans carte SD." -#~ msgid "Update" -#~ msgstr "Mise à jour" - #~ msgid "Sensitivity of pausing is" #~ msgstr "La sensibilité de pause est" @@ -21107,10 +21907,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Désélectionner" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Redimensionner" - #~ msgid "Lift Z Enforcement" #~ msgstr "Exécution du décalage en Z" diff --git a/localization/i18n/hu/OrcaSlicer_hu.po b/localization/i18n/hu/OrcaSlicer_hu.po index 497f0ebf29..d41cccaed2 100644 --- a/localization/i18n/hu/OrcaSlicer_hu.po +++ b/localization/i18n/hu/OrcaSlicer_hu.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "Language: hu\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -32,6 +32,24 @@ msgstr "Az AMS nem támogatja a TPU-t." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "Az AMS nem támogatja a \"Bambu Lab PET-CF\" filamentet." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "TPU nyomtatása előtt végezz hideghúzási módszert az eltömődés elkerüléséhez. Használhatod a hideghúzási módszert a nyomtató karbantartásához." @@ -44,6 +62,9 @@ msgstr "A nedves PVA rugalmas, ezért elakadhat az extruderben. Használat előt msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "A PLA Glow érdes felülete felgyorsíthatja az AMS rendszer kopását, különösen az AMS Lite belső alkatrészein." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "A CF/GF filament rideg és törékeny, ezért könnyen eltörhet vagy elakadhat az AMS-ben; kérlek, légy körültekintő a használatakor." @@ -53,10 +74,90 @@ msgstr "A PPS-CF rideg, ezért eltörhet a nyomtatófej feletti meghajlított PT msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "A PPA-CF rideg, ezért eltörhet a nyomtatófej feletti meghajlított PTFE csőben." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "A(z) %s nem támogatott a(z) %s extruderen." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Nagy áramlás" + +msgid "Standard" +msgstr "Normál" + +msgid "TPU High Flow" +msgstr "TPU nagy áramlású" + +msgid "Unknown" +msgstr "Ismeretlen" + +msgid "Hardened Steel" +msgstr "Edzett acél" + +msgid "Stainless Steel" +msgstr "Rozsdamentes acél" + +msgid "Tungsten Carbide" +msgstr "Volfrám-karbid" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Előfordulhat, hogy a szerszámfej és a hotendtartó megmozdul. Kérjük, ne nyúlj a kamrába." + +msgid "Warning" +msgstr "Figyelmeztetés" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "A hotendinformációk pontatlanok lehetnek. Szeretnéd újra beolvasni a hotendet? (A hotendinformáció kikapcsolt állapotban megváltozhat)." + +msgid "I confirm all" +msgstr "Összes megerősítése" + +msgid "Re-read all" +msgstr "Összes újraolvasása" + +msgid "Reading the hotends, please wait." +msgstr "A hotendek beolvasása folyamatban van, kérjük várj." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "A hotend felismerése során a szerszámfej mozogni fog. Ne nyúlj be a kamrába." + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "Jelenlegi AMS páratartalom" @@ -87,6 +188,85 @@ msgstr "Verzió:" msgid "Latest version" msgstr "Legfrissebb verzió" +msgid "Row A" +msgstr "„A“ sor" + +msgid "Row B" +msgstr "„B“ sor" + +msgid "Toolhead" +msgstr "Szerszámfej" + +msgid "Empty" +msgstr "Üres" + +msgid "Error" +msgstr "Hiba" + +msgid "Induction Hotend Rack" +msgstr "Indukciós hotendtartó" + +msgid "Hotends Info" +msgstr "Hotendek adatai" + +msgid "Read All" +msgstr "Összes beolvasása" + +msgid "Reading " +msgstr "Beolvasás " + +msgid "Please wait" +msgstr "Kérjük, várj" + +msgid "Running..." +msgstr "Futtatás..." + +msgid "Raised" +msgstr "Felemelve" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "A hotend állapota rendellenes, és jelenleg nem elérhető. Kérjük, lépj az „Eszköz -> Frissítés“ oldalra a firmware frissítéséhez." + +msgid "Abnormal Hotend" +msgstr "Rendellenes hotend" + +msgid "Refresh" +msgstr "Frissítés" + +msgid "Refreshing" +msgstr "Frissítés" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "A hotend állapota nem megfelelő, jelenleg nem kérdezhető le. Frissítsd a firmware-t, és próbáld újra." + +msgid "Cancel" +msgstr "Mégse" + +msgid "Jump to the upgrade page" +msgstr "Ugrás a frissítés oldalra" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Verzió" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Felhasznált idő: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "A dinamikus fúvókák a jelenlegi tálcához vannak kiosztva. A hotend kiválasztása nem támogatott." + +msgid "Hotend Rack" +msgstr "Hotendtartó" + +msgid "ToolHead" +msgstr "Szerszámfej" + +msgid "Nozzle information needs to be read" +msgstr "A fúvókainformációkat be kell olvasni" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Támaszok festése" @@ -159,6 +339,12 @@ msgstr "Kitöltés" msgid "Gap Fill" msgstr "Hézagok kitöltése" +msgid "Vertical" +msgstr "Függőleges" + +msgid "Horizontal" +msgstr "Vízszintes" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Csak a(z) \"%1%\" által kijelölt felületeken történik festés" @@ -254,12 +440,6 @@ msgstr "Háromszög" msgid "Height Range" msgstr "Magasságtartomány" -msgid "Vertical" -msgstr "Függőleges" - -msgid "Horizontal" -msgstr "Vízszintes" - msgid "Remove painted color" msgstr "Festett szín eltávolítása" @@ -324,6 +504,7 @@ msgstr "Gizmo-Forgatás" msgid "Optimize orientation" msgstr "Orientáció optimalizálása" +msgctxt "Verb" msgid "Scale" msgstr "Átméretezés" @@ -368,6 +549,9 @@ msgstr "Méretarányok" msgid "Object operations" msgstr "Objektum műveletek" +msgid "Scale" +msgstr "Átméretezés" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Térfogat műveletek" @@ -419,6 +603,10 @@ msgstr "Az aktuális forgatás visszaállítása a forgatás eszköz megnyitása msgid "Reset current rotation to real zeros." msgstr "Az aktuális forgatás visszaállítása valódi nullára." +msgctxt "Noun" +msgid "Scale" +msgstr "Átméretezés" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Méret" @@ -601,9 +789,6 @@ msgstr "Távolság aránya a sugárhoz viszonyítva" msgid "Confirm connectors" msgstr "Csatlakozók megerősítése" -msgid "Cancel" -msgstr "Mégse" - msgid "Flip cut plane" msgstr "Vágósík megfordítása" @@ -644,12 +829,12 @@ msgstr "Részekre darabolás" msgid "Reset cutting plane and remove connectors" msgstr "Vágósík visszaállítása és connectorok eltávolítása" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Vágás" -msgid "Warning" -msgstr "Figyelmeztetés" - msgid "Invalid connectors detected" msgstr "Érvénytelen csatlakozók észlelve" @@ -680,6 +865,13 @@ msgstr "A horonnyal rendelkező vágósík érvénytelen" msgid "Connector" msgstr "Csatlakozó" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Vágás Síkkal" @@ -727,9 +919,6 @@ msgstr "Egyszerűsítés" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Az egyszerűsítés jelenleg csak akkor engedélyezett, ha egyetlen tárgy van kiválasztva" -msgid "Error" -msgstr "Hiba" - msgid "Extra high" msgstr "Extra magas" @@ -2005,6 +2194,9 @@ msgstr "A %s csomaghoz való hozzáférés jogosulatlan." msgid "Loading user preset" msgstr "Felhasználói beállítás betöltése" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s eltávolítva." @@ -2018,6 +2210,18 @@ msgstr "Válaszd ki a nyelvet" msgid "Language" msgstr "Nyelv" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2651,6 +2855,45 @@ msgstr "Kattints az ikonra az objektum színfestésének szerkesztéséhez" msgid "Click the icon to shift this object to the bed" msgstr "Kattints az ikonra az objektum tárgyasztalra helyezéséhez" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Fájl betöltése" @@ -2660,6 +2903,9 @@ msgstr "Hiba!" msgid "Failed to get the model data in the current file." msgstr "Nem sikerült beolvasni a modelladatokat az aktuális fájlba." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Általános" @@ -2672,6 +2918,12 @@ msgstr "Válts át objektumonkénti beállítás módba a kiválasztott objektum msgid "Remove paint-on fuzzy skin" msgstr "Festett bolyhos felület eltávolítása" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Magasságtartomány eltávolítása" + msgid "Delete connector from object which is a part of cut" msgstr "Connector törlése a vágás részét képező objektumból" @@ -2702,12 +2954,24 @@ msgstr "Összes csatlakozó törlése" msgid "Deleting the last solid part is not allowed." msgstr "Az utolsó szilárd rész törlése nem megengedett." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "A célobjektum csak egy részt tartalmaz, ezért nem osztható fel." +msgid "Split to parts" +msgstr "Felosztás tárgyakra" + msgid "Assembly" msgstr "Összeállítás" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Vágási csatlakozó információk" @@ -2741,6 +3005,9 @@ msgstr "Magasságtartományok" msgid "Settings for height range" msgstr "Magasságtartomány beállításai" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Réteg" @@ -2763,6 +3030,9 @@ msgstr "Típus:" msgid "Choose part type" msgstr "Alkatrésztípus kiválasztása" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Adj meg egy új nevet" @@ -2790,6 +3060,9 @@ msgstr "A(z) \"%s\" a felosztás után meghaladja az 1 millió felületet, ami n msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "A(z) \"%s\" rész hálója hibákat tartalmaz. Előbb javítsd ki." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "További folyamatbeállítások" @@ -2799,9 +3072,6 @@ msgstr "Paraméter eltávolítása" msgid "to" msgstr "eddig" -msgid "Remove height range" -msgstr "Magasságtartomány eltávolítása" - msgid "Add height range" msgstr "Magasságtartomány hozzáadása" @@ -3013,6 +3283,9 @@ msgstr "Válassz ki egy AMS-helyet, majd nyomd meg a \"Betöltés\" vagy a \"Kit msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "A művelethez szükséges filament típusa ismeretlen. Állítsd be a célfilament adatait." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "A ventilátorsebesség módosítása nyomtatás közben befolyásolhatja a nyomtatás minőségét, válassz körültekintően." @@ -3135,6 +3408,24 @@ msgstr "Extrudálás megerősítése" msgid "Check filament location" msgstr "Ellenőrizd a filament helyzetét" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "A maximális hőmérséklet nem haladhatja meg ezt: " @@ -3188,6 +3479,62 @@ msgstr "Fejlesztői mód" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Kérjük, állítsd be a fúvókaszámot" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Hiba: Nem lehet mindkét fúvóka számát nullára állítani." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Hiba: A fúvóka száma nem haladhatja meg a(z) %d értéket." + +msgid "Confirm" +msgstr "Megerősítés" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "Fúvóka kiválasztás" + +msgid "Available Nozzles" +msgstr "Elérhető fúvókák" + +msgid "Nozzle Info" +msgstr "Fúvókaadatok" + +msgid "Sync Nozzle status" +msgstr "Fúvókaállapot szinkronizálása" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Figyelem: Nem lehetséges a fúvókaátmérők keverése egyetlen nyomtatás során. Ha a kiválasztott méret csak egy extruderen van, akkor az egy extruderes nyomtatás lesz kényszerítve." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Frissítés %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Ismeretlen fúvóka érzékelve. Frissítsd az adatokat (a nem frissített fúvókákat nem használjuk a szeleteléskor). Hasonlítsd össze a fúvóka átmérőjét és a térfogatáramot a megjelenített értékekkel." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Ismeretlen fúvóka érzékelve. Frissítsd az adatokat (a nem frissített fúvókákat nem használjuk a szeleteléskor)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Kérjük, ellenőrizd, hogy a szükséges fúvókaátmérő és áramlási sebesség megegyezik-e a kijelzőn lévővel." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "A nyomtatóban különböző fúvókák vannak. Kérjük, válassz egy fúvókát a nyomtatáshoz." + +msgid "Ignore" +msgstr "Mellőzés" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3521,15 +3868,9 @@ msgstr "Az OrcaSlicer ugyanebben a szellemben indult, a PrusaSlicer, a BambuStud msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Ma az OrcaSlicer a legszélesebb körben használt és legaktívabban fejlesztett nyílt forráskódú szeletelő a 3D nyomtatási közösségben. Sok újítását más szeletelők is átvették, így az egész iparág hajtóereje." -msgid "Version" -msgstr "Verzió" - msgid "AMS Materials Setting" msgstr "AMS anyagok beállítása" -msgid "Confirm" -msgstr "Megerősítés" - msgid "Close" msgstr "Bezárás" @@ -3550,12 +3891,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "A megadott értéknek nagyobbnak kell lennie, mint %1% és kisebbnek, mint %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Anyagáramlás kalibrálásának faktorai" +msgid "Wiki Guide" +msgstr "Wiki útmutató" + msgid "PA Profile" msgstr "PA-profil" @@ -3645,7 +3986,7 @@ msgstr "A kalibrálás befejeződött. Kérlek, válaszd ki az alábbi képen l msgid "Save" msgstr "Mentés" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Hátul" @@ -3729,6 +4070,19 @@ msgstr "Jobb fúvóka" msgid "Nozzle" msgstr "Fúvóka" +msgid "Select Filament && Hotends" +msgstr "Válassz filamentet és hotendet" + +msgid "Select Filament" +msgstr "Filament kiválasztása" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "A jelenlegi fúvókával történő nyomtatás %0.2f g többlethulladékot eredményezhet." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Megjegyzés: a filament típusa (%s) nem egyezik a szeletelési fájlban lévő filament típussal (%s). Ha ezt a férőhelyet szeretnéd használni, telepíts %s filamentet %s helyett, és módosítsd a férőhely adatait az 'Eszköz' oldalon." @@ -4439,9 +4793,6 @@ msgstr "Felület mérése" msgid "Calibrating the detection position of nozzle clumping" msgstr "A fúvóka csomósodás-észlelési pozíciójának kalibrálása" -msgid "Unknown" -msgstr "Ismeretlen" - msgid "Update successful." msgstr "Sikeres frissítés." @@ -4953,9 +5304,6 @@ msgstr "Beállítás optimálisra" msgid "Regroup filament" msgstr "Filamentek újracsoportosítása" -msgid "Wiki Guide" -msgstr "Wiki útmutató" - msgid "up to" msgstr "legfeljebb" @@ -4992,7 +5340,7 @@ msgstr "Rántás (mm/s)" msgid "Fan speed (%)" msgstr "Ventilátor fordulatszám (%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "Hőmérséklet (°C)" msgid "Volumetric flow rate (mm³/s)" @@ -5011,9 +5359,6 @@ msgstr "Filamentcserék" msgid "Options" msgstr "Opciók" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "Költség" @@ -5026,6 +5371,7 @@ msgstr "Szerszámváltások" msgid "Color change" msgstr "Színváltás" +msgctxt "Noun" msgid "Print" msgstr "Nyomtatás" @@ -5189,11 +5535,15 @@ msgstr "Extrudáláskalibráció környékének elkerülése" msgid "Align to Y axis" msgstr "Igazítás az Y-tengelyhez" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Hátul" + +msgctxt "Camera View" msgid "Left" msgstr "Bal" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Jobb" @@ -5218,9 +5568,6 @@ msgstr "Objektumok elrendezése a kiválasztott tálcákon" msgid "Split to objects" msgstr "Felosztás objektumokra" -msgid "Split to parts" -msgstr "Felosztás tárgyakra" - msgid "Assembly View" msgstr "Összeszerelési nézet" @@ -5521,6 +5868,10 @@ msgstr "Nyomtatótálca" msgid "Export G-code file" msgstr "G-kód fájl exportálása" +msgctxt "Verb" +msgid "Print" +msgstr "Nyomtatás" + msgid "Export plate sliced file" msgstr "Szeletelt tálca exportálása" @@ -5694,15 +6045,6 @@ msgstr "Aktuális konfiguráció exportálása fájlokba" msgid "Export" msgstr "Exportálás" -msgid "Sync Presets" -msgstr "Beállítások szinkronizálása" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Hívd le és alkalmazd az OrcaCloud legújabb beállításait" - -msgid "You must be logged in to sync presets from cloud." -msgstr "A beállítások felhőből történő szinkronizálásához be kell jelentkezz." - msgid "Quit" msgstr "Kilépés" @@ -5819,6 +6161,15 @@ msgstr "Nézet" msgid "Preset Bundle" msgstr "Beállításcsomag" +msgid "Sync Presets" +msgstr "Beállítások szinkronizálása" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Hívd le és alkalmazd az OrcaCloud legújabb beállításait" + +msgid "You must be logged in to sync presets from cloud." +msgstr "A beállítások felhőből történő szinkronizálásához be kell jelentkezz." + msgid "Syncing presets from cloud…" msgstr "Beállítások szinkronizálása a felhőből…" @@ -5939,6 +6290,9 @@ msgstr "Exportálás eredménye" msgid "Select profile to load:" msgstr "Válaszd ki a betölteni kívánt profilt:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6107,9 +6461,6 @@ msgstr "Kiválasztott fájlok letöltése a nyomtatóról." msgid "Batch manage files." msgstr "Fájlok kötegelt kezelése." -msgid "Refresh" -msgstr "Frissítés" - msgid "Reload file list from printer." msgstr "Fájllista újratöltése a nyomtatóról." @@ -6422,6 +6773,9 @@ msgstr "Nyomtatási lehetőségek" msgid "Safety Options" msgstr "Biztonsági beállítások" +msgid "Hotends" +msgstr "Hotendek" + msgid "Lamp" msgstr "Világítás" @@ -6455,6 +6809,12 @@ msgstr "Ha a nyomtatás szünetel, filament be- és kitöltés csak külső fér msgid "Current extruder is busy changing filament." msgstr "Az aktuális extruder filamentet vált, ezért foglalt." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Az aktuális férőhely már be van töltve." @@ -6505,9 +6865,6 @@ msgstr "Ez csak a nyomtatás során érvényesül" msgid "Silent" msgstr "Csendes" -msgid "Standard" -msgstr "Normál" - msgid "Sport" msgstr "" @@ -6541,6 +6898,12 @@ msgstr "Fénykép hozzáadása" msgid "Delete Photo" msgstr "Fénykép törlése" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Elküldés" @@ -6724,6 +7087,9 @@ msgstr "LAN only mód használata" msgid "Don't show this dialog again" msgstr "Ne jelenjen meg többé ez a párbeszédablak" +msgid "Please refer to Wiki before use->" +msgstr "Használat előtt nézd meg a Wikit ->" + msgid "3D Mouse disconnected." msgstr "3D Mouse csatlakoztatva." @@ -6978,27 +7344,18 @@ msgstr "Áramlás" msgid "Please change the nozzle settings on the printer." msgstr "Módosítsd a fúvóka beállításait a nyomtatón." -msgid "Hardened Steel" -msgstr "Edzett acél" - -msgid "Stainless Steel" -msgstr "Rozsdamentes acél" - -msgid "Tungsten Carbide" -msgstr "Volfrám-karbid" - msgid "Brass" msgstr "Sárgaréz" msgid "High flow" msgstr "Nagy átfolyás" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Ehhez a nyomtatóhoz nincs elérhető wiki hivatkozás." -msgid "Refreshing" -msgstr "Frissítés" - msgid "Unavailable while heating maintenance function is on." msgstr "Nem érhető el, amíg a fűtéskarbantartási funkció be van kapcsolva." @@ -7121,6 +7478,15 @@ msgstr "Átmérő váltása" msgid "Configuration incompatible" msgstr "Nem kompatibilis konfiguráció" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Tippek" + msgid "Sync printer information" msgstr "Nyomtatóinformációk szinkronizálása" @@ -7149,6 +7515,9 @@ msgstr "Kattints a beállítás szerkesztéséhez" msgid "Project Filaments" msgstr "Projekt filamentek" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Öblítési mennyiségek" @@ -7369,9 +7738,6 @@ msgstr "A csatlakoztatott nyomtató: %s. Ennek egyeznie kell a projekt nyomtatá msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Szeretnéd szinkronizálni a nyomtató adatait, és automatikusan átváltani a beállítást?" -msgid "Tips" -msgstr "Tippek" - msgid "The file does not contain any geometry data." msgstr "A fájl nem tartalmaz geometriai adatokat." @@ -7420,9 +7786,21 @@ msgstr "" "Ez a művelet megszakítja a vágási kapcsolatot.\n" "Ezután a modell konzisztenciája nem garantálható." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "A kijelölt objektumot nem lehet feldarabolni." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Letiltja az Auto-Drop funkciót a Z pozicionálás megőrzéséhez?\n" @@ -7449,6 +7827,9 @@ msgstr "Válassz egy új fájlt" msgid "File for the replacement wasn't selected" msgstr "A cserefájl nem lett kiválasztva" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Cseréhez mappa kiválasztása" @@ -7495,6 +7876,9 @@ msgstr "Nem sikerült újratölteni:" msgid "Error during reload" msgstr "Hiba az újratöltés során" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "A modellek szeletelése a következő figyelmeztetéseket generálta:" @@ -8267,6 +8651,15 @@ msgstr "Választásom törlése a nyomtatóbeállítás szinkronizálásához f msgid "Graphics" msgstr "Grafika" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8282,16 +8675,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8589,6 +8973,9 @@ msgstr "Nem kompatibilis beállítások" msgid "My Printer" msgstr "A nyomtatóm" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Bal oldali filamentek" @@ -8608,6 +8995,9 @@ msgstr "Beállítások hozzáadása/eltávolítása" msgid "Edit preset" msgstr "Beállítás módosítása" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Meghatározatlan" @@ -8639,9 +9029,6 @@ msgstr "Nyomtatók kiválasztása/eltávolítása (rendszerbeállítások)" msgid "Create printer" msgstr "Nyomtató létrehozása" -msgid "Empty" -msgstr "Üres" - msgid "Incompatible" msgstr "Nem kompatibilis" @@ -8873,12 +9260,42 @@ msgstr "küldés befejezve" msgid "Error code" msgstr "Hibakód" -msgid "High Flow" -msgstr "Nagy áramlás" +msgid "Error desc" +msgstr "Hibaleírás" + +msgid "Extra info" +msgstr "Extra infó" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "A(z) %s(%s) fúvókaáramlási beállítása nem egyezik a szeletelési fájl értékével (%s). Győződj meg róla, hogy a beszerelt fúvóka megegyezik a nyomtató beállításaival, majd szeleteléskor állítsd be a megfelelő nyomtató-előbeállítást." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8941,8 +9358,38 @@ msgstr "%dg-mal több filament és %d váltással több az optimális csoportos msgid "nozzle" msgstr "fúvóka" -msgid "both extruders" -msgstr "mindkét extruder" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "A(z) %s(%s) fúvókaáramlási beállítása nem egyezik a szeletelési fájl értékével (%s). Győződj meg róla, hogy a beszerelt fúvóka megegyezik a nyomtató beállításaival, majd szeleteléskor állítsd be a megfelelő nyomtató-előbeállítást." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Tipp: Ha nemrég cseréltél fúvókát a nyomtatón, lépj az 'Eszköz -> Nyomtató alkatrészei' menübe, és módosítsd a fúvóka beállítását." @@ -8955,10 +9402,17 @@ msgstr "A jelenlegi nyomtató %s átmérője (%.1fmm) nem egyezik a szeletelési msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "A jelenlegi fúvókaátmérő (%.1fmm) nem egyezik a szeletelési fájléval (%.1fmm). Győződj meg róla, hogy a beszerelt fúvóka egyezik a nyomtatóbeállításokkal, majd szeleteléskor válaszd a megfelelő nyomtatóbeállítást." +msgid "both extruders" +msgstr "mindkét extruder" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "A jelenlegi anyag keménysége (%s) meghaladja a(z) %s (%s) keménységét. Ellenőrizd a fúvóka- vagy anyagbeállításokat, majd próbáld újra." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] magas hőmérsékletű környezetben történő nyomtatást igényel. Kérlek, csukd be az ajtót." @@ -9069,9 +9523,6 @@ msgstr "A jelenlegi firmware legfeljebb 16 anyagot támogat. Vagy csökkentsd az msgid "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." msgstr "A külső filament típusa ismeretlen, vagy nem egyezik a szeletelőfájlban szereplő filament típusával. Győződj meg arról, hogy a megfelelő filamentet helyezted be a külső orsóba." -msgid "Please refer to Wiki before use->" -msgstr "Használat előtt nézd meg a Wikit ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "A jelenlegi firmware nem támogatja a fájlátvitelt belső tárolóra." @@ -9255,6 +9706,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Kattints az összes beállítás utolsó mentett változatának visszaállításához." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "A fúvókacsere miatt szükség van a törlőtoronyra. Nélküle előfordulhatnak hibák a nyomtatott tárgyon. Biztos, hogy kikapcsolod a törlőtornyot?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "A sima időfelvétel miatt szükség van a törlőtoronyra. Nélküle előfordulhatnak hibák a nyomtatott tárgyon. Biztos, hogy kikapcsolod a törlőtornyot?" @@ -9336,9 +9790,6 @@ msgstr "Szeretnéd az értéket automatikusan a beállított tartományhoz igaz msgid "Adjust" msgstr "Módosítás" -msgid "Ignore" -msgstr "Mellőzés" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Kísérleti funkció: Filamentcsere közben nagyobb távolságon történő visszahúzás és elvágás az öblítés minimalizálása érdekében. Bár ez jelentősen csökkentheti az öblítés mértékét, növelheti a fúvóka eltömődésének vagy más nyomtatási problémák kockázatát." @@ -9840,6 +10291,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Biztos, hogy %1% a kiválasztott beállítást?" +msgid "Select printers" +msgstr "Nyomtatók kiválasztása" + +msgid "Select profiles" +msgstr "Profilok kiválasztása" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10088,6 +10545,12 @@ msgstr "Értékek átvitele balról jobbra" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Ha engedélyezve van, ez a párbeszédablak használható a kijelölt értékek bal oldali előbeállításból a jobb oldaliba való átvitelére." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Fájl hozzáadása" @@ -10343,12 +10806,8 @@ msgstr "A fúvókainformációk szinkronizálása sikerült." msgid "Successfully synchronized nozzle and AMS number information." msgstr "A fúvóka- és AMS-száminformációk szinkronizálása sikerült." -msgid "Continue to sync filaments" -msgstr "Filamentek szinkronizálásának folytatása" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Mégse" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "A filament színének szinkronizálása a nyomtatóról sikerült." @@ -10456,6 +10915,9 @@ msgstr "Bejelentkezés" msgid "Login failed. Please try again." msgstr "Sikertelen bejelentkezés. Próbáld újra." +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Művelet szükséges] " @@ -10770,6 +11232,9 @@ msgstr "Nyomtató neve" msgid "Where to find your printer's IP and Access Code?" msgstr "Hol találom a nyomtató IP címét és a hozzáférési kódot?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Csatlakozás" @@ -10834,6 +11299,9 @@ msgstr "Vágómodul" msgid "Auto Fire Extinguishing System" msgstr "Automatikus tűzoltó rendszer" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10852,6 +11320,9 @@ msgstr "A frissítés nem sikerült" msgid "Update successful" msgstr "Sikeres frissítés" +msgid "Hotends on Rack" +msgstr "Hotendek a tartón" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Biztos, hogy frissíteni akarsz? Ez körülbelül 10 percet vesz igénybe. Ne kapcsold ki a nyomtatót, amíg a frissítés tart." @@ -10961,6 +11432,9 @@ msgstr "Csoportosítási hiba: " msgid " can not be placed in the " msgstr " nem helyezhető ide: " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Belső híd" @@ -11677,7 +12151,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11691,7 +12165,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12140,9 +12614,6 @@ msgstr "" "Az éles szögek észlelése előtt a geometria egyszerűsítve lesz. Ez a paraméter a leegyszerűsítésnél figyelembe vett eltérés minimális hosszát adja meg.\n" "0 értékkel kikapcsolható." -msgid "Select printers" -msgstr "Nyomtatók kiválasztása" - msgid "upward compatible machine" msgstr "felfelé kompatibilis gép" @@ -12153,9 +12624,6 @@ msgstr "Feltétel" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Logikai kifejezés, amely egy aktív nyomtatóprofil konfigurációs értékeit használja. Ha ez a kifejezés igaz, akkor ez a profil kompatibilis az aktív nyomtatóprofillal." -msgid "Select profiles" -msgstr "Profilok kiválasztása" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Logikai kifejezés, amely egy aktív nyomtatási profil konfigurációs értékeit használja. Ha ez a kifejezés igaz, akkor ez a profil kompatibilis az aktív nyomtatási profillal." @@ -12426,6 +12894,42 @@ msgstr "Felső felületi sűrűség" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "A felső felületi réteg sűrűsége. A 100%-os érték teljesen tömör, sima felső réteget hoz létre. Ennek az értéknek a csökkentése a kiválasztott felső felületi mintázatnak megfelelően texturált felső felületet eredményez. A 0%-os érték azt eredményezi, hogy a felső rétegen csak a falak jönnek létre. Esztétikai vagy funkcionális célokra szolgál, nem pedig olyan problémák javítására, mint a túlextrudálás." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Alsó felület mintázata" @@ -12758,12 +13262,18 @@ msgstr "Automatikus öblítéshez" msgid "Auto For Match" msgstr "Automatikus egyeztetéshez" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "Öblítési hőmérséklet" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "A filament öblítésekor használt hőmérséklet. A 0 az ajánlott fúvókahőmérséklet-tartomány felső határát jelenti." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Öblítési volumetrikus sebesség" @@ -13031,6 +13541,12 @@ msgstr "Filament nyomtatható" msgid "The filament is printable in extruder." msgstr "A filament nyomtatható az extruderben." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Lágyulási hőmérséklet" @@ -13093,12 +13609,12 @@ msgstr "Kitöltés sűrűsége" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "A belső ritka kitöltés sűrűsége. A 100% minden ritka kitöltést tömör kitöltéssé alakít, és a belső tömör kitöltési minta kerül használatra." -msgid "Align infill direction to model" -msgstr "Kitöltési irány igazítása a modellhez" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13637,6 +14153,15 @@ msgstr "A legjobb automatikus elrendezés tartománya [0,1] a tárgyasztal alakj msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Engedélyezd ezt az opciót, ha a gép rendelkezik kiegészítő tárgyhűtő ventilátorral. G-kód parancs: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13711,6 +14236,12 @@ msgstr "" "Engedélyezd ezt, ha a nyomtató támogatja a légszűrést.\n" "G-kód parancs: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Hűtőszűrő használata" + +msgid "Enable this if printer support cooling filter" +msgstr "Engedélyezd a beállítást, ha a nyomtató támogatja a hűtőszűrőt" + msgid "G-code flavor" msgstr "G-kód változat" @@ -14243,6 +14774,30 @@ msgstr "Minimum mozgási sebesség" msgid "Minimum travel speed (M205 T)" msgstr "Minimum mozgási sebesség (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Az Y tengely maximális ereje" + +msgid "The allowed maximum output force of Y axis" +msgstr "Az Y tengely megengedett maximális kimeneti ereje" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Az Y tengely asztaltömege" + +msgid "The machine bed mass load of Y axis" +msgstr "Az Y tengely gépasztaltömeg-terhelése" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "A megengedett maximális nyomtatott tömeg" + +msgid "The allowed max printed mass on a plate" +msgstr "A megengedett maximális nyomtatott tömeg egy lemezen" + msgid "Maximum acceleration for extruding" msgstr "Maximális gyorsulás extrudáláshoz" @@ -14814,6 +15369,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Hibrid" + msgid "Enable filament dynamic map" msgstr "Filament dinamikus leképezés engedélyezése" @@ -14849,6 +15407,12 @@ msgstr "Betöltési sebesség" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "A filament visszatöltésének sebessége a fúvókába. A 0 ugyanazt a sebességet jelenti, mint a visszahúzásnál." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Firmware-ben megadott visszahúzás használata" @@ -14880,6 +15444,10 @@ msgstr "Igazított" msgid "Aligned back" msgstr "Hátulra igazítva" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Hátul" + msgid "Random" msgstr "Véletlenszerû" @@ -15157,6 +15725,12 @@ msgstr "Ha a sima vagy a hagyományos mód van kiválasztva, minden nyomtatásn msgid "Traditional" msgstr "Hagyományos" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Hőmérséklet változás" @@ -15244,6 +15818,18 @@ msgstr "Az összes nyomtató extruder előkészítése" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Ha engedélyezve van, akkor a nyomtatás kezdetén az összes nyomtató extruder előkészítésre kerül a tárgyasztal elülső szélénél." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Szeletelési hézag lezárási sugara" @@ -15636,7 +16222,7 @@ msgstr "" "Bekapcsolva ez a paraméter egy chamber_temperature nevű G-code változót is beállít, amely felhasználható a kívánt kamrahőmérséklet átadására a nyomtatásindító makrónak, vagy egy ilyen hőkiegyenlítő makrónak: PRINT_START (egyéb változók) CHAMBER_TEMP=[chamber_temperature]. Ez akkor lehet hasznos, ha a nyomtatód nem támogatja az M141/M191 parancsokat, vagy ha az aktív kamrafűtés hiányában a hőkiegyenlítést a nyomtatásindító makróban szeretnéd kezelni." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15691,6 +16277,45 @@ msgstr "Felső héj vastagság" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "A felső szilárd rétegek száma szeleteléskor megnő, ha a felső héjrétegekből számított vastagság kisebb ennél az értéknél. Ezzel elkerülhető, hogy túl vékony legyen a héj kis rétegmagasságnál. A 0 azt jelenti, hogy ez a beállítás ki van kapcsolva, és a felső héj vastagságát egyszerűen a felső héjrétegek száma határozza meg." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Mozgási sebesség, amikor nem történik extrudálás" @@ -15738,6 +16363,12 @@ msgstr "Öblítési szorzó" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "A tényleges öblítési mennyiségek megegyeznek az öblítési szorzó értékével, szorozva a táblázatban szereplő öblítési mennyiségekkel." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Előkészítési mennyiség" @@ -15745,6 +16376,18 @@ msgstr "Előkészítési mennyiség" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Az extruder toronyban történő előkészítéséhez szükséges anyagmennyiség." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Ez a törlőtorony szélessége." @@ -16039,6 +16682,57 @@ msgstr "Minimális falszélesség" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "A fal szélessége, amely lecseréli a modell vékony részeit (a Minimális méretben megadott érték szerint). Ha a minimális falszélesség vékonyabb, mint a nyomtatandó elem vastagsága, akkor a fal olyan vastag lesz, mint maga a nyomtatott elem. A fúvóka átmérőjének százalékában van kifejezve" +msgid "Hotend change time" +msgstr "Hotendváltás ideje" + +msgid "Time to change hotend." +msgstr "A hotendváltás ideje." + +msgid "Hotend change" +msgstr "Hotendváltás" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "A hotend cseréjekor ajánlott egy bizonyos hosszúságú filamentet extrudálni az eredeti fúvókából. Ez segít minimalizálni a fúvóka szivárgását." + +msgid "Extruder change" +msgstr "Extruderváltás" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "A szivárgás elkerülése érdekében a fúvóka a betolás befejezése után egy bizonyos ideig visszafelé mozog. A beállítás határozza meg a mozgás idejét." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "A szivárgás elkerülése érdekében a fúvóka lehűl betolás közben. Ezért a betolási időnek hosszabbnak kell lennie, mint a lehűlési időnek. A 0 kikapcsolja ezt az opciót." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "Az extruderváltás előtti betolás maximális áramlási sebessége, ahol -1 a maximális sebesség használatát jelenti." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "A szivárgás megakadályozása érdekében a fúvóka a betolás során lehűl. Megjegyzés: csak a hűtési parancs és a ventilátor bekapcsolása kerül elküldésre, a célhőmérséklet elérése nem garantált. A 0 letiltást jelent." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "A hotendváltás előtti betolás maximális áramlási sebessége, ahol -1 a maximális sebesség használatát jelenti." + +msgid "length when change hotend" +msgstr "hossz hotendcsere esetén" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Ha ezt a visszahúzási értéket módosítod, akkor ezt az értéket használja a nyomtató a filament hotend belsejéből történő visszahúzásakor, mielőtt hotendet cserélne." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Az extruder átöblítéséhez szükséges anyagmennyiség a hotend cseréjekor." + +msgid "Preheat temperature delta" +msgstr "Előmelegítési hőmérséklet delta" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Hőmérséklet-különbség alkalmazása az eszközcsere előtti előmelegítés során." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Keskeny belső szilárd kitöltések felismerése" @@ -16793,12 +17487,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibrálás nem támogatott" -msgid "Error desc" -msgstr "Hibaleírás" - -msgid "Extra info" -msgstr "Extra infó" - msgid "Flow Dynamics" msgstr "Áramlásdinamika" @@ -17005,6 +17693,12 @@ msgstr "Kérlek, add meg a nevet." msgid "The name cannot exceed 40 characters." msgstr "A név nem haladhatja meg a 40 karaktert." +msgid "Nozzle ID" +msgstr "Fúvókaazonosító" + +msgid "Standard Flow" +msgstr "Normál áramlás" + msgid "Please find the best line on your plate" msgstr "Keresd meg a legjobb vonalat a tálcán" @@ -17095,9 +17789,6 @@ msgstr "Az AMS- és fúvókainformációk szinkronizálva vannak" msgid "Nozzle Flow" msgstr "Fúvóka anyagáramlása" -msgid "Nozzle Info" -msgstr "Fúvókaadatok" - msgid "Filament position" msgstr "filamentpozíció" @@ -17172,6 +17863,10 @@ msgstr "Előzmények sikeresen lekérdezve" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Az előző anyagáramlás-dinamikai kalibrációs rekordok frissítése" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Megjegyzés: A hotend száma a tartóhoz van rendelve ezen: %s. Amikor a hotendet áthelyezed egy új tartóra, a száma automatikusan frissül." + msgid "Action" msgstr "Művelet" @@ -18918,6 +19613,12 @@ msgstr "Nyomtatás sikertelen" msgid "Removed" msgstr "Eltávolítva" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Ne emlékeztessen újra" @@ -18951,12 +19652,25 @@ msgstr "Videós útmutató" msgid "(Sync with printer)" msgstr "(Szinkronizálás a nyomtatóval)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "A szeletelés a következő csoportosítási módszer szerint történik:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Tipp: A filamenteket húzással másik fúvókához rendelheted." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Az aktuális tálca filamentcsoportosítási módját a szeletelési tálca gomb legördülő beállítása határozza meg." @@ -19188,9 +19902,6 @@ msgstr "Ez a művelet nem vonható vissza. Folytatod?" msgid "Skipping objects." msgstr "Objektumok kihagyása." -msgid "Select Filament" -msgstr "Filament kiválasztása" - msgid "Null Color" msgstr "Nincs szín" @@ -19712,6 +20423,19 @@ msgstr "" "Kunkorodás elkerülése\n" "Tudtad, hogy a kunkorodásra hajlamos anyagok (például ABS) nyomtatásakor a tárgyasztal hőmérsékletének növelése csökkentheti a kunkorodás valószínűségét?" +#~ msgid "Continue to sync filaments" +#~ msgstr "Filamentek szinkronizálásának folytatása" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Mégse" + +#~ msgid "Align infill direction to model" +#~ msgstr "Kitöltési irány igazítása a modellhez" + +#~ msgid "Print" +#~ msgstr "Nyomtatás" + #~ msgid "in" #~ msgstr "in" diff --git a/localization/i18n/it/OrcaSlicer_it.po b/localization/i18n/it/OrcaSlicer_it.po index 6aa547173a..0bdcec19a7 100644 --- a/localization/i18n/it/OrcaSlicer_it.po +++ b/localization/i18n/it/OrcaSlicer_it.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "Il TPU non è supportato dall'AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "L'AMS non supporta 'Bambu Lab PET-CF'." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Effettuare un'estrazione a freddo prima di stampare con il TPU per evitare intasamenti. È possibile utilizzare la funzione estrazione a freddo (o cold pull) della stampante." @@ -47,6 +65,9 @@ msgstr "Il PVA umido è flessibile e potrebbe bloccarsi nell'estrusore. Asciugar msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "La superficie ruvida del PLA Glow può accelerare l'usura del sistema AMS, in particolare dei componenti interni dell'AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "I filamenti CF/GF sono duri e fragili. È facile romperli o creare inceppamenti nell'AMS. Si prega di utilizzarli con cautela." @@ -56,10 +77,90 @@ msgstr "Il PPS-CF è fragile e potrebbe rompersi nel tubo in PTFE inserito sopra msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "Il PPA-CF è fragile e potrebbe rompersi nel tubo in PTFE inserito sopra il gruppo testina." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s non è supportato dall'estrusore %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Alto flusso" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "TPU Alto FLusso" + +msgid "Unknown" +msgstr "Sconosciuto" + +msgid "Hardened Steel" +msgstr "Acciaio temprato" + +msgid "Stainless Steel" +msgstr "Acciaio inossidabile" + +msgid "Tungsten Carbide" +msgstr "Carburo di tungsteno" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "La testa di stampa e il supporto hotend potrebbero muoversi. Tieni le mani lontane dalla camera." + +msgid "Warning" +msgstr "Attenzione" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Le informazioni sull'Hotend potrebbero non essere accurate. Vuoi rileggere l'Hotend? (Le informazioni sull'Hotend potrebbero cambiare durante lo spegnimento)." + +msgid "I confirm all" +msgstr "Confermo tutto" + +msgid "Re-read all" +msgstr "Rileggi tutto" + +msgid "Reading the hotends, please wait." +msgstr "Lettura degli hotend in corso, attendi." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Durante l'aggiornamento dell'hotend, la testa di stampa si muoverà. Non inserire la mano nella camera." + +msgid "Update" +msgstr "Aggiorna" + msgid "Current AMS humidity" msgstr "Umidità AMS attuale" @@ -90,6 +191,85 @@ msgstr "Versione:" msgid "Latest version" msgstr "Ultima versione" +msgid "Row A" +msgstr "Fila A" + +msgid "Row B" +msgstr "Fila B" + +msgid "Toolhead" +msgstr "Testa di stampa" + +msgid "Empty" +msgstr "Vuoto" + +msgid "Error" +msgstr "Errore" + +msgid "Induction Hotend Rack" +msgstr "Rack Hotend a Induzione" + +msgid "Hotends Info" +msgstr "Informazioni Hotend" + +msgid "Read All" +msgstr "Leggi Tutto" + +msgid "Reading " +msgstr "Lettura " + +msgid "Please wait" +msgstr "Attendi prego" + +msgid "Running..." +msgstr "In Corso..." + +msgid "Raised" +msgstr "Sollevato" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Questo hotend presenta un’anomalia ed è attualmente non disponibile. Vai su 'Dispositivo -> Aggiorna' per aggiornare il firmware." + +msgid "Abnormal Hotend" +msgstr "Hotend Anomalo" + +msgid "Refresh" +msgstr "Aggiorna" + +msgid "Refreshing" +msgstr "Aggiornamento" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Stato hotend anomalo, al momento non disponibile. Aggiorna il firmware e riprova." + +msgid "Cancel" +msgstr "Annulla" + +msgid "Jump to the upgrade page" +msgstr "Vai alla pagina dell'aggiornamento" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Versione" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Tempo Utilizzo: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "I Nozzle Dinamici sono assegnati al piatto corrente. La selezione dell’hotend non è supportata." + +msgid "Hotend Rack" +msgstr "Rack Hotend" + +msgid "ToolHead" +msgstr "Testa di stampa" + +msgid "Nozzle information needs to be read" +msgstr "È necessario leggere le informazioni sul nozzle" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Dipingi supporti" @@ -162,6 +342,12 @@ msgstr "Riempi" msgid "Gap Fill" msgstr "Riempi spazio vuoto" +msgid "Vertical" +msgstr "Verticale" + +msgid "Horizontal" +msgstr "Orizzontale" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Consente di dipingere solo sulle facce selezionate da: \"%1%\"" @@ -257,12 +443,6 @@ msgstr "Triangolo" msgid "Height Range" msgstr "Interv. altezza" -msgid "Vertical" -msgstr "Verticale" - -msgid "Horizontal" -msgstr "Orizzontale" - msgid "Remove painted color" msgstr "Rimuovi colore dipinto" @@ -327,6 +507,7 @@ msgstr "Strumento di rotazione" msgid "Optimize orientation" msgstr "Ottimizza orientamento" +msgctxt "Verb" msgid "Scale" msgstr "Ridimensiona" @@ -371,6 +552,9 @@ msgstr "Rapporti di scala" msgid "Object operations" msgstr "Operazioni sugli oggetti" +msgid "Scale" +msgstr "Ridimensiona" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Operazioni volume" @@ -422,6 +606,10 @@ msgstr "Reimposta la rotazione corrente al valore di apertura dello strumento." msgid "Reset current rotation to real zeros." msgstr "Reimposta la rotazione corrente a zero reale." +msgctxt "Noun" +msgid "Scale" +msgstr "Ridimensiona" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Dimensioni" @@ -604,9 +792,6 @@ msgstr "Proporzione di spazio in relazione al raggio" msgid "Confirm connectors" msgstr "Conferma connettori" -msgid "Cancel" -msgstr "Annulla" - msgid "Flip cut plane" msgstr "Capovolgi piano di taglio" @@ -647,12 +832,12 @@ msgstr "Taglia in parti" msgid "Reset cutting plane and remove connectors" msgstr "Ripristina il piano di taglio e rimuovi i connettori" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Effettua taglio" -msgid "Warning" -msgstr "Attenzione" - msgid "Invalid connectors detected" msgstr "Rilevati connettori non validi" @@ -683,6 +868,13 @@ msgstr "Il piano di taglio con scanalatura non è valido" msgid "Connector" msgstr "Connettore" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Taglio per piano" @@ -730,9 +922,6 @@ msgstr "Semplifica" msgid "Simplification is currently only allowed when a single part is selected" msgstr "La semplificazione è attualmente consentita solo quando è selezionata una singola parte" -msgid "Error" -msgstr "Errore" - msgid "Extra high" msgstr "Molto alto" @@ -2007,6 +2196,9 @@ msgstr "L'accesso al pacchetto %s non è autorizzato." msgid "Loading user preset" msgstr "Caricamento profili utente" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s è stato rimosso." @@ -2020,6 +2212,18 @@ msgstr "Seleziona la lingua" msgid "Language" msgstr "Lingua" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2653,6 +2857,45 @@ msgstr "Clicca sull'icona per modificare i colori dell'oggetto" msgid "Click the icon to shift this object to the bed" msgstr "Fare clic sull'icona per spostare l'oggetto sul piatto" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Caricamento file" @@ -2662,6 +2905,9 @@ msgstr "Errore!" msgid "Failed to get the model data in the current file." msgstr "Impossibile ottenere i dati del modello nel file corrente." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Generico" @@ -2674,6 +2920,12 @@ msgstr "Passa alla modalità di impostazione oggetto per modificare le impostazi msgid "Remove paint-on fuzzy skin" msgstr "Rimuovi superficie ruvida dipinta" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Rimuovi intervallo altezza" + msgid "Delete connector from object which is a part of cut" msgstr "Elimina il connettore dall'oggetto che fa parte del taglio" @@ -2704,12 +2956,24 @@ msgstr "Elimina tutti i connettori" msgid "Deleting the last solid part is not allowed." msgstr "Non è consentita l'eliminazione dell'ultima parte solida." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "L'oggetto di destinazione contiene solo una parte e non può essere suddiviso." +msgid "Split to parts" +msgstr "Dividi in parti" + msgid "Assembly" msgstr "Assemblaggio" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Informazioni sui connettori di taglio" @@ -2743,6 +3007,9 @@ msgstr "Intervalli di altezza" msgid "Settings for height range" msgstr "Impostazioni intervallo altezza" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Strato" @@ -2765,6 +3032,9 @@ msgstr "Tipo:" msgid "Choose part type" msgstr "Scegli tipo di parte" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Inserisci un nuovo nome" @@ -2792,6 +3062,9 @@ msgstr "\"%s\" supererà 1 milione di facce dopo questa suddivisione, il che pot msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "La mesh della parte \"%s\" contiene errori. Ripararla prima." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Profilo processo aggiuntivo" @@ -2801,9 +3074,6 @@ msgstr "Rimuovi parametro" msgid "to" msgstr "a" -msgid "Remove height range" -msgstr "Rimuovi intervallo altezza" - msgid "Add height range" msgstr "Aggiungi intervallo di altezza" @@ -3014,6 +3284,9 @@ msgstr "Scegliere uno slot AMS, quindi premi il pulsante \"Carica\" o \"Scarica\ msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Il tipo di filamento è sconosciuto, ma è necessario per eseguire questa azione. Impostare le informazioni del filamento di destinazione." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "La modifica della velocità della ventola durante la stampa potrebbe influire sulla qualità di stampa, scegliere con attenzione." @@ -3136,6 +3409,24 @@ msgstr "Confermare l'estrusione" msgid "Check filament location" msgstr "Controllare la posizione del filamento" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "La temperatura massima non può superare " @@ -3188,6 +3479,62 @@ msgstr "Modalità sviluppatore" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Imposta il numero di nozzle" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Errore: Impossibile impostare il numero di nozzle su zero." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Errore: il numero di nozzle non può superare %d." + +msgid "Confirm" +msgstr "Conferma" + +msgid "Extruder" +msgstr "Estrusore" + +msgid "Nozzle Selection" +msgstr "Selezione Nozzle" + +msgid "Available Nozzles" +msgstr "Nozzle disponibili" + +msgid "Nozzle Info" +msgstr "Informazioni ugello" + +msgid "Sync Nozzle status" +msgstr "Sync Nozzle" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Attenzione: L'uso di diametri nozzle differenti in una sola stampa non è supportata. Se la dimensione selezionata è disponibile solo su un estrusore, verrà forzata la stampa con un solo estrusore." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Aggiornamento %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Nozzle sconosciuto rilevato. Effettua un refresh per aggiornare le informazioni (i nozzle non aggiornati saranno esclusi durante l'elaborazione). Verifica il diametro del nozzle e il flusso rispetto ai valori mostrati." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Nozzle sconosciuto rilevato. Effettua un refresh per aggiornare (i nozzle non aggiornati verranno saltati durante l'elaborazione)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Verifica se il diametro del nozzle richiesto eil flusso corrispondono ai valori attualmente visualizzati." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "La tua stampante dispone di diversi nozzle installati. Seleziona un nozzle per questa stampa." + +msgid "Ignore" +msgstr "Ignora" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3521,15 +3868,9 @@ msgstr "OrcaSlicer è nato con lo stesso spirito, traendo ispirazione da PrusaSl msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Oggi, OrcaSlicer è il programma di sezionamento a sorgente aperta più utilizzato e attivamente sviluppato nella comunità della stampa 3D. Molte delle sue innovazioni sono state adottate da altri programmi di stampa, rendendolo un punto di riferimento per l'intero settore." -msgid "Version" -msgstr "Versione" - msgid "AMS Materials Setting" msgstr "Impostazione materiali AMS" -msgid "Confirm" -msgstr "Conferma" - msgid "Close" msgstr "Chiudi" @@ -3550,12 +3891,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "Il valore immesso deve essere maggiore di %1% e minore di %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Fattori di calibrazione della dinamica del flusso" +msgid "Wiki Guide" +msgstr "Guida Wiki" + msgid "PA Profile" msgstr "Profilo AP" @@ -3646,7 +3987,7 @@ msgstr "Calibrazione completata. Trova la linea di estrusione più uniforme sul msgid "Save" msgstr "Salva" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Posteriore" @@ -3730,6 +4071,19 @@ msgstr "Ugello destro" msgid "Nozzle" msgstr "Ugello" +msgid "Select Filament && Hotends" +msgstr "Seleziona Filamento e Hotend" + +msgid "Select Filament" +msgstr "Seleziona filamento" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "La stampa con l'attuale nozzle potrebbe generare un %0.2f g extra di scarto." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Nota: il tipo di filamento (%s) non corrisponde al tipo di filamento (%s) nel file di slicing. Se si desidera utilizzare questo slot, è possibile installare %s al posto di %s e modificare le informazioni dello slot nella pagina 'Dispositivo'." @@ -4440,9 +4794,6 @@ msgstr "Misurazione superficie" msgid "Calibrating the detection position of nozzle clumping" msgstr "Calibrazione della posizione di rilevamento degli ammassi sull'ugello" -msgid "Unknown" -msgstr "Sconosciuto" - msgid "Update successful." msgstr "Aggiornamento riuscito." @@ -4954,9 +5305,6 @@ msgstr "Imposta al valore ottimale" msgid "Regroup filament" msgstr "Raggruppa nuovamente i filamenti" -msgid "Wiki Guide" -msgstr "Guida Wiki" - msgid "up to" msgstr "fino a" @@ -4993,8 +5341,8 @@ msgstr "Scatto (mm/s)" msgid "Fan speed (%)" msgstr "Velocità ventola (%)" -msgid "Temperature (°C)" -msgstr "Temperatura (°C)" +msgid "Temperature (℃)" +msgstr "Temperatura (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Portata volumetrica (mm³/s)" @@ -5012,9 +5360,6 @@ msgstr "Cambi filamento" msgid "Options" msgstr "Opzioni" -msgid "Extruder" -msgstr "Estrusore" - msgid "Cost" msgstr "Costo" @@ -5027,6 +5372,7 @@ msgstr "Cambi testina" msgid "Color change" msgstr "Cambio colore" +msgctxt "Noun" msgid "Print" msgstr "Stampa" @@ -5190,11 +5536,15 @@ msgstr "Evitare la regione di calibrazione dell'estrusione" msgid "Align to Y axis" msgstr "Allinea all'asse Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Posteriore" + +msgctxt "Camera View" msgid "Left" msgstr "Sinistra" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Destra" @@ -5219,9 +5569,6 @@ msgstr "Disponi gli oggetti sui piatti selezionati" msgid "Split to objects" msgstr "Dividi in oggetti" -msgid "Split to parts" -msgstr "Dividi in parti" - msgid "Assembly View" msgstr "Vista di montaggio" @@ -5522,6 +5869,10 @@ msgstr "Piatto di stampa" msgid "Export G-code file" msgstr "Esporta file G-code" +msgctxt "Verb" +msgid "Print" +msgstr "Stampa" + msgid "Export plate sliced file" msgstr "Esporta il file del piatto elaborato" @@ -5695,15 +6046,6 @@ msgstr "Esporta la configurazione corrente in un file" msgid "Export" msgstr "Esporta" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Esci" @@ -5820,6 +6162,15 @@ msgstr "Vista" msgid "Preset Bundle" msgstr "Pacchetto profili" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5940,6 +6291,9 @@ msgstr "Risultato Esportazione" msgid "Select profile to load:" msgstr "Seleziona profilo da caricare:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6108,9 +6462,6 @@ msgstr "Scarica i file selezionati dalla stampante." msgid "Batch manage files." msgstr "Gestione file in gruppi." -msgid "Refresh" -msgstr "Aggiorna" - msgid "Reload file list from printer." msgstr "Ricarica l'elenco dei file dalla stampante." @@ -6423,6 +6774,9 @@ msgstr "Opzioni Stampa" msgid "Safety Options" msgstr "Opzioni di sicurezza" +msgid "Hotends" +msgstr "Hotend" + msgid "Lamp" msgstr "" @@ -6456,6 +6810,12 @@ msgstr "Quando la stampa è in pausa, il caricamento e lo scaricamento del filam msgid "Current extruder is busy changing filament." msgstr "L'estrusore corrente è occupato nel cambio filamento." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Lo slot corrente è già stato caricato." @@ -6506,9 +6866,6 @@ msgstr "Questo ha effetto solo in fase di stampa" msgid "Silent" msgstr "Silenzioso" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "Sportivo" @@ -6542,6 +6899,12 @@ msgstr "Aggiungi foto" msgid "Delete Photo" msgstr "Elimina foto" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Invia" @@ -6725,6 +7088,9 @@ msgstr "Come utilizzare la modalità Solo LAN" msgid "Don't show this dialog again" msgstr "Non mostrare più questa finestra di dialogo" +msgid "Please refer to Wiki before use->" +msgstr "Fare riferimento alla Wiki prima dell'uso ->" + msgid "3D Mouse disconnected." msgstr "Mouse 3D disconnesso." @@ -6979,27 +7345,18 @@ msgstr "Flusso" msgid "Please change the nozzle settings on the printer." msgstr "Modificare le impostazioni dell'ugello sulla stampante." -msgid "Hardened Steel" -msgstr "Acciaio temprato" - -msgid "Stainless Steel" -msgstr "Acciaio inossidabile" - -msgid "Tungsten Carbide" -msgstr "Carburo di tungsteno" - msgid "Brass" msgstr "Ottone" msgid "High flow" msgstr "Alto flusso" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Nessun link wiki disponibile per questa stampante." -msgid "Refreshing" -msgstr "Aggiornamento" - msgid "Unavailable while heating maintenance function is on." msgstr "Non disponibile mentre la funzione di manutenzione riscaldamento è attiva." @@ -7122,6 +7479,15 @@ msgstr "Cambia diametro" msgid "Configuration incompatible" msgstr "Configurazione incompatibile" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Suggerimenti" + msgid "Sync printer information" msgstr "Sincronizza informazioni stampante" @@ -7150,6 +7516,9 @@ msgstr "Clicca per modificare il profilo" msgid "Project Filaments" msgstr "Filamenti del progetto" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volumi di spurgo" @@ -7375,9 +7744,6 @@ msgstr "La stampante connessa è %s. Deve corrispondere al profilo del progetto msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Vuoi sincronizzare le informazioni della stampante e cambiare automaticamente il profilo?" -msgid "Tips" -msgstr "Suggerimenti" - msgid "The file does not contain any geometry data." msgstr "Il file non contiene dati geometrici." @@ -7428,9 +7794,21 @@ msgstr "" "Questa azione interromperà la corrispondenza tra gli oggetti tagliati.\n" "In seguito, la coerenza del modello non può essere garantita." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "L'oggetto selezionato non può essere diviso." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Disabilitare la funzione di Rilascio automatico per preservare il posizionamento sull'asse Z?\n" @@ -7457,6 +7835,9 @@ msgstr "Seleziona nuovo file" msgid "File for the replacement wasn't selected" msgstr "Il file per la sostituzione non è stato selezionato" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Seleziona la cartella da cui sostituire" @@ -7503,6 +7884,9 @@ msgstr "Impossibile ricaricare:" msgid "Error during reload" msgstr "Errore durante il ricaricamento" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Ci sono avvisi dopo aver elaborato i modelli:" @@ -8274,6 +8658,15 @@ msgstr "Cancella la mia scelta per la sincronizzazione del profilo stampante dop msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8289,16 +8682,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8579,6 +8963,9 @@ msgstr "Profili incompatibili" msgid "My Printer" msgstr "La mia stampante" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filamenti sinistri" @@ -8598,6 +8985,9 @@ msgstr "Aggiungi/Rimuovi profilo" msgid "Edit preset" msgstr "Modifica profilo" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Non specificato" @@ -8629,9 +9019,6 @@ msgstr "Seleziona/Rimuovi stampanti (profili di sistema)" msgid "Create printer" msgstr "Crea una stampante" -msgid "Empty" -msgstr "Vuoto" - msgid "Incompatible" msgstr "Non compatibile" @@ -8863,12 +9250,42 @@ msgstr "Invio completato" msgid "Error code" msgstr "Codice di errore" -msgid "High Flow" -msgstr "Alto flusso" +msgid "Error desc" +msgstr "Descrizione errore" + +msgid "Extra info" +msgstr "Ulteriori informazioni" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "L'impostazione del flusso dell'ugello di %s(%s) non corrisponde al file di slicing (%s). Assicurarsi che l'ugello installato corrisponda alle impostazioni della stampante, quindi impostare il profilo stampante corrispondente durante lo slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8932,8 +9349,38 @@ msgstr "Costa %dg di filamento e %d cambi in più rispetto al raggruppamento ott msgid "nozzle" msgstr "ugello" -msgid "both extruders" -msgstr "entrambi gli estrusori" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "L'impostazione del flusso dell'ugello di %s(%s) non corrisponde al file di slicing (%s). Assicurarsi che l'ugello installato corrisponda alle impostazioni della stampante, quindi impostare il profilo stampante corrispondente durante lo slicing." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Suggerimento: se hai cambiato l'ugello della stampante di recente, vai a 'Dispositivo -> Parti stampante' per modificare le impostazioni dell'ugello." @@ -8946,10 +9393,17 @@ msgstr "Il diametro %s (%.1fmm) della stampante corrente non corrisponde al file msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Il diametro dell'ugello corrente (%.1fmm) non corrisponde al file di slicing (%.1fmm). Assicurarsi che l'ugello installato corrisponda alle impostazioni della stampante, quindi impostare il profilo stampante corrispondente durante lo slicing." +msgid "both extruders" +msgstr "entrambi gli estrusori" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "La durezza del materiale corrente (%s) supera la durezza di %s(%s). Verificare le impostazioni dell'ugello o del materiale e riprovare." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] richiede la stampa in un ambiente ad alta temperatura. Chiudere la porta." @@ -9060,9 +9514,6 @@ msgstr "Il firmware corrente supporta un massimo di 16 materiali. È possibile r msgid "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." msgstr "Il tipo di filamento esterno è sconosciuto o non corrisponde al tipo di filamento specificato nel file di sezionamento. Assicurati di aver installato il filamento corretto nella bobina esterna." -msgid "Please refer to Wiki before use->" -msgstr "Fare riferimento alla Wiki prima dell'uso ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Il firmware corrente non supporta il trasferimento di file nella memoria interna." @@ -9246,6 +9697,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Clicca per ripristinare tutte le impostazioni dell'ultimo profilo salvato." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "La torre di spurgo è necessaria per la sostituzione del nozzle. Senza la prime tower potrebbero esserci dei difetti sul modello. Sei sicuro di voler disabilitare la torre di spurgo?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "È necessaria una torre di spurgo per la modalità timeplase fluida. Potrebbero esserci difetti sul modello senza una torre di spurgo. Sei sicuro di voler disabilitare la torre di spurgo?" @@ -9327,9 +9781,6 @@ msgstr "Regolare automaticamente l'intervallo impostato?\n" msgid "Adjust" msgstr "Regola" -msgid "Ignore" -msgstr "Ignora" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Funzionalità sperimentale: ritrazione e taglio del filamento a una distanza maggiore durante i cambi di filamento per ridurre al minimo lo spurgo. Sebbene possa ridurre notevolmente lo spurgo, può anche aumentare il rischio di intasamento degli ugelli o di altre complicazioni di stampa." @@ -9833,6 +10284,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Sei sicuro di voler %1% il preset selezionato?" +msgid "Select printers" +msgstr "Seleziona stampanti" + +msgid "Select profiles" +msgstr "Seleziona profili" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10070,6 +10527,12 @@ msgstr "Trasferimento dei valori da sinistra a destra" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Se abilitata, questa finestra può essere utilizzata per trasferire i valori selezionati dal profilo di sinistra a quello di destra." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Aggiungi file" @@ -10325,12 +10788,8 @@ msgstr "Informazioni ugello sincronizzate con successo." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Informazioni ugello e numero AMS sincronizzate con successo." -msgid "Continue to sync filaments" -msgstr "Continua la sincronizzazione dei filamenti" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Annulla" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Colore del filamento sincronizzato con successo dalla stampante." @@ -10438,6 +10897,9 @@ msgstr "Accedi" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Azione necessaria] " @@ -10752,6 +11214,9 @@ msgstr "Nome stampante" msgid "Where to find your printer's IP and Access Code?" msgstr "Dove trovo l'IP e il codice accesso della stampante?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Connetti" @@ -10816,6 +11281,9 @@ msgstr "Modulo di taglio" msgid "Auto Fire Extinguishing System" msgstr "Sistema antincendio automatico" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10834,6 +11302,9 @@ msgstr "Aggiornamento fallito" msgid "Update successful" msgstr "Aggiornamento riuscito" +msgid "Hotends on Rack" +msgstr "Hotend sul Rack" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Sei sicuro di voler aggiornare? Ci vorranno circa 10 minuti. Non spegnere l'alimentazione durante l'aggiornamento della stampante." @@ -10943,6 +11414,9 @@ msgstr "Errore di raggruppamento: " msgid " can not be placed in the " msgstr " non può essere posizionato nel " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Ponte interno" @@ -11659,7 +12133,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11673,7 +12147,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12122,9 +12596,6 @@ msgstr "" "La geometria verrà decimata prima di rilevare gli spigoli vivi. Questo parametro indica la lunghezza minima dello scostamento per la decimazione.\n" "0 per disattivare." -msgid "Select printers" -msgstr "Seleziona stampanti" - msgid "upward compatible machine" msgstr "macchina compatibile con versioni successive" @@ -12135,9 +12606,6 @@ msgstr "Condizione" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Un'espressione booleana che usa i valori di configurazione di un profilo stampante attivo. Se questa espressione produce un risultato vero, questo profilo si considera compatibile con il profilo stampante attivo." -msgid "Select profiles" -msgstr "Seleziona profili" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Un'espressione booleana che usa i valori di configurazione di un profilo di stampa attivo. Se questa espressione produce un risultato vero, questo profilo si considera compatibile con il profilo di stampa attivo." @@ -12409,6 +12877,42 @@ msgstr "Densità superficie superiore" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Densità dello strato superficiale superiore. Un valore del 100% crea uno strato superiore completamente solido e liscio. La riduzione di questo valore produce una superficie superiore texturizzata, secondo il pattern di superficie superiore scelto. Un valore dello 0% risulterà nella creazione delle sole pareti sullo strato superiore. Destinato a scopi estetici o funzionali, non per risolvere problemi come la sovraestrusione." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Motivo superficie inferiore" @@ -12741,12 +13245,18 @@ msgstr "Automatico per spurgo" msgid "Auto For Match" msgstr "Automatico per abbinamento" +msgid "Nozzle Manual" +msgstr "Manuale nozzle" + msgid "Flush temperature" msgstr "Temperatura di spurgo" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatura durante la spurga del filamento. 0 indica il limite superiore dell'intervallo di temperatura dell'ugello consigliato." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Velocità volumetrica di spurgo" @@ -13014,6 +13524,12 @@ msgstr "Filamento stampabile" msgid "The filament is printable in extruder." msgstr "Il filamento è stampabile nell'estrusore." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Temperatura di ammorbidimento" @@ -13076,12 +13592,12 @@ msgstr "Densità riempimento sparso" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Densità del riempimento sparso interno. 100% trasforma il riempimento sparso in riempimento solido e verrà utilizzato il motivo del riempimento solido interno." -msgid "Align infill direction to model" -msgstr "Allinea direzione riempimento al modello" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13619,6 +14135,15 @@ msgstr "Miglior posizionamento automatico degli oggetti nell'intervallo [0,1] ri msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Abilita questa opzione se la macchina è dotata di ventola di raffreddamento ausiliaria. Comando G-code: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13690,6 +14215,12 @@ msgstr "" "Abilita questa opzione se la stampante supporta il filtrazione dell'aria\n" "Comando G-code: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Usa filtro raffreddamento" + +msgid "Enable this if printer support cooling filter" +msgstr "Abilita questa opzione se la stampante supporta il filtro di raffreddamento." + msgid "G-code flavor" msgstr "Formato G-code" @@ -14221,6 +14752,30 @@ msgstr "Velocità minima di spostamento" msgid "Minimum travel speed (M205 T)" msgstr "Velocità minima di spostamento (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Forza massima dell'asse Y" + +msgid "The allowed maximum output force of Y axis" +msgstr "La forza di uscita massima consentita dell'asse Y" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Massa del piano lungo l'asse Y" + +msgid "The machine bed mass load of Y axis" +msgstr "Il carico di massa del piano della macchina sull'asse Y" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "La massima massa stampata consentita" + +msgid "The allowed max printed mass on a plate" +msgstr "La massima massa di stampa consentita su un piatto" + msgid "Maximum acceleration for extruding" msgstr "Accelerazione massima per l'estrusione" @@ -14788,6 +15343,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Ibrido" + msgid "Enable filament dynamic map" msgstr "" @@ -14823,6 +15381,12 @@ msgstr "Velocità di de-retrazione" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Velocità per il ricaricamento del filamento nell'ugello. Zero indica la stessa velocità della retrazione." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Usa retrazione firmware" @@ -14854,6 +15418,10 @@ msgstr "Allineato" msgid "Aligned back" msgstr "Allineato dietro" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Posteriore" + msgid "Random" msgstr "Casuale" @@ -15127,6 +15695,12 @@ msgstr "Se si seleziona la modalità fluida o tradizionale, per ogni stampa verr msgid "Traditional" msgstr "Tradizionale" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Variazione di temperatura" @@ -15214,6 +15788,18 @@ msgstr "Prepara tutti gli estrusori di stampa" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Se abilitata, tutti gli estrusori di stampa verranno preparati nel bordo frontale del piano di stampa all'inizio della stampa." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Raggio di chiusura spazi vuoti" @@ -15605,7 +16191,7 @@ msgstr "" "Se abilitato, questo parametro imposta anche una variabile G-code denominata chamber_temperature, che può essere utilizzata per passare la temperatura desiderata della camera nella macro di inizio stampa o in una macro di preriscaldamento in questo modo: PRINT_START (altre variabili) CHAMBER_TEMP=[chamber_temperature]. Questo può essere utile se la stampante non supporta i comandi M141/M191 o, se non è presente un sistema di riscaldamento della camera, si desidera gestire il preriscaldamento nella macro di inizio stampa." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15659,6 +16245,45 @@ msgstr "Spessore guscio superiore" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Il numero di strati solidi superiori viene aumentato durante l'elaborazione se lo spessore calcolato dagli strati del guscio superiore è più sottile di questo valore. In questo modo si evita di avere un guscio troppo sottile quando l'altezza degli strati è piccola. Il valore 0 indica che questa impostazione è disattivata e che lo spessore del guscio superiore è determinato in modo assoluto dagli strati del guscio superiore." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Indica la velocità di spostamento più rapida e senza estrusione." @@ -15707,6 +16332,12 @@ msgstr "Moltiplicatore spurgo" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "I volumi di spurgo effettivi sono pari al moltiplicatore di spurgo moltiplicato per i volumi di spurgo indicati nella tabella." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Volume torre di spurgo" @@ -15714,6 +16345,18 @@ msgstr "Volume torre di spurgo" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Volume materiale da usare per la torre di spurgo." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Larghezza della torre di spurgo." @@ -16006,6 +16649,57 @@ msgstr "Larghezza minima parete" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Larghezza della parete che sostituirà gli elementi sottili (in base alla dimensione minima degli elementi) del modello. Se la larghezza minima della parete è più sottile dello spessore dell'elemento, la parete diventerà spessa quanto l'elemento stesso. Questo valore è espresso come percentuale rispetto al diametro dell'ugello." +msgid "Hotend change time" +msgstr "Tempo cambio Hotend" + +msgid "Time to change hotend." +msgstr "È ora di sostituire l'hotend." + +msgid "Hotend change" +msgstr "Cambio Hotend" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Quando si cambia l'hotend, è consigliato estrudere una certa lunghezza di filamento dall nozzle originale. Questo aiuta a ridurre al minimo la trasudazione dal nozzle." + +msgid "Extruder change" +msgstr "Cambio dell'estrusore" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Per evitare trasudamento, il nozzle eseguirà un movimento con percorso inverso per un certo periodo dopo il completamento della battuta. L'impostazione definisce il tempo di percorrenza." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Per evitare fuoriuscite di materiale, la temperatura del nozzle verrà abbassata durante il ramming. Pertanto, il tempo di ramming deve essere superiore al tempo di raffreddamento. 0 indica che la funzione è disattivata." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "La velocità volumetrica massima per l'urto prima del cambio dell'estrusore, dove -1 indica l'utilizzo della velocità volumetrica massima." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Per prevenire la trasudazione, la temperatura del nozzle verrà raffreddata durante la pressatura. Nota: viene attivato solo un comando di raffreddamento e la ventola, non è garantito il raggiungimento della temperatura target. 0 significa disabilitato." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "La velocità volumetrica massima per l'urto prima di una sostituzione del Hotend, dove -1 indica l'utilizzo della velocità volumetrica massima." + +msgid "length when change hotend" +msgstr "lunghezza quando si cambia hotend" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Quando questo valore di retrazione viene modificato, verrà utilizzato come quantità di filamento retratto all'interno del hotend prima di cambiare hotend." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Volume di materiale necessario per innescare l'estrusore in vista di una sostituzione dell'hotend sulla torre." + +msgid "Preheat temperature delta" +msgstr "Differenza di temperatura di preriscaldamento" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Differenza di temperatura applicata durante il preriscaldamento prima del cambio utensile." + msgid "Detect narrow internal solid infills" msgstr "Rileva riempimento solido interno su piccole aree" @@ -16759,12 +17453,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Calibrazione non supportata" -msgid "Error desc" -msgstr "Descrizione errore" - -msgid "Extra info" -msgstr "Ulteriori informazioni" - msgid "Flow Dynamics" msgstr "Dinamica del flusso" @@ -16971,6 +17659,12 @@ msgstr "Immettere il nome che si desidera salvare nella stampante." msgid "The name cannot exceed 40 characters." msgstr "Il nome non può superare i 40 caratteri." +msgid "Nozzle ID" +msgstr "ID Nozzle" + +msgid "Standard Flow" +msgstr "Flusso standard" + msgid "Please find the best line on your plate" msgstr "Trova la linea migliore nel tuo piatto" @@ -17061,9 +17755,6 @@ msgstr "Le informazioni AMS e ugello sono sincronizzate" msgid "Nozzle Flow" msgstr "Flusso ugello" -msgid "Nozzle Info" -msgstr "Informazioni ugello" - msgid "Filament position" msgstr "Posizione del filamento" @@ -17138,6 +17829,10 @@ msgstr "Risultato della cronologia ottenuto con successo" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Aggiornamento della cronologia dei dati di calibrazione della dinamica del flusso" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Nota: Il numero del hotend su %s è collegato al supporto. Quando un hotend viene spostato su un nuovo supporto, il suo numero verrà aggiornato automaticamente." + msgid "Action" msgstr "Azione" @@ -18900,6 +19595,12 @@ msgstr "Stampa non riuscita" msgid "Removed" msgstr "Rimosso" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Non ricordarmelo più" @@ -18933,12 +19634,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "(Sincronizza con stampante)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Lo slicing verrà eseguito secondo questo metodo di raggruppamento:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Suggerimento: puoi trascinare i filamenti per riassegnarli a ugelli diversi." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Il metodo di raggruppamento dei filamenti per la piastra corrente è determinato dall'opzione a discesa nel pulsante di slicing della piastra." @@ -19171,9 +19885,6 @@ msgstr "Questa azione non può essere annullata. Continuare?" msgid "Skipping objects." msgstr "Salto degli oggetti." -msgid "Select Filament" -msgstr "Seleziona filamento" - msgid "Null Color" msgstr "Nessun colore" @@ -19692,6 +20403,19 @@ msgstr "" "Evita le deformazioni\n" "Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?" +#~ msgid "Continue to sync filaments" +#~ msgstr "Continua la sincronizzazione dei filamenti" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Annulla" + +#~ msgid "Align infill direction to model" +#~ msgstr "Allinea direzione riempimento al modello" + +#~ msgid "Print" +#~ msgstr "Stampa" + #~ msgid "in" #~ msgstr "in" @@ -20492,9 +21216,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Impossibile iniziare senza scheda SD." -#~ msgid "Update" -#~ msgstr "Aggiorna" - #~ msgid "Sensitivity of pausing is" #~ msgstr "La sensibilità della pausa è" @@ -21208,10 +21929,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Deseleziona" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Ridimensiona" - #~ msgid "Lift Z Enforcement" #~ msgstr "Applicazione dell'ascensore Z" diff --git a/localization/i18n/ja/OrcaSlicer_ja.po b/localization/i18n/ja/OrcaSlicer_ja.po index 3faef352c0..df0dc9dc7a 100644 --- a/localization/i18n/ja/OrcaSlicer_ja.po +++ b/localization/i18n/ja/OrcaSlicer_ja.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPUはAMSではサポートされていません。" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMSは「Bambu Lab PET-CF」をサポートしていません。" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "TPU印刷前にコールドプルを行ってください。プリンターのコールドプルメンテナンス機能を使用できます。" @@ -47,6 +65,9 @@ msgstr "湿ったPVAは柔らかくエクストルーダーに詰まる可能性 msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "PLA Glowの粗い表面はAMSシステム、特にAMS Liteの内部部品の摩耗を早める可能性があります。" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GFフィラメントは硬く脆いため、AMS内で折れたり詰まったりしやすいです。注意してご使用ください。" @@ -56,10 +77,90 @@ msgstr "PPS-CFは脆く、ツールヘッド上部の曲がったPTFEチュー msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CFは脆く、ツールヘッド上部の曲がったPTFEチューブ内で折れる可能性があります。" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%sは%sエクストルーダーでサポートされていません。" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "ハイフロー" + +msgid "Standard" +msgstr "標準" + +msgid "TPU High Flow" +msgstr "TPUハイフロー" + +msgid "Unknown" +msgstr "不明" + +msgid "Hardened Steel" +msgstr "焼入れ鋼" + +msgid "Stainless Steel" +msgstr "ステンレス鋼" + +msgid "Tungsten Carbide" +msgstr "タングステンカーバイド" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "ツールヘッドおよびホットエンドラックが動く可能性があります。チャンバー内に手を入れないでください。" + +msgid "Warning" +msgstr "警告" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "ホットエンドの情報が正確でない可能性があります。再読み込みしますか?(電源オフ時に情報が変更される場合があります)" + +msgid "I confirm all" +msgstr "すべて確認しました" + +msgid "Re-read all" +msgstr "すべて再読み込み" + +msgid "Reading the hotends, please wait." +msgstr "ホットエンドを読み取り中です。しばらくお待ちください。" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "ホットエンドのアップグレード中にツールヘッドが動きます。チャンバー内に手を入れないでください。" + +msgid "Update" +msgstr "更新" + msgid "Current AMS humidity" msgstr "現在のAMS湿度" @@ -90,6 +191,85 @@ msgstr "バージョン" msgid "Latest version" msgstr "最新バージョン" +msgid "Row A" +msgstr "A列" + +msgid "Row B" +msgstr "B列" + +msgid "Toolhead" +msgstr "ツールヘッド" + +msgid "Empty" +msgstr "空" + +msgid "Error" +msgstr "エラー" + +msgid "Induction Hotend Rack" +msgstr "誘導式ホットエンドラック" + +msgid "Hotends Info" +msgstr "ホットエンド情報" + +msgid "Read All" +msgstr "すべて読み取り" + +msgid "Reading " +msgstr "読み取り中" + +msgid "Please wait" +msgstr "お待ちください" + +msgid "Running..." +msgstr "実行中..." + +msgid "Raised" +msgstr "上昇した" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "ホットエンドが異常な状態のため、現在使用できません。「デバイス -> アップグレード」からファームウェアをアップデートしてください。" + +msgid "Abnormal Hotend" +msgstr "異常なホットエンド" + +msgid "Refresh" +msgstr "再読込" + +msgid "Refreshing" +msgstr "更新中" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "ホットエンドの状態が異常のため、現在使用できません。ファームウェアを更新してから再度お試しください。" + +msgid "Cancel" +msgstr "取消し" + +msgid "Jump to the upgrade page" +msgstr "アップグレードページに移動" + +msgid "SN" +msgstr "シリアル番号" + +msgid "Version" +msgstr "バージョン" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "使用時間: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "現在のプレートではダイナミックノズルが割り当てられています。ホットエンドの手動選択はできません。" + +msgid "Hotend Rack" +msgstr "ホットエンドラック" + +msgid "ToolHead" +msgstr "ツールヘッド" + +msgid "Nozzle information needs to be read" +msgstr "ノズル情報を読み取る必要があります" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "サポートペイント" @@ -162,6 +342,12 @@ msgstr "塗りつぶし" msgid "Gap Fill" msgstr "隙間充填" +msgid "Vertical" +msgstr "垂直" + +msgid "Horizontal" +msgstr "水平" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "%1%で選択した面だけをペイントする" @@ -257,12 +443,6 @@ msgstr "三角形" msgid "Height Range" msgstr "高さ範囲" -msgid "Vertical" -msgstr "垂直" - -msgid "Horizontal" -msgstr "水平" - msgid "Remove painted color" msgstr "塗った色を消去" @@ -327,6 +507,7 @@ msgstr "ギズモ-回転" msgid "Optimize orientation" msgstr "向きを最適化" +msgctxt "Verb" msgid "Scale" msgstr "スケール" @@ -371,6 +552,9 @@ msgstr "倍率" msgid "Object operations" msgstr "オブジェクト操作" +msgid "Scale" +msgstr "スケール" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "操作" @@ -422,6 +606,10 @@ msgstr "回転ツールを開いた時の値にリセットします。" msgid "Reset current rotation to real zeros." msgstr "現在の回転を0にリセットします。" +msgctxt "Noun" +msgid "Scale" +msgstr "スケール" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "サイズ" @@ -604,9 +792,6 @@ msgstr "半径に関係する空間の割合" msgid "Confirm connectors" msgstr "コネクタを確認" -msgid "Cancel" -msgstr "取消し" - msgid "Flip cut plane" msgstr "カット面の反転" @@ -647,12 +832,12 @@ msgstr "パーツに割り切る" msgid "Reset cutting plane and remove connectors" msgstr "カット面をリセットし、コネクターを削除" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "カットを実行" -msgid "Warning" -msgstr "警告" - msgid "Invalid connectors detected" msgstr "無効なコネクタが検出されました" @@ -681,6 +866,13 @@ msgstr "溝のあるカット面は無効" msgid "Connector" msgstr "コネクタ" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "面でカット" @@ -728,9 +920,6 @@ msgstr "簡略化" msgid "Simplification is currently only allowed when a single part is selected" msgstr "簡略化は 1 つのパーツのみに使用できます" -msgid "Error" -msgstr "エラー" - msgid "Extra high" msgstr "超高い" @@ -2001,6 +2190,9 @@ msgstr "" msgid "Loading user preset" msgstr "ユーザープリセットを読込み中" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2014,6 +2206,18 @@ msgstr "言語を選択" msgid "Language" msgstr "言語" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2644,6 +2848,45 @@ msgstr "オブジェクトに色塗りをします" msgid "Click the icon to shift this object to the bed" msgstr "アイコンをクリックしてオブジェクトをベッドに移動" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "ファイルを読み込み中" @@ -2653,6 +2896,9 @@ msgstr "エラー!" msgid "Failed to get the model data in the current file." msgstr "現在のファイルのモデルデータの取得に失敗しました。" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "一般" @@ -2665,6 +2911,12 @@ msgstr "オブジェクト設定で、各オブジェクトの造形設定を指 msgid "Remove paint-on fuzzy skin" msgstr "ペイントファジースキンを削除" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "高さ範囲を削除" + msgid "Delete connector from object which is a part of cut" msgstr "カットの一部であるオブジェクトからコネクタを削除" @@ -2695,12 +2947,24 @@ msgstr "全てのコネクターを削除" msgid "Deleting the last solid part is not allowed." msgstr "最後のソリッドパーツは削除できません。" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "対象のオブジェクトにはパーツが1つしかなく、分割できません。" +msgid "Split to parts" +msgstr "パーツに分割" + msgid "Assembly" msgstr "アセンブリ" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "カットコネクタ情報" @@ -2734,6 +2998,9 @@ msgstr "高さ範囲" msgid "Settings for height range" msgstr "高さ範囲の設定" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "積層" @@ -2756,6 +3023,9 @@ msgstr "タイプ" msgid "Choose part type" msgstr "パーツタイプを選択" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "新しい名前を入力" @@ -2781,6 +3051,9 @@ msgstr "\"%s\"はこのサブディビジョン後に100万面を超え、スラ msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "\"%s\"パーツのメッシュにエラーがあります。まず修復してください。" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "他のプリセット" @@ -2790,9 +3063,6 @@ msgstr "パラメータを削除" msgid "to" msgstr "→" -msgid "Remove height range" -msgstr "高さ範囲を削除" - msgid "Add height range" msgstr "高さ範囲を追加" @@ -3004,6 +3274,9 @@ msgstr "AMSスロットを選択し、「ロード」または「アンロード msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "この操作に必要なフィラメントタイプが不明です。対象のフィラメント情報を設定してください。" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "印刷中のファン速度変更は印刷品質に影響する可能性があります。慎重に選択してください。" @@ -3126,6 +3399,24 @@ msgstr "押出を確認" msgid "Check filament location" msgstr "フィラメント位置を確認" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "最高温度は次の値を超えることはできません " @@ -3179,6 +3470,62 @@ msgstr "開発者モード" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "ノズル数を設定してください" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "エラー:両方のノズル数を0に設定することはできません。" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "エラー:ノズル数は%dを超えることはできません。" + +msgid "Confirm" +msgstr "確認" + +msgid "Extruder" +msgstr "押出機" + +msgid "Nozzle Selection" +msgstr "ノズル選択" + +msgid "Available Nozzles" +msgstr "利用可能なノズル" + +msgid "Nozzle Info" +msgstr "ノズル情報" + +msgid "Sync Nozzle status" +msgstr "ノズル状態を同期" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "注意:1つの造形でノズル径の混在はサポートされていません。選択したサイズが片方の押出機にしかない場合は、単一押出機での造形が強制されます。" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "更新中 %d/%d…" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "不明なノズルが検出されました。情報を更新してください(更新されていないノズルはスライス時に除外されます)。ノズル径と流量が表示と一致しているかご確認ください。" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "不明なノズルが検出されました。情報を更新してください(未更新のノズルはスライスから除外されます)。" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "必要なノズル径と流量が、現在表示されている値と一致しているかご確認ください。" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "プリンターには異なるノズルが取り付けられています。この造形に使用するノズルを選択してください。" + +msgid "Ignore" +msgstr "無視" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3506,15 +3853,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "バージョン" - msgid "AMS Materials Setting" msgstr "AMS素材設定" -msgid "Confirm" -msgstr "確認" - msgid "Close" msgstr "閉じる" @@ -3533,12 +3874,12 @@ msgstr "最小" msgid "The input value should be greater than %1% and less than %2%" msgstr "入力値範囲は %1% ~ %2%" -msgid "SN" -msgstr "シリアル番号" - msgid "Factors of Flow Dynamics Calibration" msgstr "フローダイナミクスキャリブレーションの係数" +msgid "Wiki Guide" +msgstr "Wikiガイド" + msgid "PA Profile" msgstr "PAプロファイル" @@ -3629,7 +3970,7 @@ msgstr "キャリブレーションが完了しました。下の写真のよう msgid "Save" msgstr "保存" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "背面" @@ -3713,6 +4054,19 @@ msgstr "右ノズル" msgid "Nozzle" msgstr "ノズル" +msgid "Select Filament && Hotends" +msgstr "フィラメントとホットエンドを選択" + +msgid "Select Filament" +msgstr "フィラメントを選択" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "現在のノズルで造形すると、約%0.2fgのフィラメントが無駄になる可能性があります。" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "注意: フィラメントタイプ(%s)がスライスファイルのフィラメントタイプ(%s)と一致しません。このスロットを使用する場合は、%sの代わりに%sをインストールし、「デバイス」ページでスロット情報を変更してください。" @@ -4414,9 +4768,6 @@ msgstr "表面の測定中" msgid "Calibrating the detection position of nozzle clumping" msgstr "ノズルクランピング検出位置のキャリブレーション中" -msgid "Unknown" -msgstr "不明" - msgid "Update successful." msgstr "更新は完了しました。" @@ -4927,9 +5278,6 @@ msgstr "最適に設定" msgid "Regroup filament" msgstr "フィラメントを再グルーピング" -msgid "Wiki Guide" -msgstr "Wikiガイド" - msgid "up to" msgstr "最大" @@ -4966,7 +5314,7 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "ファン回転速度 (%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "温度 (℃)" msgid "Volumetric flow rate (mm³/s)" @@ -4985,9 +5333,6 @@ msgstr "フィラメント交換" msgid "Options" msgstr "オプション" -msgid "Extruder" -msgstr "押出機" - msgid "Cost" msgstr "コスト" @@ -5000,6 +5345,7 @@ msgstr "ツールチェンジ" msgid "Color change" msgstr "色変更" +msgctxt "Noun" msgid "Print" msgstr "造形する" @@ -5163,11 +5509,15 @@ msgstr "押出しキャリブレーション領域を避ける" msgid "Align to Y axis" msgstr "Y軸に整列" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "背面" + +msgctxt "Camera View" msgid "Left" msgstr "左" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "右" @@ -5192,9 +5542,6 @@ msgstr "選択したプレートをレイアウト" msgid "Split to objects" msgstr "オブジェクトに分割" -msgid "Split to parts" -msgstr "パーツに分割" - msgid "Assembly View" msgstr "組立て" @@ -5489,6 +5836,10 @@ msgstr "造形開始" msgid "Export G-code file" msgstr "G-codeをエクスポート" +msgctxt "Verb" +msgid "Print" +msgstr "造形する" + msgid "Export plate sliced file" msgstr "エクスポート" @@ -5662,15 +6013,6 @@ msgstr "現在の構成をエクスポート" msgid "Export" msgstr "エクスポート" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "終了" @@ -5787,6 +6129,15 @@ msgstr "表示" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5906,6 +6257,9 @@ msgstr "エクスポート結果" msgid "Select profile to load:" msgstr "プロファイルを選択" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6065,9 +6419,6 @@ msgstr "プリンターから選択したファイルをダウンロード" msgid "Batch manage files." msgstr "ファイルのバッチ処理" -msgid "Refresh" -msgstr "再読込" - msgid "Reload file list from printer." msgstr "プリンターからファイルリストを再読み込み。" @@ -6379,6 +6730,9 @@ msgstr "造型オプション" msgid "Safety Options" msgstr "安全オプション" +msgid "Hotends" +msgstr "ホットエンド" + msgid "Lamp" msgstr "照明" @@ -6412,6 +6766,12 @@ msgstr "印刷が一時停止中の場合、フィラメントのロード/ア msgid "Current extruder is busy changing filament." msgstr "現在のエクストルーダーはフィラメント交換中です。" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "現在のスロットは既にロードされています。" @@ -6462,9 +6822,6 @@ msgstr "造形時の設定" msgid "Silent" msgstr "サイレント" -msgid "Standard" -msgstr "標準" - msgid "Sport" msgstr "スポーツ" @@ -6498,6 +6855,12 @@ msgstr "写真を追加" msgid "Delete Photo" msgstr "写真を削除" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "送信" @@ -6682,6 +7045,9 @@ msgstr "LANのみモードの使い方" msgid "Don't show this dialog again" msgstr "このダイアログを再度表示しない" +msgid "Please refer to Wiki before use->" +msgstr "使用前にWikiを参照してください->" + msgid "3D Mouse disconnected." msgstr "3D Mouseが切断されました。" @@ -6932,27 +7298,18 @@ msgstr "フロー" msgid "Please change the nozzle settings on the printer." msgstr "プリンターのノズル設定を変更してください。" -msgid "Hardened Steel" -msgstr "焼入れ鋼" - -msgid "Stainless Steel" -msgstr "ステンレス鋼" - -msgid "Tungsten Carbide" -msgstr "タングステンカーバイド" - msgid "Brass" msgstr "真鍮" msgid "High flow" msgstr "ハイフロー" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "このプリンターのWikiリンクはありません。" -msgid "Refreshing" -msgstr "更新中" - msgid "Unavailable while heating maintenance function is on." msgstr "加熱メンテナンス機能がオンの間は使用できません。" @@ -7075,6 +7432,15 @@ msgstr "直径を切り替え" msgid "Configuration incompatible" msgstr "構成ファイルは互換性がありません" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "ヒント" + msgid "Sync printer information" msgstr "プリンター情報を同期" @@ -7103,6 +7469,9 @@ msgstr "プリセットを編集" msgid "Project Filaments" msgstr "プロジェクトフィラメント" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "フラッシュ量" @@ -7332,9 +7701,6 @@ msgstr "接続されたプリンターは%sです。印刷にはプロジェク msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "プリンター情報を同期してプリセットを自動的に切り替えますか?" -msgid "Tips" -msgstr "ヒント" - msgid "The file does not contain any geometry data." msgstr "このファイルにはジオメトリデータが含まれていません。" @@ -7385,9 +7751,21 @@ msgstr "" "この操作はカット対応を壊します。\n" "その後、モデルの一貫性は保証されません。" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "選択したオブジェクトを分割できませんでした。" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7414,6 +7792,9 @@ msgstr "ファイルを選択" msgid "File for the replacement wasn't selected" msgstr "交換用のファイルが選択されていません" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "置換するフォルダを選択" @@ -7460,6 +7841,9 @@ msgstr "再読み込みできません:" msgid "Error during reload" msgstr "再読み込み中のエラー" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "スライスの警告:" @@ -8232,6 +8616,15 @@ msgstr "ファイルロード後のプリンタープリセット同期の選択 msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8247,16 +8640,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8540,6 +8924,9 @@ msgstr "互換性の無い プリセット" msgid "My Printer" msgstr "マイプリンター" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "左フィラメント" @@ -8559,6 +8946,9 @@ msgstr "プリセットの追加/削除" msgid "Edit preset" msgstr "プリセットを編集" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "未指定" @@ -8590,9 +8980,6 @@ msgstr "プリンターの選択/削除(システムプリセット)" msgid "Create printer" msgstr "プリンターを作成" -msgid "Empty" -msgstr "空" - msgid "Incompatible" msgstr "互換性なし" @@ -8824,12 +9211,42 @@ msgstr "送信完了" msgid "Error code" msgstr "エラーコード" -msgid "High Flow" -msgstr "ハイフロー" +msgid "Error desc" +msgstr "エラー詳細" + +msgid "Extra info" +msgstr "追加情報" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s(%s)のノズルフロー設定がスライスファイル(%s)と一致しません。インストールされているノズルがプリンターの設定と一致していることを確認し、スライス時に対応するプリンタープリセットを設定してください。" +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8893,8 +9310,38 @@ msgstr "最適なグルーピングより%dgのフィラメントと%d回の変 msgid "nozzle" msgstr "ノズル" -msgid "both extruders" -msgstr "両方のエクストルーダー" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s(%s)のノズルフロー設定がスライスファイル(%s)と一致しません。インストールされているノズルがプリンターの設定と一致していることを確認し、スライス時に対応するプリンタープリセットを設定してください。" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "ヒント: 最近プリンターのノズルを交換した場合は、「デバイス -> プリンターパーツ」でノズル設定を変更してください。" @@ -8907,10 +9354,17 @@ msgstr "現在のプリンターの%s径(%.1fmm)がスライスファイル(%.1f msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "現在のノズル径(%.1fmm)がスライスファイル(%.1fmm)と一致しません。インストールされているノズルがプリンターの設定と一致していることを確認し、スライス時に対応するプリンタープリセットを設定してください。" +msgid "both extruders" +msgstr "両方のエクストルーダー" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "現在の材料(%s)の硬度が%s(%s)の硬度を超えています。ノズルまたは材料の設定を確認して再試行してください。" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ]は高温環境での印刷が必要です。ドアを閉めてください。" @@ -9021,9 +9475,6 @@ msgstr "現在のファームウェアは最大16種類の材料をサポート msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "使用前にWikiを参照してください->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "現在のファームウェアは内部ストレージへのファイル転送をサポートしていません。" @@ -9207,6 +9658,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "全ての変更をリセットします" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "ノズルの切り替えにはプライムタワーが必要です。無効にするとモデルに欠陥が生じる可能性があります。本当にプライムタワーを無効にしますか?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "スムーズタイムラプスビデオを作成するにはプライムタワーが必要です。プライムタワーを有効にしますか?" @@ -9288,9 +9742,6 @@ msgstr "設定範囲に自動調整しますか?\n" msgid "Adjust" msgstr "調整" -msgid "Ignore" -msgstr "無視" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "実験的機能: フィラメント交換時により長い距離でフィラメントをリトラクト・カットしてフラッシュを最小化します。フラッシュを大幅に削減できますが、ノズル詰まりやその他の印刷問題のリスクが高まる可能性もあります。" @@ -9782,6 +10233,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "選択したプリセットを %1% しますか?" +msgid "Select printers" +msgstr "プリンターを選択" + +msgid "Select profiles" +msgstr "プロファイルを選択" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10003,6 +10460,12 @@ msgstr "左から右へ値を移す" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "有効にすると、このダイアログで左から右のプリセットに選択した値を転送できます。" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "ファイルを追加" @@ -10258,12 +10721,8 @@ msgstr "ノズル情報の同期に成功しました。" msgid "Successfully synchronized nozzle and AMS number information." msgstr "ノズルとAMS数の情報の同期に成功しました。" -msgid "Continue to sync filaments" -msgstr "フィラメントの同期を続行" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "キャンセル" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "プリンターからフィラメントの色を正常に同期しました。" @@ -10371,6 +10830,9 @@ msgstr "サインイン" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "【対応が必要】 " @@ -10685,6 +11147,9 @@ msgstr "プリンター名" msgid "Where to find your printer's IP and Access Code?" msgstr "どこでプリンターのIPアドレスとアクセスコードを確認できますか?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "接続" @@ -10749,6 +11214,9 @@ msgstr "カッティングモジュール" msgid "Auto Fire Extinguishing System" msgstr "自動消火システム" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10767,6 +11235,9 @@ msgstr "更新は失敗しました" msgid "Update successful" msgstr "更新は成功しました" +msgid "Hotends on Rack" +msgstr "ラック上のホットエンド" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "更新してもよろしいでしょうか?約 10 分ほどかかります。更新中に、プリンターの電源を切らないでください。" @@ -10873,6 +11344,9 @@ msgstr "グルーピングエラー: " msgid " can not be placed in the " msgstr " に配置できません " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "内部ブリッジ" @@ -11556,7 +12030,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11570,7 +12044,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11956,9 +12430,6 @@ msgid "" "0 to deactivate." msgstr "" -msgid "Select printers" -msgstr "プリンターを選択" - msgid "upward compatible machine" msgstr "互換性のあるデバイス" @@ -11969,9 +12440,6 @@ msgstr "条件" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "アクティブなプリンタープロファイルの構成値を使った論理式です。 この論理式が真の場合、このプロファイルはアクティブなプリンタープロファイルと互換性があると見なされます。" -msgid "Select profiles" -msgstr "プロファイルを選択" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "アクティブなプリントプロファイルの構成値を使用する論理式。 この式の結果がtrueの場合、このプロファイルはアクティブなプリントプロファイルと互換性があるとみなされます。" @@ -12214,6 +12682,42 @@ msgstr "上面密度" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "底面パターン" @@ -12511,12 +13015,18 @@ msgstr "フラッシュ用自動" msgid "Auto For Match" msgstr "マッチ用自動" +msgid "Nozzle Manual" +msgstr "ノズルマニュアル" + msgid "Flush temperature" msgstr "フラッシュ温度" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "フィラメントフラッシュ時の温度。0は推奨ノズル温度範囲の上限を示します。" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "フラッシュ体積速度" @@ -12776,6 +13286,12 @@ msgstr "フィラメント印刷可能" msgid "The filament is printable in extruder." msgstr "このフィラメントはエクストルーダーで印刷可能です。" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "軟化温度" @@ -12837,12 +13353,12 @@ msgstr "充填密度" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "" -msgid "Align infill direction to model" -msgstr "インフィル方向をモデルに合わせる" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13344,6 +13860,15 @@ msgstr "ベッド形状に対する最適な自動配置位置(範囲 [0,1]) msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13404,6 +13929,12 @@ msgid "" "G-code command: M106 P3 S(0-255)" msgstr "" +msgid "Use cooling filter" +msgstr "冷却フィルターを使用" + +msgid "Enable this if printer support cooling filter" +msgstr "プリンターが冷却フィルターに対応している場合は有効にする" + msgid "G-code flavor" msgstr "G-codeスタイル" @@ -13915,6 +14446,30 @@ msgstr "最小移動速度" msgid "Minimum travel speed (M205 T)" msgstr "最小移動速度(M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Y軸の最大力" + +msgid "The allowed maximum output force of Y axis" +msgstr "Y軸の許容最大出力" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Y軸のベッド質量" + +msgid "The machine bed mass load of Y axis" +msgstr "Y軸のマシンベッド質量" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "印刷可能な最大質量" + +msgid "The allowed max printed mass on a plate" +msgstr "プレートに印刷できる最大質量" + msgid "Maximum acceleration for extruding" msgstr "押出最大加速度" @@ -14436,6 +14991,9 @@ msgstr "ダイレクトドライブ" msgid "Bowden" msgstr "ボーデン" +msgid "Hybrid" +msgstr "ハイブリッド" + msgid "Enable filament dynamic map" msgstr "" @@ -14471,6 +15029,12 @@ msgstr "復帰速度" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "ファームウェアリトラクションを使用" @@ -14502,6 +15066,10 @@ msgstr "整列" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "背面" + msgid "Random" msgstr "ランダム" @@ -14757,6 +15325,12 @@ msgstr "有効にした場合、タイムラプスビデオを録画します。 msgid "Traditional" msgstr "通常" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "軟化温度" @@ -14844,6 +15418,18 @@ msgstr "全てのエクストルーダーでプライムを実施" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "有効にすると、すべてのプリントエクストルーダーは、プリント開始時にプリントベッドの前端で準備されます。" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "隙間充填半径" @@ -15217,7 +15803,7 @@ msgid "" msgstr "" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15272,6 +15858,45 @@ msgstr "トップ面厚さ" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "トップ面の厚さです、トップ面層数で決まった厚みがこの値より小さい場合、層数を増やします。この値が0にする場合、この設定が無効となり、設定した層数で造形します。" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "移動完了時の速度です。" @@ -15314,6 +15939,12 @@ msgstr "フラッシュ倍率" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "実フラッシュ量 = マルチプライヤー × フラッシュ量" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "プライム量" @@ -15321,6 +15952,18 @@ msgstr "プライム量" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "フィラメントのフラッシュ量です。" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "プライムタワーの幅です。" @@ -15591,6 +16234,57 @@ msgstr "最小壁幅" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "" +msgid "Hotend change time" +msgstr "ホットエンド交換時間" + +msgid "Time to change hotend." +msgstr "ホットエンドの切り替えにかかる時間です。" + +msgid "Hotend change" +msgstr "ホットエンドの変更" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "ホットエンドを切り替える際、元のノズルから一定量のフィラメントを押し出すことを推奨します。これにより、ノズルの垂れを最小限に抑えられます。" + +msgid "Extruder change" +msgstr "押出機の変更" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "糸引きを防ぐために、ラム動作の完了後にノズルが一定時間逆方向へ移動します。この設定では、その移動時間を定義します。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "糸引きを防ぐため、ラム動作中にノズル温度が冷却されます。そのため、ラム動作時間は冷却時間より長く設定する必要があります。0を指定すると、この機能は無効になります。" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "押出機切り替え前のラミングにおける最大体積流量です。-1 を設定すると、最大体積流量が使用されます。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "ノズルの垂れを防ぐため、ラミング中にノズル温度を冷却します。注:冷却指示とファンの作動のみが行われ、目標温度に達することは保証されません。0を設定すると無効になります。" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "ホットエンド変更前のラミングにおける最大体積流量です。-1 を設定すると、最大体積流量が使用されます。" + +msgid "length when change hotend" +msgstr "ノズル切替時のリトラクト長さ" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "このリトラクション値を変更すると、ホットエンドを切り替える前にノズル内で引き戻すフィラメントの長さとして使用されます。" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "ホットエンド変更を伴う場合に、プライムタワー上で押出機を初期化するために必要な材料量です。" + +msgid "Preheat temperature delta" +msgstr "予熱温度差" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "工具交換前の予熱中に適用される温度差。" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "薄いソリッド インフィル検出" @@ -16342,12 +17036,6 @@ msgstr "" msgid "Calibration not supported" msgstr "キャリブレーションは対応していません。" -msgid "Error desc" -msgstr "エラー詳細" - -msgid "Extra info" -msgstr "追加情報" - msgid "Flow Dynamics" msgstr "動的流量" @@ -16536,6 +17224,12 @@ msgstr "プリンタに保存する名前を入力してください。" msgid "The name cannot exceed 40 characters." msgstr "名前は40文字を超えることはできません。" +msgid "Nozzle ID" +msgstr "ノズルID" + +msgid "Standard Flow" +msgstr "標準フロー" + msgid "Please find the best line on your plate" msgstr "プレート上で最適なラインを見つけてください。" @@ -16625,9 +17319,6 @@ msgstr "AMSとノズル情報が同期されました" msgid "Nozzle Flow" msgstr "ノズルフロー" -msgid "Nozzle Info" -msgstr "ノズル情報" - msgid "Filament position" msgstr "フィラメント位置" @@ -16699,6 +17390,10 @@ msgstr "履歴結果の取得に成功しました" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "フローダイナミクスキャリブレーション履歴を更新中" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "注:%s のホットエンド番号はホルダーに紐づいています。ホットエンドを新しいホルダーに移動すると、その番号は自動的に更新されます。" + msgid "Action" msgstr "アクション" @@ -18391,6 +19086,12 @@ msgstr "印刷失敗" msgid "Removed" msgstr "削除済み" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "再度通知しない" @@ -18424,12 +19125,25 @@ msgstr "ビデオチュートリアル" msgid "(Sync with printer)" msgstr "(プリンターと同期)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "このグルーピング方法に従ってスライスします:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "ヒント: フィラメントをドラッグして別のノズルに再割り当てできます。" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "現在のプレートのフィラメントグルーピング方法はスライスプレートボタンのドロップダウンオプションで決定されます。" @@ -18662,9 +19376,6 @@ msgstr "この操作は元に戻せません。続行しますか?" msgid "Skipping objects." msgstr "オブジェクトをスキップ中。" -msgid "Select Filament" -msgstr "フィラメントを選択" - msgid "Null Color" msgstr "色なし" @@ -19160,6 +19871,19 @@ msgstr "" "反りを避ける\n" "ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか?" +#~ msgid "Continue to sync filaments" +#~ msgstr "フィラメントの同期を続行" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "キャンセル" + +#~ msgid "Align infill direction to model" +#~ msgstr "インフィル方向をモデルに合わせる" + +#~ msgid "Print" +#~ msgstr "造形する" + #~ msgid "in" #~ msgstr "に" @@ -19699,9 +20423,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "起動するのにSDカードが必要です。" -#~ msgid "Update" -#~ msgstr "更新" - #~ msgid "Sensitivity of pausing is" #~ msgstr "感度" @@ -20106,10 +20827,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "選択解除" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "スケール" - #~ msgid "Z-hop when retract" #~ msgstr "リトラクト時にZ方向調整" diff --git a/localization/i18n/ko/OrcaSlicer_ko.po b/localization/i18n/ko/OrcaSlicer_ko.po index 769694b8d6..6b514ac644 100644 --- a/localization/i18n/ko/OrcaSlicer_ko.po +++ b/localization/i18n/ko/OrcaSlicer_ko.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2025-06-02 17:12+0900\n" "Last-Translator: crwusiz \n" "Language-Team: \n" @@ -39,6 +39,24 @@ msgstr "TPU는 AMS에서 지원되지 않습니다." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS는 'Bambu Lab PET-CF'를 지원하지 않습니다." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "TPU 인쇄 전에 콜드 풀을 수행하여 막힘을 방지하세요. 프린터의 콜드 풀 유지보수 기능을 사용할 수 있습니다." @@ -51,6 +69,9 @@ msgstr "습한 PVA는 유연하여 익스트루더에 끼일 수 있습니다. msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "PLA Glow의 거친 표면은 AMS 시스템, 특히 AMS Lite의 내부 부품의 마모를 가속화할 수 있습니다." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF 필라멘트는 단단하고 부서지기 쉽습니다. AMS에 걸리거나 부러지기 쉬우므로 주의하여 사용하세요." @@ -60,10 +81,90 @@ msgstr "PPS-CF는 취성이 있어 툴헤드 위의 구부러진 PTFE 튜브에 msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF는 취성이 있어 툴헤드 위의 구부러진 PTFE 튜브에서 부러질 수 있습니다." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s은(는) %s 익스트루더에서 지원되지 않습니다." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "높은 흐름" + +msgid "Standard" +msgstr "표준" + +msgid "TPU High Flow" +msgstr "TPU 고유량" + +msgid "Unknown" +msgstr "알 수 없는" + +msgid "Hardened Steel" +msgstr "경화강" + +msgid "Stainless Steel" +msgstr "스테인레스 스틸" + +msgid "Tungsten Carbide" +msgstr "텅스텐 카바이드" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "툴헤드와 핫엔드 랙이 움직일 수 있습니다. 챔버에 손을 대지 마십시오." + +msgid "Warning" +msgstr "경고" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "핫엔드 정보가 부정확할 수 있습니다. 핫엔드를 다시 읽어 보시겠습니까? (핫엔드 정보는 전원이 꺼지는 동안 변경될 수 있습니다.)" + +msgid "I confirm all" +msgstr "모두 확인합니다" + +msgid "Re-read all" +msgstr "모두 다시 읽기" + +msgid "Reading the hotends, please wait." +msgstr "핫엔드를 읽는 중입니다, 잠시 기다려 주십시오." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "핫엔드 업그레이드 중에 툴헤드가 움직일 것입니다. 챔버 내부에 손을 넣지 마십시오." + +msgid "Update" +msgstr "업데이트" + msgid "Current AMS humidity" msgstr "현재 AMS 습도" @@ -94,6 +195,85 @@ msgstr "버전:" msgid "Latest version" msgstr "최신 버전" +msgid "Row A" +msgstr "A열" + +msgid "Row B" +msgstr "B열" + +msgid "Toolhead" +msgstr "툴헤드" + +msgid "Empty" +msgstr "비어 있음" + +msgid "Error" +msgstr "오류" + +msgid "Induction Hotend Rack" +msgstr "인덕션 핫엔드 랙" + +msgid "Hotends Info" +msgstr "핫엔드 정보" + +msgid "Read All" +msgstr "모두 읽기" + +msgid "Reading " +msgstr "읽는 중 " + +msgid "Please wait" +msgstr "잠시 기다려 주세요" + +msgid "Running..." +msgstr "실행 중..." + +msgid "Raised" +msgstr "상승함" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "이 핫엔드에 이상 상태가 발생하여 현재 사용할 수 없습니다. '장치 -> 업그레이드'로 이동하여 펌웨어를 업그레이드해 주세요." + +msgid "Abnormal Hotend" +msgstr "비정상 핫엔드" + +msgid "Refresh" +msgstr "새로 고침" + +msgid "Refreshing" +msgstr "새로고침 중" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "핫엔드 상태 비정상, 현재 사용할 수 없습니다. 펌웨어를 업그레이드한 후 다시 시도해 주세요." + +msgid "Cancel" +msgstr "취소" + +msgid "Jump to the upgrade page" +msgstr "업그레이드 페이지로 이동" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "버전" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "사용 시간: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "다이내믹 노즐은 현재 플레이트에 할당됩니다. 핫엔드 선택은 지원되지 않습니다." + +msgid "Hotend Rack" +msgstr "핫엔드 랙" + +msgid "ToolHead" +msgstr "툴헤드" + +msgid "Nozzle information needs to be read" +msgstr "노즐 정보를 읽어야 합니다" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "서포트 칠하기" @@ -166,6 +346,12 @@ msgstr "채우기" msgid "Gap Fill" msgstr "간격 채우기" +msgid "Vertical" +msgstr "수직" + +msgid "Horizontal" +msgstr "수평" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "\"%1%\"에서 선택한 영역에만 칠하기 허용" @@ -261,12 +447,6 @@ msgstr "삼각형" msgid "Height Range" msgstr "높이 범위" -msgid "Vertical" -msgstr "수직" - -msgid "Horizontal" -msgstr "수평" - msgid "Remove painted color" msgstr "칠한 색 제거" @@ -331,6 +511,7 @@ msgstr "변형도구 - 회전" msgid "Optimize orientation" msgstr "방향 최적화" +msgctxt "Verb" msgid "Scale" msgstr "배율" @@ -375,6 +556,9 @@ msgstr "배율비" msgid "Object operations" msgstr "객체 작업" +msgid "Scale" +msgstr "배율" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "용량 작업" @@ -426,6 +610,10 @@ msgstr "회전 도구를 열었을 때의 값으로 현재 회전을 초기화 msgid "Reset current rotation to real zeros." msgstr "현재 회전을 0으로 초기화합니다." +msgctxt "Noun" +msgid "Scale" +msgstr "배율" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "크기" @@ -608,9 +796,6 @@ msgstr "반경과 관련된 공간 비율" msgid "Confirm connectors" msgstr "커넥터 승인" -msgid "Cancel" -msgstr "취소" - msgid "Flip cut plane" msgstr "절단면 뒤집기" @@ -651,12 +836,12 @@ msgstr "부품으로 자르기" msgid "Reset cutting plane and remove connectors" msgstr "절단면 재설정 및 커넥터 제거" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "잘라내기 실행" -msgid "Warning" -msgstr "경고" - msgid "Invalid connectors detected" msgstr "잘못된 커넥터가 감지됨" @@ -685,6 +870,13 @@ msgstr "홈이 있는 절단면은 유효하지 않습니다" msgid "Connector" msgstr "커넥터" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "평면으로 자르기" @@ -732,9 +924,6 @@ msgstr "단순화" msgid "Simplification is currently only allowed when a single part is selected" msgstr "단순화는 현재 단일 부품이 선택된 경우에만 허용됩니다" -msgid "Error" -msgstr "오류" - msgid "Extra high" msgstr "매우 높음" @@ -2007,6 +2196,9 @@ msgstr "" msgid "Loading user preset" msgstr "사용자 사전 설정 로드 중" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2020,6 +2212,18 @@ msgstr "언어 선택" msgid "Language" msgstr "언어" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2651,6 +2855,45 @@ msgstr "아이콘을 클릭하여 객체의 색상 칠하기를 편집합니다" msgid "Click the icon to shift this object to the bed" msgstr "아이콘을 클릭하여 이 객체를 베드로 옮깁니다" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "파일 로딩 중" @@ -2660,6 +2903,9 @@ msgstr "오류!" msgid "Failed to get the model data in the current file." msgstr "현재 파일에서 모델의 데이터를 가져오지 못했습니다." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "일반" @@ -2672,6 +2918,12 @@ msgstr "객체별 설정 모드로 전환하여 선택한 객체의 프로세스 msgid "Remove paint-on fuzzy skin" msgstr "칠한 퍼지 스킨 제거" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "높이 범위 제거" + msgid "Delete connector from object which is a part of cut" msgstr "잘라내기의 일부인 객체에서 커넥터 삭제" @@ -2702,12 +2954,24 @@ msgstr "모든 커넥터 삭제" msgid "Deleting the last solid part is not allowed." msgstr "마지막 꽉찬 부품을 삭제할 수 없습니다." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "대상 객체에는 파트가 하나뿐이며 분할할 수 없습니다." +msgid "Split to parts" +msgstr "부품으로 분할" + msgid "Assembly" msgstr "조립" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "잘라내기 커넥터 정보" @@ -2741,6 +3005,9 @@ msgstr "높이 범위" msgid "Settings for height range" msgstr "높이 범위 설정" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "레이어" @@ -2763,6 +3030,9 @@ msgstr "유형:" msgid "Choose part type" msgstr "부품 유형 선택" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "새 이름 입력" @@ -2788,6 +3058,9 @@ msgstr "\"%s\"은(는) 이 서브디비전 후 100만 면을 초과하여 슬라 msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "\"%s\" 파트의 메쉬에 오류가 있습니다. 먼저 수리하세요." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "추가 프로세스 사전 설정" @@ -2797,9 +3070,6 @@ msgstr "매개 변수 제거" msgid "to" msgstr "으로" -msgid "Remove height range" -msgstr "높이 범위 제거" - msgid "Add height range" msgstr "높이 범위 추가" @@ -3011,6 +3281,9 @@ msgstr "AMS 슬롯을 선택한 다음 '로드' 또는 '언로드' 버튼을 누 msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "이 작업에 필요한 필라멘트 유형이 알 수 없습니다. 대상 필라멘트 정보를 설정하세요." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "인쇄 중 팬 속도를 변경하면 인쇄 품질에 영향을 줄 수 있습니다. 신중하게 선택하세요." @@ -3133,6 +3406,24 @@ msgstr "압출 확인" msgid "Check filament location" msgstr "필라멘트 위치 확인" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "최대 온도는 다음 값을 초과할 수 없습니다 " @@ -3186,6 +3477,62 @@ msgstr "개발자 모드" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "노즐 수를 설정하세요" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "오류: 노즐 수를 둘 다 0으로 설정할 수 없습니다." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "오류: 노즐 수는 %d을 초과할 수 없습니다." + +msgid "Confirm" +msgstr "확인" + +msgid "Extruder" +msgstr "압출기" + +msgid "Nozzle Selection" +msgstr "노즐 선택" + +msgid "Available Nozzles" +msgstr "사용 가능한 노즐" + +msgid "Nozzle Info" +msgstr "노즐 정보" + +msgid "Sync Nozzle status" +msgstr "노즐 상태 동기화" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "주의: 한 번에 여러 노즐 직경을 혼합하여 출력하는 것은 지원되지 않습니다. 선택한 크기가 압출기 하나에만 있는 경우, 단일 압출기 출력이 적용됩니다." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "새로 고침 %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "알 수 없는 노즐이 감지되었습니다. 정보를 업데이트하려면 새로 고침하세요(새로 고침되지 않은 노즐은 슬라이싱 과정에서 제외됩니다). 표시된 값과 노즐 직경 및 유량을 확인하세요." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "알 수 없는 노즐이 감지되었습니다. 새로 고침하여 업데이트하세요(새로 고침되지 않은 노즐은 슬라이싱 시 건너뜁니다)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "필요한 노즐 직경과 유량이 현재 표시된 값과 일치하는지 확인하세요." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "프린터에 여러 개의 노즐이 설치되어 있습니다. 이 출력에 맞는 노즐을 선택하세요." + +msgid "Ignore" +msgstr "무시" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3519,15 +3866,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "버전" - msgid "AMS Materials Setting" msgstr "AMS 재료 설정" -msgid "Confirm" -msgstr "확인" - msgid "Close" msgstr "닫기" @@ -3548,12 +3889,12 @@ msgstr "최소" msgid "The input value should be greater than %1% and less than %2%" msgstr "입력 값은 %1%보다 크고 %2%보다 작아야 합니다" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "동적 압출량 교정 계수" +msgid "Wiki Guide" +msgstr "위키 가이드" + msgid "PA Profile" msgstr "PA 사전설정" @@ -3644,7 +3985,7 @@ msgstr "교정이 완료되었습니다. 당신의 고온 베드에서 아래 msgid "Save" msgstr "저장" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "뒷면" @@ -3728,6 +4069,19 @@ msgstr "오른쪽 노즐" msgid "Nozzle" msgstr "노즐" +msgid "Select Filament && Hotends" +msgstr "필라멘트 및 핫엔드" + +msgid "Select Filament" +msgstr "필라멘트 선택" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "현재 노즐로 출력하면 약 %0.2fg의 낭비물이 발생할 수 있습니다." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "참고: 필라멘트 유형(%s)이 슬라이싱 파일에 있는 필라멘트 유형(%s)과 일치하지 않습니다. 이 슬롯을 사용하려면 %s 대신 %s 을 설치하고 '장치' 페이지에서 슬롯 정보를 변경하면 됩니다." @@ -4438,9 +4792,6 @@ msgstr "표면 측정 중" msgid "Calibrating the detection position of nozzle clumping" msgstr "노즐 클럼핑 감지 위치 보정 중" -msgid "Unknown" -msgstr "알 수 없는" - msgid "Update successful." msgstr "업데이트에 성공했습니다." @@ -4953,9 +5304,6 @@ msgstr "최적으로 설정" msgid "Regroup filament" msgstr "필라멘트 재그룹핑" -msgid "Wiki Guide" -msgstr "위키 가이드" - msgid "up to" msgstr "까지" @@ -4992,7 +5340,7 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "팬 속도 (%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "온도 (℃)" msgid "Volumetric flow rate (mm³/s)" @@ -5011,9 +5359,6 @@ msgstr "필라멘트 변경" msgid "Options" msgstr "옵션" -msgid "Extruder" -msgstr "압출기" - msgid "Cost" msgstr "비용" @@ -5026,6 +5371,7 @@ msgstr "" msgid "Color change" msgstr "색 변경" +msgctxt "Noun" msgid "Print" msgstr "출력" @@ -5189,11 +5535,15 @@ msgstr "압출 교정 영역을 피하세요" msgid "Align to Y axis" msgstr "Y축에 정렬" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "뒷면" + +msgctxt "Camera View" msgid "Left" msgstr "왼쪽" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "오른쪽" @@ -5218,9 +5568,6 @@ msgstr "선택한 플레이트의 객체 정렬" msgid "Split to objects" msgstr "객체로 분할" -msgid "Split to parts" -msgstr "부품으로 분할" - msgid "Assembly View" msgstr "조립 보기" @@ -5517,6 +5864,10 @@ msgstr "플레이트 출력" msgid "Export G-code file" msgstr "Gcode 파일 내보내기" +msgctxt "Verb" +msgid "Print" +msgstr "출력" + msgid "Export plate sliced file" msgstr "플레이트 슬라이스 파일 내보내기" @@ -5690,15 +6041,6 @@ msgstr "현재 설정을 파일로 내보내기" msgid "Export" msgstr "내보내기" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "종료" @@ -5815,6 +6157,15 @@ msgstr "시점" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5934,6 +6285,9 @@ msgstr "결과 내보내기" msgid "Select profile to load:" msgstr "불러올 사전설정 선택:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6097,9 +6451,6 @@ msgstr "선택된 파일을 프린터에서 다운로드합니다." msgid "Batch manage files." msgstr "파일을 일괄 관리합니다." -msgid "Refresh" -msgstr "새로 고침" - msgid "Reload file list from printer." msgstr "프린터에서 파일 목록을 다시 로드합니다." @@ -6411,6 +6762,9 @@ msgstr "출력 옵션" msgid "Safety Options" msgstr "안전 옵션" +msgid "Hotends" +msgstr "핫엔드" + msgid "Lamp" msgstr "조명" @@ -6444,6 +6798,12 @@ msgstr "인쇄가 일시 중지되면 필라멘트 로딩 및 언로딩은 외 msgid "Current extruder is busy changing filament." msgstr "현재 익스트루더가 필라멘트 교체 중입니다." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "현재 슬롯은 이미 로드되었습니다." @@ -6495,9 +6855,6 @@ msgstr "출력하는 동안에만 적용됩니다" msgid "Silent" msgstr "조용한" -msgid "Standard" -msgstr "표준" - msgid "Sport" msgstr "스포츠" @@ -6531,6 +6888,12 @@ msgstr "사진 추가" msgid "Delete Photo" msgstr "사진 삭제" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "제출" @@ -6718,6 +7081,9 @@ msgstr "LAN 전용 모드 사용 방법" msgid "Don't show this dialog again" msgstr "이 대화 상자를 다시 표시하지 마세요." +msgid "Please refer to Wiki before use->" +msgstr "사용하기 전에 Wiki를 참조하십시오->" + msgid "3D Mouse disconnected." msgstr "3D 마우스가 분리됨." @@ -6968,27 +7334,18 @@ msgstr "플로우" msgid "Please change the nozzle settings on the printer." msgstr "프린터의 노즐 설정을 변경하세요." -msgid "Hardened Steel" -msgstr "경화강" - -msgid "Stainless Steel" -msgstr "스테인레스 스틸" - -msgid "Tungsten Carbide" -msgstr "텅스텐 카바이드" - msgid "Brass" msgstr "황동" msgid "High flow" msgstr "고유량" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "이 프린터에 사용 가능한 위키 링크가 없습니다." -msgid "Refreshing" -msgstr "새로고침 중" - msgid "Unavailable while heating maintenance function is on." msgstr "가열 유지보수 기능이 켜져 있는 동안에는 사용할 수 없습니다." @@ -7111,6 +7468,15 @@ msgstr "직경 스위치" msgid "Configuration incompatible" msgstr "호환되지 않는 구성" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "팁" + msgid "Sync printer information" msgstr "프린터 정보 동기화" @@ -7139,6 +7505,9 @@ msgstr "클릭하여 사전 설정 편집" msgid "Project Filaments" msgstr "프로젝트 필라멘트" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "버리기 볼륨" @@ -7367,9 +7736,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "팁" - msgid "The file does not contain any geometry data." msgstr "파일에 형상 데이터가 포함되어 있지 않습니다." @@ -7420,9 +7786,21 @@ msgstr "" "이 작업을 수행하면 잘라낸 객체간 연결이 끊어집니다.\n" "그 이후 모델의 일관성은 보장되지 않습니다." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "선택한 객체를 분할할 수 없습니다." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7449,6 +7827,9 @@ msgstr "새 파일 선택" msgid "File for the replacement wasn't selected" msgstr "대체할 파일이 선택되지 않았습니다" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7495,6 +7876,9 @@ msgstr "새로고침할 수 없음:" msgid "Error during reload" msgstr "새로고침 중 오류가 발생했습니다" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "모델을 슬라이싱한 후 경고 발생:" @@ -8256,6 +8640,15 @@ msgstr "파일을 로드한 후 프린터 사전 설정 동기화를 선택 취 msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8271,16 +8664,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8562,6 +8946,9 @@ msgstr "호환되지 않는 사전 설정" msgid "My Printer" msgstr "내 프린터" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "왼쪽 필라멘트" @@ -8581,6 +8968,9 @@ msgstr "사전 설정 추가/제거" msgid "Edit preset" msgstr "사전 설정 편집" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "" @@ -8612,9 +9002,6 @@ msgstr "프린터 선택/제거(시스템 사전 설정)" msgid "Create printer" msgstr "프린터 생성" -msgid "Empty" -msgstr "비어 있음" - msgid "Incompatible" msgstr "호환되지 않음" @@ -8846,12 +9233,42 @@ msgstr "전송 완료" msgid "Error code" msgstr "오류 코드" -msgid "High Flow" -msgstr "높은 흐름" +msgid "Error desc" +msgstr "오류 설명" + +msgid "Extra info" +msgstr "추가 정보" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s(%s)의 노즐 유량 설정이 슬라이싱 파일(%s)과 일치하지 않습니다. 설치된 노즐이 프린터의 설정과 일치하는지 확인한 다음 슬라이싱하는 동안 해당 프린터 프리셋을 설정하세요." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8917,8 +9334,38 @@ msgstr "비용 %dg 필라멘트 및 %d 최적의 그룹화보다 더 많이 변 msgid "nozzle" msgstr "노즐" -msgid "both extruders" -msgstr "두 압출기" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s(%s)의 노즐 유량 설정이 슬라이싱 파일(%s)과 일치하지 않습니다. 설치된 노즐이 프린터의 설정과 일치하는지 확인한 다음 슬라이싱하는 동안 해당 프린터 프리셋을 설정하세요." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "팁: 최근에 프린터의 노즐을 변경한 경우 '장치 -> 프린터 부품'으로 이동하여 노즐 설정을 변경하세요." @@ -8931,10 +9378,17 @@ msgstr "현재 프린터의 %s 직경(%.1fmm)이 슬라이싱 파일(%.1fmm)과 msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "현재 노즐 직경(%.1fmm)이 슬라이싱 파일(%.1fmm)과 일치하지 않습니다. 설치된 노즐이 프린터의 설정과 일치하는지 확인한 다음 슬라이싱할 때 해당 프린터 프리셋을 설정하세요." +msgid "both extruders" +msgstr "두 압출기" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "현재 재료의 경도 (%s) 가 경도 %s (%s) 를 초과합니다. 노즐 또는 재료 설정을 확인하고 다시 시도하십시오." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -9045,9 +9499,6 @@ msgstr "현재 펌웨어는 최대 16개의 재료를 지원합니다. 준비 msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "사용하기 전에 Wiki를 참조하십시오->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "현재 펌웨어는 내부 스토리지로의 파일 전송을 지원하지 않습니다." @@ -9231,6 +9682,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "모든 설정을 마지막으로 저장한 사전 설정으로 되돌립니다." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "노즐 교체를 위해 프라임 타워가 필요합니다. 프라임 타워가 없으면 모델에 결함이 있을 수 있습니다. 프라임 타워를 비활성화하시겠습니까?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "유연모드 타임랩스를 위해서는 프라임 타워가 필요합니다. 프라임 타워가 없는 모델에는 결함이 있을 수 있습니다. 프라임 타워를 사용하지 않도록 설정하시겠습니까?" @@ -9308,9 +9762,6 @@ msgstr "설정 범위에 자동으로 맞춰지나요?\n" msgid "Adjust" msgstr "조정" -msgid "Ignore" -msgstr "무시" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "실험적 기능: 플러시를 최소화하기 위해 필라멘트 교체 중에 더 먼 거리에서 필라멘트를 집어넣고 절단합니다. 플러시를 눈에 띄게 줄일 수 있지만 노즐 막힘이나 기타 출력 문제의 위험이 높아질 수도 있습니다." @@ -9809,6 +10260,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "선택한 사전 설정을 %1%로 설정하시겠습니까?" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10036,6 +10493,12 @@ msgstr "왼쪽에서 오른쪽으로 값 전송" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "이 대화 상자를 활성화하면 선택한 값을 왼쪽에서 오른쪽으로 사전 설정으로 변환하는 데 사용할 수 있습니다." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "파일 추가" @@ -10291,12 +10754,8 @@ msgstr "노즐 정보를 성공적으로 동기화했습니다." msgid "Successfully synchronized nozzle and AMS number information." msgstr "노즐 및 AMS 번호 정보를 성공적으로 동기화했습니다." -msgid "Continue to sync filaments" -msgstr "필라멘트 동기화 계속하기" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "취소" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10404,6 +10863,9 @@ msgstr "로그인" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10718,6 +11180,9 @@ msgstr "프린터 이름" msgid "Where to find your printer's IP and Access Code?" msgstr "프린터의 IP 및 액세스 코드는 어디에서 찾을 수 있습니까?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "연결" @@ -10782,6 +11247,9 @@ msgstr "커팅 모듈" msgid "Auto Fire Extinguishing System" msgstr "자동 화재 진압 시스템" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10800,6 +11268,9 @@ msgstr "업데이트 실패" msgid "Update successful" msgstr "업데이트 성공" +msgid "Hotends on Rack" +msgstr "랙의 핫엔드" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "업데이트하시겠습니까? 약 10분 정도 소요됩니다. 프린터가 업데이트되는 동안에는 전원을 끄지 마십시오." @@ -10908,6 +11379,9 @@ msgstr "그룹화 오류입니다:" msgid " can not be placed in the " msgstr " 에 배치할 수 없습니다" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "내부 브릿지" @@ -11618,7 +12092,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11632,7 +12106,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12049,9 +12523,6 @@ msgstr "" "날카로운 각도를 감지하기 전에 형상이 무시됩니다. 이 매개변수는 무시하는 형상의 최소 길이를 나타냅니다.\n" "0으로 비활성화합니다" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "상향 호환 장치" @@ -12062,9 +12533,6 @@ msgstr "" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "활성 프린터 프로필의 구성 값을 사용하는 불리언 표현식입니다. 이 표현식이 true로 평가되면 이 프로필은 활성 프린터 프로필과 호환되는 것으로 간주됩니다." -msgid "Select profiles" -msgstr "" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "활성 출력 프로필의 구성 값을 사용하는 불리언 표현식입니다. 이 표현식이 true로 평가되면 이 프로필은 활성 출력 프로필과 호환되는 것으로 간주됩니다." @@ -12337,6 +12805,42 @@ msgstr "상단 표면 밀도" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "하단 표면 패턴" @@ -12661,12 +13165,18 @@ msgstr "자동 플러시" msgid "Auto For Match" msgstr "자동 경기" +msgid "Nozzle Manual" +msgstr "노즐 설명서" + msgid "Flush temperature" msgstr "플러시 온도" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "플러시 체적 속도" @@ -12929,6 +13439,12 @@ msgstr "필라멘트 출력 가능" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "연화 온도" @@ -12991,12 +13507,12 @@ msgstr "드문 채우기 밀도" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "내부 드문 채우기의 밀도, 100%는 모든 드문 채우기를 꽉찬 내부 채우기로 변경하고 채우기에는 패턴이 사용됩니다" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13507,6 +14023,15 @@ msgstr "베드 모양 w.r.t. 범위 [0,1] 내에서 가장 좋은 자동 정렬 msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "장치에 보조 출력물 냉각팬이 있는 경우 이 옵션을 활성화합니다. Gcode 명령: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13578,6 +14103,12 @@ msgstr "" "프린터가 공기 여과를 지원하는 경우 활성화하세요.\n" "Gcode 명령: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "냉각 필터 사용" + +msgid "Enable this if printer support cooling filter" +msgstr "프린터가 냉각 필터를 지원하는 경우 이 기능을 활성화하세요." + msgid "G-code flavor" msgstr "Gcode 유형" @@ -14107,6 +14638,30 @@ msgstr "최소 이동 속도" msgid "Minimum travel speed (M205 T)" msgstr "최소 이동 속도 (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Y축의 최대 힘" + +msgid "The allowed maximum output force of Y axis" +msgstr "Y축의 허용 최대 출력 힘" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Y축의 베드 질량" + +msgid "The machine bed mass load of Y axis" +msgstr "Y축 장비 베드 질량 하중" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "허용되는 최대 출력 질량" + +msgid "The allowed max printed mass on a plate" +msgstr "플레이트에 허용되는 최대 출력 질량" + msgid "Maximum acceleration for extruding" msgstr "압출 중 최대 가속도" @@ -14654,6 +15209,9 @@ msgstr "직접 드라이브" msgid "Bowden" msgstr "보우덴" +msgid "Hybrid" +msgstr "하이브리드" + msgid "Enable filament dynamic map" msgstr "" @@ -14689,6 +15247,12 @@ msgstr "후퇴 복귀 속도" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "펌웨어 리트렉션 사용" @@ -14720,6 +15284,10 @@ msgstr "정렬" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "뒷면" + msgid "Random" msgstr "무작위" @@ -14994,6 +15562,12 @@ msgstr "유연 또는 기존 모드를 선택한 경우 각 출력에 대해 타 msgid "Traditional" msgstr "기존" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "온도 가변" @@ -15082,6 +15656,18 @@ msgstr "모든 활성화된 압출기 프라이밍" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "활성화되면 모든 활성화된 압출기는 출력 시작 시 출력 베드의 앞쪽 가장자리에서 프라이밍합니다." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "슬라이스 간격 폐쇄 반경" @@ -15466,7 +16052,7 @@ msgstr "" "활성화된 경우 이 매개변수는 원하는 챔버 온도를 출력 시작 매크로 또는 PRINT_START(기타 변수) CHAMBER_TEMP=[chamber_temp]와 같은 열 흡수 매크로에 전달하는 데 사용할 수 있는 Chamber_temp라는 Gcode 변수도 설정합니다. 이는 프린터가 M141/M191 명령을 지원하지 않거나 활성 챔버 히터가 설치되지 않은 경우 출력 시작 매크로에서 열 흡수를 처리하려는 경우 유용할 수 있습니다." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15521,6 +16107,45 @@ msgstr "상단 쉘 두께" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "상단 쉘 레이어로 계산된 두께가 이 값보다 얇은 경우 슬라이싱할 때 상단 꽉찬 레이어의 수가 증가합니다. 이렇게 하면 레이어 높이가 작을 때 쉘이 너무 얇아지는 것을 방지할 수 있습니다. 0은 이 설정이 비활성화되고 상단 쉘의 두께가 절대적으로 상단 쉘 레이어에 의해 결정됨을 의미합니다" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "압출이 없을 때의 이동 속도" @@ -15569,6 +16194,12 @@ msgstr "버리기 승수" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "실제 버리기 볼륨은 버리기 승수에 테이블의 버리기 볼륨을 곱한 것과 같습니다." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "프라임양" @@ -15576,6 +16207,18 @@ msgstr "프라임양" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "탑에서 압출을 실행할 재료의 부피." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "프라임 타워의 너비" @@ -15865,6 +16508,57 @@ msgstr "최소 벽 너비" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "모델의 얇은 형상(최소 형상 크기에 따름)을 대체할 벽의 너비입니다. 최소 벽 너비가 형상의 두께보다 얇은 경우 벽은 형상 자체만큼 두꺼워집니다. 노즐 직경에 대한 백분율로 표시됩니다" +msgid "Hotend change time" +msgstr "핫엔드 교체 시간" + +msgid "Time to change hotend." +msgstr "핫엔드를 교체할 시간입니다." + +msgid "Hotend change" +msgstr "핫엔드 교체" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "핫엔드를 교체할 때는 원래 노즐에서 일정 길이의 필라멘트를 압출하는 것이 좋습니다. 이렇게 하면 노즐 흘러내림을 최소화할 수 있습니다." + +msgid "Extruder change" +msgstr "압출기 교체" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "흘러내림을 방지하기 위해 노즐은 래밍이 완료된 후 일정 시간 동안 역방향 이동을 수행합니다. 이 설정은 이동 시간을 정의합니다." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "흘러내림을 방지하기 위해 래밍하는 동안 노즐 온도가 냉각됩니다. 따라서 래밍 시간은 쿨다운 시간보다 길어야 합니다. 0은 비활성화를 의미합니다." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "압출기 교체 전 충돌을 위한 최대 체적 속도이며, 여기서 -1은 최대 체적 속도를 사용함을 의미합니다." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "누수 방지를 위해 충돌 중 노즐 온도가 낮아집니다. 참고: 냉각 명령과 팬 작동만 실행되며, 목표 온도 도달은 보장되지 않습니다. 0은 비활성화를 의미합니다." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "핫엔드 교체 전에 적용되는 충돌의 최대 체적 속도이며, 여기서 -1은 최대 체적 속도를 사용함을 의미합니다." + +msgid "length when change hotend" +msgstr "핫엔드 교체 시 길이" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "이 수축 값이 수정되면 핫엔드를 변경하기 전에 핫엔드 내부로 수축되는 필라멘트 양으로 사용됩니다." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "타워에서 핫엔드를 교체하기 위해 압출기를 준비하는 데 필요한 재료 부피." + +msgid "Preheat temperature delta" +msgstr "예열 온도 차이" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "도구 교체 전 예열 과정에서 적용되는 온도 차이입니다." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "좁은 꽉찬 내부 채우기 감지" @@ -16631,12 +17325,6 @@ msgstr "" msgid "Calibration not supported" msgstr "교정이 지원되지 않음" -msgid "Error desc" -msgstr "오류 설명" - -msgid "Extra info" -msgstr "추가 정보" - msgid "Flow Dynamics" msgstr "동적 압출량" @@ -16839,6 +17527,12 @@ msgstr "프린터에 저장할 이름을 입력하세요." msgid "The name cannot exceed 40 characters." msgstr "이름은 40자를 초과할 수 없습니다." +msgid "Nozzle ID" +msgstr "노즐 ID" + +msgid "Standard Flow" +msgstr "표준 유량" + msgid "Please find the best line on your plate" msgstr "당신의 플레이트에서 가장 좋은 선을 찾아보세요" @@ -16929,9 +17623,6 @@ msgstr "AMS와 노즐 정보가 동기화되었습니다." msgid "Nozzle Flow" msgstr "노즐 흐름" -msgid "Nozzle Info" -msgstr "노즐 정보" - msgid "Filament position" msgstr "필라멘트 위치" @@ -17006,6 +17697,10 @@ msgstr "기록 결과 가져오기 성공" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "과거 동적 압출량 교정 기록 새로 고침" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "참고: %s의 핫엔드 번호는 홀더에 연결되어 있습니다. 핫엔드를 새 홀더로 옮기면 번호가 자동으로 업데이트됩니다." + msgid "Action" msgstr "실행" @@ -18736,6 +19431,12 @@ msgstr "출력 실패" msgid "Removed" msgstr "삭제됨" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "다시 알리지 마세요" @@ -18769,12 +19470,25 @@ msgstr "비디오 자습서" msgid "(Sync with printer)" msgstr "(프린터와 동기화)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "이 그룹화 방법에 따라 슬라이싱합니다:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "현재 플레이트의 필라멘트 그룹화 방법은 슬라이스 플레이트 버튼의 드롭다운 옵션에 따라 결정됩니다." @@ -19007,9 +19721,6 @@ msgstr "이 작업은 취소할 수 없습니다. 계속하시겠습니까?" msgid "Skipping objects." msgstr "물체 건너뛰기" -msgid "Select Filament" -msgstr "필라멘트 선택" - msgid "Null Color" msgstr "무효 색상" @@ -19528,6 +20239,16 @@ msgstr "" "뒤틀림 방지\n" "ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?" +#~ msgid "Continue to sync filaments" +#~ msgstr "필라멘트 동기화 계속하기" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "취소" + +#~ msgid "Print" +#~ msgstr "출력" + #~ msgid "in" #~ msgstr "인치" @@ -20243,9 +20964,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "SD 카드가 없으면 시작할 수 없습니다." -#~ msgid "Update" -#~ msgstr "업데이트" - #~ msgid "Sensitivity of pausing is" #~ msgstr "일시 정지 감도" @@ -21019,10 +21737,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "선택 취소" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "규모" - #~ msgid "Lift Z Enforcement" #~ msgstr "강제 Z 올리기" diff --git a/localization/i18n/list.txt b/localization/i18n/list.txt index d968cd5322..1614bc453b 100644 --- a/localization/i18n/list.txt +++ b/localization/i18n/list.txt @@ -41,12 +41,23 @@ src/slic3r/GUI/DeviceCore/DevMapping.h src/slic3r/GUI/DeviceCore/DevMapping.cpp src/slic3r/GUI/DeviceCore/DevNozzleSystem.h src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp +src/slic3r/GUI/DeviceCore/DevNozzleRack.h +src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp +src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp src/slic3r/GUI/DeviceCore/DevUtil.h src/slic3r/GUI/DeviceCore/DevUtil.cpp src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.h src/slic3r/GUI/DeviceTab/uiAmsHumidityPopup.cpp src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h src/slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.cpp +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h +src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.cpp src/slic3r/GUI/Gizmos/GLGizmoFdmSupports.hpp src/slic3r/GUI/Gizmos/GLGizmoFlatten.cpp @@ -97,6 +108,8 @@ src/slic3r/GUI/Widgets/FilamentLoad.cpp src/slic3r/GUI/Widgets/TempInput.cpp src/slic3r/GUI/Widgets/CheckList.cpp src/slic3r/GUI/Widgets/SwitchButton.cpp +src/slic3r/GUI/Widgets/MultiNozzleSync.cpp +src/slic3r/GUI/Widgets/ProgressDialog.cpp src/slic3r/GUI/ImGuiWrapper.cpp src/slic3r/GUI/Jobs/ArrangeJob.cpp src/slic3r/GUI/Jobs/OrientJob.cpp @@ -274,4 +287,6 @@ src/slic3r/GUI/DownloaderFileGet.cpp src/slic3r/GUI/FileArchiveDialog.cpp src/slic3r/GUI/PrinterCloudAuthDialog.cpp src/slic3r/GUI/PrinterWebViewHandler.cpp +src/slic3r/GUI/AMSDryControl.cpp +src/slic3r/GUI/AMSDryControl.hpp src/libslic3r/PresetBundle.cpp diff --git a/localization/i18n/lt/OrcaSlicer_lt.po b/localization/i18n/lt/OrcaSlicer_lt.po index 69de514c68..a22a2efe86 100644 --- a/localization/i18n/lt/OrcaSlicer_lt.po +++ b/localization/i18n/lt/OrcaSlicer_lt.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-07-02 14:13+0300\n" "Last-Translator: Gintaras Kučinskas \n" "Language-Team: \n" @@ -40,6 +40,24 @@ msgstr "AMS nepalaiko TPU." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS nepalaiko „Bambu Lab PET-CF“." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Prieš spausdindami TPU, atlikite valymą traukiant atvėsusią giją („cold pull“), kad išvengtumėte užsikimšimo. Galite naudoti spausdintuvo techninės priežiūros funkciją." @@ -52,6 +70,9 @@ msgstr "Drėgnas PVA yra lankstus ir gali įstrigti ekstruderyje. Prieš naudoji msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "Šiurkštus „PLA Glow“ paviršius gali pagreitinti AMS sistemos, ypač „AMS Lite“ vidinių komponentų, nusidėvėjimą." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Pastaba: CF/GF gijos yra kietos ir trapios. Jas lengva nulaužti arba jos gali įstrigti AMS. Naudokite atsargiai." @@ -61,10 +82,90 @@ msgstr "PPS-CF yra trapus ir gali lūžti sulenktoje PTFE tūtelėje virš spaus msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF yra trapus ir gali lūžti sulenktoje PTFE tūtelėje virš spausdinimo galvutės." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%2$s ekstruderis nepalaiko %1$s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Didelis srautas (High Flow)" + +msgid "Standard" +msgstr "Standartinis" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Nežinomas" + +msgid "Hardened Steel" +msgstr "Grūdintas plienas" + +msgid "Stainless Steel" +msgstr "Nerūdijantis plienas" + +msgid "Tungsten Carbide" +msgstr "Volframo karbidas" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Įspėjimas" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "Dabartinė AMS drėgmė" @@ -95,6 +196,85 @@ msgstr "Versija:" msgid "Latest version" msgstr "Naujausia versija" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Tuščias" + +msgid "Error" +msgstr "Klaida" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Atnaujinti" + +msgid "Refreshing" +msgstr "Atnaujinama" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "Atšaukti" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "SN" + +msgid "Version" +msgstr "Versija" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + msgid "Support Painting" msgstr "Atramų piešimas" @@ -164,6 +344,12 @@ msgstr "Užpildymas" msgid "Gap Fill" msgstr "Plyšių užpildymas" +msgid "Vertical" +msgstr "Vertikaliai" + +msgid "Horizontal" +msgstr "Horizontaliai" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Leidžia piešti tik ant paviršių, kuriuos pasirinko: „%1%“" @@ -256,12 +442,6 @@ msgstr "Trikampis" msgid "Height Range" msgstr "Aukščio diapazonas" -msgid "Vertical" -msgstr "Vertikaliai" - -msgid "Horizontal" -msgstr "Horizontaliai" - msgid "Remove painted color" msgstr "Pašalinti dažytą spalvą" @@ -326,6 +506,7 @@ msgstr "Manipuliatorius – Pasukimas" msgid "Optimize orientation" msgstr "Optimizuoti orientaciją" +msgctxt "Verb" msgid "Scale" msgstr "Mastelis" @@ -369,6 +550,9 @@ msgstr "Mastelio koeficientai" msgid "Object operations" msgstr "" +msgid "Scale" +msgstr "Mastelis" + msgid "Volume operations" msgstr "" @@ -414,6 +598,10 @@ msgstr "Atkurti dabartinį pasukimą iki vertės, buvusios atidarius pasukimo į msgid "Reset current rotation to real zeros." msgstr "Atstatyti dabartinį sukimąsi į tikrąsias nulines vertes." +msgctxt "Noun" +msgid "Scale" +msgstr "Mastelis" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Dydis" @@ -596,9 +784,6 @@ msgstr "Tarpo proporcija spindulio atžvilgiu" msgid "Confirm connectors" msgstr "Patvirtinti jungtis" -msgid "Cancel" -msgstr "Atšaukti" - msgid "Flip cut plane" msgstr "Apversti pjovimo plokštumą" @@ -639,12 +824,12 @@ msgstr "Supjaustyti į detales" msgid "Reset cutting plane and remove connectors" msgstr "Atstatyti pjovimo plokštumą ir pašalinti jungtis" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Atlikti pjūvį" -msgid "Warning" -msgstr "Įspėjimas" - msgid "Invalid connectors detected" msgstr "Nustatytos netinkamos jungtys" @@ -677,6 +862,13 @@ msgstr "Neteisinga pjovimo plokštuma su grioveliu" msgid "Connector" msgstr "Jungtis" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Pjovimas plokštuma" @@ -723,9 +915,6 @@ msgstr "Supaprastinti" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Šiuo metu supaprastinimas leidžiamas tik tada, kai pasirenkama viena dalis" -msgid "Error" -msgstr "Klaida" - msgid "Extra high" msgstr "Labai aukštas" @@ -2000,6 +2189,9 @@ msgstr "Prieiga prie rinkinio %s nesuteikta." msgid "Loading user preset" msgstr "Įkeliamas naudotojo profilis" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s buvo pašalintas." @@ -2013,6 +2205,18 @@ msgstr "Pasirinkite kalbą" msgid "Language" msgstr "Kalba" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2613,6 +2817,45 @@ msgstr "" msgid "Click the icon to shift this object to the bed" msgstr "Spustelėkite piktogramą, kad perkeltumėte šį objektą ant pagrindo" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Įkeliamas failas" @@ -2622,6 +2865,9 @@ msgstr "Klaida!" msgid "Failed to get the model data in the current file." msgstr "Nepavyko gauti modelio duomenų iš dabartinio failo." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Bendras" @@ -2634,6 +2880,12 @@ msgstr "Norėdami redaguoti pasirinktų objektų spausdinimo parametrus, persiju msgid "Remove paint-on fuzzy skin" msgstr "Pašalinti pieštą grublėtą paviršių" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Pašalinti aukščio ribas" + msgid "Delete connector from object which is a part of cut" msgstr "Pašalinkite jungtį nuo objekto, kuris yra pjūvio dalis" @@ -2659,12 +2911,24 @@ msgstr "Ištrinti visas jungtis" msgid "Deleting the last solid part is not allowed." msgstr "Neleidžiama ištrinti paskutinės geometrinės detalės." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Tikslinis objektas turi tik vieną detalę ir negali būti išskaidytas." +msgid "Split to parts" +msgstr "Padalinti į dalis" + msgid "Assembly" msgstr "Surinkimas" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Pjovimo jungčių informacija" @@ -2695,6 +2959,9 @@ msgstr "Aukščio diapazonai" msgid "Settings for height range" msgstr "Aukščio diapazono nustatymai" +msgid "Delete selected" +msgstr "Ištrinti pasirinkimą" + msgid "Layer" msgstr "Sluoksnis" @@ -2716,6 +2983,9 @@ msgstr "Tipas:" msgid "Choose part type" msgstr "Pasirinkite detalės tipą" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Įvesti naują pavadinimą" @@ -2745,6 +3015,9 @@ msgstr "„%s“ po šio padalijimo (subdivision) viršys 1 milijoną poligonų msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "Detalės „%s“ poligoninis tinklas (mesh) turi klaidų. Pirmiausia jas sutaisykite." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Papildomas proceso profilis" @@ -2754,9 +3027,6 @@ msgstr "Pašalinti parametrą" msgid "to" msgstr "į" -msgid "Remove height range" -msgstr "Pašalinti aukščio ribas" - msgid "Add height range" msgstr "Pridėti aukščio ribas" @@ -2959,6 +3229,9 @@ msgstr "" msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Šiam veiksmui atlikti reikalingas gijos tipas yra nežinomas. Nustatykite tikslinės gijos informaciją." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Ventiliatoriaus greičio keitimas spausdinimo metu gali paveikti spausdinimo kokybę, pasirinkite atsakingai." @@ -3080,6 +3353,24 @@ msgstr "Patvirtinti, kad išspausta" msgid "Check filament location" msgstr "Patikrinti gijos padėtį" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Maksimali temperatūra negali viršyti " @@ -3131,6 +3422,62 @@ msgstr "Kūrėjo režimas" msgid "Launch troubleshoot center" msgstr "Atidaryti trikčių šalinimo centrą" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Patvirtinti" + +msgid "Extruder" +msgstr "Ekstruderis (Stūmiklis)" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "Purkštuko informacija" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Nekreipti dėmesio" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3454,15 +3801,9 @@ msgstr "„OrcaSlicer“ buvo sukurtas vadovaujantis ta pačia dvasia, remiantis msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Šiandien „OrcaSlicer“ yra plačiausiai naudojama ir aktyviausiai tobulinama atvirojo kodo paruošimo spausdinimui (slicer) programa 3D spausdinimo bendruomenėje.. Daugelis jos naujovių buvo perimtos kitų pjaustymo programų, todėl ji tapo visos pramonės varomąja jėga." -msgid "Version" -msgstr "Versija" - msgid "AMS Materials Setting" msgstr "AMS medžiagų nuostatos" -msgid "Confirm" -msgstr "Patvirtinti" - msgid "Close" msgstr "Uždaryti" @@ -3483,12 +3824,12 @@ msgstr "min" msgid "The input value should be greater than %1% and less than %2%" msgstr "Įvesties reikšmė turi būti didesnė nei %1% ir mažesnė nei %2%" -msgid "SN" -msgstr "SN" - msgid "Factors of Flow Dynamics Calibration" msgstr "Srauto dinamikos kalibravimo koeficientai" +msgid "Wiki Guide" +msgstr "Wiki vadovas" + msgid "PA Profile" msgstr "PA profilis" @@ -3576,6 +3917,7 @@ msgstr "Kalibravimas baigtas. Raskite tolygiausią ekstruzijos liniją ant kaiti msgid "Save" msgstr "Išsaugoti" +msgctxt "Navigation" msgid "Back" msgstr "Atgal" @@ -3659,6 +4001,19 @@ msgstr "Dešinysis purkštukas" msgid "Nozzle" msgstr "Purkštukas" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "Pasirinkti giją" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Pastaba: gijos tipas (%s) nesutampa su gijos tipu (%s) paruoštame spausdinimo faile. Jei norite naudoti šią angą, vietoj %s galite įstatyti %s ir pakeisti angos informaciją puslapyje „Įrenginys“." @@ -4326,9 +4681,6 @@ msgstr "Matuojamas paviršius" msgid "Calibrating the detection position of nozzle clumping" msgstr "Kalibruojama medžiagos sankaupos ant purkštuko aptikimo padėtis" -msgid "Unknown" -msgstr "Nežinomas" - msgid "Update successful." msgstr "Atnaujinimas sėkmingas." @@ -4837,9 +5189,6 @@ msgstr "Nustatyti į optimalų" msgid "Regroup filament" msgstr "Pergrupuoti gijas" -msgid "Wiki Guide" -msgstr "Wiki vadovas" - msgid "up to" msgstr "iki" @@ -4873,8 +5222,8 @@ msgstr "Trūktelėjimas (mm/s)" msgid "Fan speed (%)" msgstr "" -msgid "Temperature (°C)" -msgstr "Temperatūra (°C)" +msgid "Temperature (℃)" +msgstr "Temperatūra (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Tūrinis srautas (mm³/s)" @@ -4891,9 +5240,6 @@ msgstr "Gijos keitimai" msgid "Options" msgstr "Parinktys" -msgid "Extruder" -msgstr "Ekstruderis (Stūmiklis)" - msgid "Cost" msgstr "Kaina" @@ -4906,6 +5252,7 @@ msgstr "Įrankio keitimai" msgid "Color change" msgstr "Spalvos keitimas" +msgctxt "Noun" msgid "Print" msgstr "Spausdinti" @@ -5069,11 +5416,15 @@ msgstr "Vengti ekstruzijos kalibravimo srities" msgid "Align to Y axis" msgstr "Išlygiuoti pagal Y ašį" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Atgal" + +msgctxt "Camera View" msgid "Left" msgstr "Kairė" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Dešinė" @@ -5098,9 +5449,6 @@ msgstr "Išdėstyti objektus pasirinktose plokštėse" msgid "Split to objects" msgstr "Padalinti į objektus" -msgid "Split to parts" -msgstr "Padalinti į dalis" - msgid "Assembly View" msgstr "Surinkimo vaizdas" @@ -5396,6 +5744,10 @@ msgstr "Spausdinti plokštę" msgid "Export G-code file" msgstr "Eksportuoti G-kodo failą" +msgctxt "Verb" +msgid "Print" +msgstr "Spausdinti" + msgid "Export plate sliced file" msgstr "Eksportuoti supjaustytos plokštės failą" @@ -5569,15 +5921,6 @@ msgstr "Eksportuoti dabartinę konfigūraciją į failus" msgid "Export" msgstr "Eksportuoti" -msgid "Sync Presets" -msgstr "Sinchronizuoti profilius" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Atsisiųsti ir pritaikyti naujausius profilius iš „OrcaCloud“" - -msgid "You must be logged in to sync presets from cloud." -msgstr "Norėdami sinchronizuoti profilius iš debesies, turite būti prisijungę." - msgid "Quit" msgstr "Išeiti" @@ -5692,6 +6035,15 @@ msgstr "Vaizdas" msgid "Preset Bundle" msgstr "Profilių rinkinys" +msgid "Sync Presets" +msgstr "Sinchronizuoti profilius" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Atsisiųsti ir pritaikyti naujausius profilius iš „OrcaCloud“" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Norėdami sinchronizuoti profilius iš debesies, turite būti prisijungę." + msgid "Syncing presets from cloud…" msgstr "Sinchronizuojami profiliai iš debesies…" @@ -5810,6 +6162,9 @@ msgstr "" msgid "Select profile to load:" msgstr "Pasirinkite įkeliamą profilį:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5977,9 +6332,6 @@ msgstr "Atsisiųsti pasirinktus failus iš spausdintuvo." msgid "Batch manage files." msgstr "Masinis failų valdymas." -msgid "Refresh" -msgstr "Atnaujinti" - msgid "Reload file list from printer." msgstr "Iš naujo iš spausdintuvo įkelti failų sąrašą." @@ -6285,6 +6637,9 @@ msgstr "Spausdinimo parametrai" msgid "Safety Options" msgstr "Saugos nustatymai" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Apšvietimas" @@ -6318,6 +6673,12 @@ msgstr "Kai spausdinimas pristabdytas, gijos įvėrimas ir išvėrimas palaikoma msgid "Current extruder is busy changing filament." msgstr "Šiuo metu ekstruderis keičia giją." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Į šį lizdą gija jau įverta." @@ -6366,9 +6727,6 @@ msgstr "Tai turi įtakos tik spausdinimo metu" msgid "Silent" msgstr "Tylus" -msgid "Standard" -msgstr "Standartinis" - msgid "Sport" msgstr "Sportinis" @@ -6402,6 +6760,12 @@ msgstr "Įtraukti nuotrauką" msgid "Delete Photo" msgstr "Ištrinti nuotrauką" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Pateikti" @@ -6585,6 +6949,9 @@ msgstr "Kaip naudoti tik LAN režimą" msgid "Don't show this dialog again" msgstr "Daugiau nerodyti šio dialogo lango" +msgid "Please refer to Wiki before use->" +msgstr "Prieš naudodami peržiūrėkite „Wiki“ ->" + msgid "3D Mouse disconnected." msgstr "3D pelė atjungta." @@ -6838,27 +7205,18 @@ msgstr "Srautas" msgid "Please change the nozzle settings on the printer." msgstr "Pakeiskite purkštuko nustatymus spausdintuve." -msgid "Hardened Steel" -msgstr "Grūdintas plienas" - -msgid "Stainless Steel" -msgstr "Nerūdijantis plienas" - -msgid "Tungsten Carbide" -msgstr "Volframo karbidas" - msgid "Brass" msgstr "Žalvaris" msgid "High flow" msgstr "Didelio srauto (High flow)" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Šiam spausdintuvui nėra „wiki“ nuorodos." -msgid "Refreshing" -msgstr "Atnaujinama" - msgid "Unavailable while heating maintenance function is on." msgstr "Neprieinama, kol įjungta kaitinimo palaikymo funkcija." @@ -6989,6 +7347,15 @@ msgstr "Pakeisti skersmenį" msgid "Configuration incompatible" msgstr "Nesuderinama konfigūracija" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Patarimai" + msgid "Sync printer information" msgstr "Sinchronizuoti spausdintuvo informaciją" @@ -7017,6 +7384,9 @@ msgstr "Spustelėkite, norėdami redaguoti profilį" msgid "Project Filaments" msgstr "Projekto gijos" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Valymo tūriai" @@ -7229,9 +7599,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Ar norite sinchronizuoti spausdintuvo informaciją ir automatiškai perjungti profilį?" -msgid "Tips" -msgstr "Patarimai" - msgid "The file does not contain any geometry data." msgstr "Faile nėra jokių geometrinių duomenų." @@ -7274,9 +7641,21 @@ msgid "" "After that, model consistency can't be guaranteed." msgstr "" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Pasirinkto objekto negalima suskaidyti." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "Išjungti automatinį nuleidimą, kad būtų išsaugota Z pozicija?\n" @@ -7301,6 +7680,9 @@ msgstr "Pasirinkite naują failą" msgid "File for the replacement wasn't selected" msgstr "" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Pasirinkite aplanką, iš kurio pakeisti" @@ -7349,6 +7731,9 @@ msgstr "Nepavyko įkelti iš naujo:" msgid "Error during reload" msgstr "Klaida įkeliant iš naujo" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Po sluoksniavimo yra įspėjimų:" @@ -8100,6 +8485,15 @@ msgstr "Išvalyti mano pasirinkimą dėl spausdintuvo profilio sinchronizavimo msgid "Graphics" msgstr "Grafika" +msgid "Smooth normals" +msgstr "Glotnios normalės" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Phong šešėliavimas" @@ -8115,20 +8509,8 @@ msgstr "Realistiniame vaizde taiko SSAO." msgid "Shadows" msgstr "Šešėliai" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "Realistiniame vaizde atvaizduoja krentančius šešėlius ant spausdinimo pagrindo." - -msgid "Smooth normals" -msgstr "Glotnios normalės" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"Realistiškam vaizdui pritaiko glotnias normales.\n" -"\n" -"Kad pakeitimai įsigaliotų, reikia rankiniu būdu perkrauti sceną (dešiniuoju pelės mygtuku spustelėkite 3D vaizdą → „Perkrauti viską“)." msgid "Anti-aliasing" msgstr "Išlyginimas" @@ -8416,6 +8798,9 @@ msgstr "Nesuderinami profiliai" msgid "My Printer" msgstr "Mano spausdintuvas" +msgid "AMS filaments" +msgstr "AMS gijos" + msgid "Left filaments" msgstr "Kairiosios gijos" @@ -8434,6 +8819,9 @@ msgstr "Pridėti / pašalinti profilius" msgid "Edit preset" msgstr "Redaguoti profilį" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Nenurodyta" @@ -8464,9 +8852,6 @@ msgstr "Pasirinkti / pašalinti spausdintuvus (sistemos profiliai)" msgid "Create printer" msgstr "Sukurti spausdintuvą" -msgid "Empty" -msgstr "Tuščias" - msgid "Incompatible" msgstr "Nesuderinama" @@ -8695,12 +9080,42 @@ msgstr "Siuntimas baigtas" msgid "Error code" msgstr "Klaidos kodas" -msgid "High Flow" -msgstr "Didelis srautas (High Flow)" +msgid "Error desc" +msgstr "Klaidos aprašymas" + +msgid "Extra info" +msgstr "Papildoma informacija" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s (%s) purkštuko srauto nustatymas nesutampa su sluoksniavimo failu (%s). Įsitikinkite, kad įstatytas purkštukas atitinka spausdintuvo nustatymus, o tada sluoksniuodami pasirinkite atitinkamą spausdintuvo profilį." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8762,8 +9177,38 @@ msgstr "Sunaudoja %d g gijos ir %d pakeitimais daugiau nei pasirinkus optimalų msgid "nozzle" msgstr "purkštukas" -msgid "both extruders" -msgstr "abu ekstruderiai" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s (%s) purkštuko srauto nustatymas nesutampa su sluoksniavimo failu (%s). Įsitikinkite, kad įstatytas purkštukas atitinka spausdintuvo nustatymus, o tada sluoksniuodami pasirinkite atitinkamą spausdintuvo profilį." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Patarimas: jei neseniai pakeitėte spausdintuvo purkštuką, eikite į „Įrenginys -> Spausdintuvo dalys“, kad pakeistumėte purkštuko nustatymą." @@ -8776,10 +9221,17 @@ msgstr "Dabartinio spausdintuvo %s skersmuo (%.1f mm) nesutampa su sluoksniavimo msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Dabartinis purkštuko skersmuo (%.1f mm) nesutampa su sluoksniavimo failu (%.1f mm). Įsitikinkite, kad įstatytas purkštukas atitinka spausdintuvo nustatymus, o tada sluoksniuodami parinkite atitinkamą spausdintuvo profilį." +msgid "both extruders" +msgstr "abu ekstruderiai" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Dabartinės medžiagos kietumas (%s) viršija %s (%s) kietumą. Patikrinkite purkštuko arba medžiagos nustatymus ir bandykite dar kartą." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] reikalauja spausdinimo aukštos temperatūros aplinkoje. Užverkite dureles." @@ -8889,9 +9341,6 @@ msgstr "Dabartinė programinė įranga palaiko ne daugiau kaip 16 medžiagų. Ga msgid "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." msgstr "Išorinės gijos tipas yra nežinomas arba nesutampa su gijos tipu sluoksniavimo faile. Įsitikinkite, kad į išorinę ritę įstatėte tinkamą giją." -msgid "Please refer to Wiki before use->" -msgstr "Prieš naudodami peržiūrėkite „Wiki“ ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Dabartinė programinė įranga nepalaiko failų perdavimo į vidinę laikmeną." @@ -9070,6 +9519,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Paspauskite, norėdami atkurti visus nustatymus pagal paskutinį išsaugotą profilį." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "" @@ -9147,9 +9599,6 @@ msgstr "" msgid "Adjust" msgstr "Sureguliuoti" -msgid "Ignore" -msgstr "Nekreipti dėmesio" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Eksperimentinė funkcija: gijos įtraukimas ir nukirpimas didesniu atstumu keičiant giją, siekiant sumažinti išvalymą (flush). Nors tai gali pastebimai sumažinti išvalymą, taip pat gali padidėti purkštuko užsikimšimo ar kitų spausdinimo komplikacijų rizika." @@ -9644,6 +10093,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "" +msgid "Select printers" +msgstr "Pasirinkite spausdintuvus" + +msgid "Select profiles" +msgstr "Pasirinkti profilius" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9888,6 +10343,12 @@ msgstr "Reikšmių perkėlimas iš kairės į dešinę" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Jei įjungta, šis dialogo langas gali būti naudojamas pasirinktoms reikšmėms perkelti iš kairiojo profilio į dešinįjį." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Pridėti failą" @@ -10143,12 +10604,8 @@ msgstr "Purkštuko informacija sėkmingai sinchronizuota." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Purkštuko ir AMS skaičiaus informacija sėkmingai sinchronizuota." -msgid "Continue to sync filaments" -msgstr "Tęsti gijų sinchronizavimą" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Atšaukti" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Gijos spalva sėkmingai sinchronizuota iš spausdintuvo." @@ -10256,6 +10713,9 @@ msgstr "Prisijungti" msgid "Login failed. Please try again." msgstr "Prisijungti nepavyko. Bandykite dar kartą." +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Reikalingas veiksmas] " @@ -10562,6 +11022,9 @@ msgstr "Spausdintuvo pavadinimas" msgid "Where to find your printer's IP and Access Code?" msgstr "Kur rasti spausdintuvo IP ir prieigos kodą?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Jungtis" @@ -10626,6 +11089,9 @@ msgstr "Pjovimo modulis" msgid "Auto Fire Extinguishing System" msgstr "Automatinė gaisro gesinimo sistema" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10644,6 +11110,9 @@ msgstr "Atnaujinti nepavyko" msgid "Update successful" msgstr "Atnaujinimas sėkmingas" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Ar tikrai norite atnaujinti? Tai užtruks apie 10 minučių. Neišjunkite maitinimo, kol spausdintuvas atnaujinamas." @@ -10745,6 +11214,9 @@ msgstr "Grupavimo klaida: " msgid " can not be placed in the " msgstr "negali būti įkeltas į " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Vidinis tiltas" @@ -11425,19 +11897,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Išorinių tiltelių kampo perrašymas.\n" -"Palikus 0, tiltelio kampas bus apskaičiuojamas automatiškai kiekvienam konkrečiam tilteliui.\n" -"Kitu atveju nurodytas kampas bus naudojamas pagal:\n" -" - absoliučiąsias koordinates;\n" -" - absoliučiąsias koordinates + modelio pasukimą: jei įjungta „Sulygiuoti užpildo kryptį su modeliu“;\n" -" - optimalų automatinį kampą + šią reikšmę: jei įjungta „Santykinis tiltelio kampas“.\n" -"\n" -"Naudokite 180° nulinėms absoliučiosioms koordinatėms." msgid "Internal bridge infill direction" msgstr "Vidinio tilto užpildo kryptis" @@ -11447,19 +11911,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"Vidinių tiltelių kampo perrašymas.\n" -"Palikus 0, tiltelio kampas bus apskaičiuojamas automatiškai kiekvienam konkrečiam tilteliui.\n" -"Kitu atveju nurodytas kampas bus naudojamas pagal:\n" -" - absoliučiąsias koordinates;\n" -" - absoliučiąsias koordinates + modelio pasukimą: jei įjungta „Sulygiuoti užpildo kryptį su modeliu“;\n" -" - optimalų automatinį kampą + šią reikšmę: jei įjungta „Santykinis tiltelio kampas“.\n" -"\n" -"Naudokite 180° nulinėms absoliučiosioms koordinatėms." msgid "Relative bridge angle" msgstr "Santykinis tiltelio kampas" @@ -11948,9 +12404,6 @@ msgstr "" "Prieš aptinkant aštrius kampus, geometrija yra supaprastinama (decimuojama). Šis parametras nurodo minimalų nuokrypio ilgį supaprastinimui atlikti.\n" "Įrašykite 0, kad išjungtumėte." -msgid "Select printers" -msgstr "Pasirinkite spausdintuvus" - msgid "upward compatible machine" msgstr "atgaliniu būdu suderinamas įrenginys" @@ -11960,9 +12413,6 @@ msgstr "Sąlyga" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "" -msgid "Select profiles" -msgstr "Pasirinkti profilius" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "" @@ -12228,6 +12678,42 @@ msgstr "Viršutinio paviršiaus tankis" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Viršutinio paviršiaus sluoksnio tankis. Nustačius 100 %, sukuriamas visiškai vientisas ir lygus viršutinis sluoksnis. Sumažinus šią reikšmę, gaunamas tekstūruotas viršutinis paviršius pagal pasirinktą raštą. Nustačius 0 %, viršutiniame sluoksnyje bus spausdinamos tik sienelės. Funkcija skirta estetiniais arba funkciniais tikslais, o ne tokioms problemoms kaip perteklinė ekstruzija (over-extrusion) spręsti." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Apatinio paviršiaus raštas" @@ -12551,12 +13037,18 @@ msgstr "Automatiškai pravalymui" msgid "Auto For Match" msgstr "Automatiškai pritaikymui" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "Pravalymo temperatūra" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatūra pravalant giją. 0 nurodo viršutinę rekomenduojamos purkštuko temperatūros diapazono ribą." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Pravalymo tūrinis greitis" @@ -12819,6 +13311,12 @@ msgstr "Gija tinkama spausdinti" msgid "The filament is printable in extruder." msgstr "Gija yra tinkama spausdinti pasirinktame ekstruderyje." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Minkštėjimo temperatūra" @@ -12878,15 +13376,13 @@ msgstr "Reto užpildo tankis" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Vidinio reto užpildo tankis. 100% paverčia visą retą užpildą vientisu užpildu ir tuomet bus naudojamas vidinio vientiso užpildo raštas." -msgid "Align infill direction to model" -msgstr "Suderinti užpildo kryptį su modeliu" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"Sulygiuoja užpildo, tiltelių, lyginimo ir paviršiaus užpildymo kryptis pagal modelio orientaciją ant pagrindo.\n" -"Kai įjungta, kryptys sukasi kartu su modeliu, kad būtų išlaikytos optimalios tvirtumo charakteristikos." msgid "Insert solid layers" msgstr "Įterpti vientisus sluoksnius" @@ -13406,6 +13902,15 @@ msgstr "Geriausia automatinio išdėstymo padėtis intervale [0,1] pagal pagrind msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Įjunkite šią parinktį, jei įrenginyje yra papildomas detalės aušinimo ventiliatorius (auxiliary fan). G-kodo komanda: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13479,6 +13984,12 @@ msgstr "" "Įjunkite, jei spausdintuvas palaiko oro filtravimą.\n" "G-kodo komanda: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "G-kodo tipas" @@ -13998,6 +14509,30 @@ msgstr "Mažiausias tuščios eigos greitis" msgid "Minimum travel speed (M205 T)" msgstr "Mažiausias tuščios eigos greitis (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Didžiausias išstūmimo pagreitis" @@ -14541,6 +15076,9 @@ msgstr "Tiesioginė pavara (Direct Drive)" msgid "Bowden" msgstr "Bowdeno vamzdelis (Bowden)" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "Įjungti dinaminį gijų susiejimą" @@ -14574,6 +15112,12 @@ msgstr "" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Gijos sugrąžinimo atgal į purkštuką greitis. Nulis reiškia tokį patį įtraukimo greitį." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Naudoti aparatinės programinės įrangos įtraukimą" @@ -14604,6 +15148,9 @@ msgstr "Sulygiuota" msgid "Aligned back" msgstr "Sulygiuota gale" +msgid "Back" +msgstr "Atgal" + msgid "Random" msgstr "Atsitiktinė" @@ -14876,6 +15423,12 @@ msgstr "" msgid "Traditional" msgstr "Tradicinis" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Temperatūros kitimas" @@ -14961,6 +15514,18 @@ msgstr "Paruošti (prime) visus spausdinimo ekstruderius" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Jei įjungta, visi spausdinimo ekstruderiai spausdinimo pradžioje bus paruošti (primed) prie priekinio spausdinimo pagrindo krašto." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Sluoksniavimo tarpo uždarymo spindulys" @@ -15388,6 +15953,45 @@ msgstr "Viršutinio apvalkalo storis" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "" @@ -15431,12 +16035,30 @@ msgstr "Pravalymo (flush) daugiklis" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Ekstruderio paruošimo (prime) tūris" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "" @@ -15722,6 +16344,57 @@ msgstr "Mažiausias sienelės plotis" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Sienelės, kuri pakeis plonus modelio elementus (pagal mažiausią elemento dydį), plotis. Jei mažiausias sienelės plotis yra mažesnis už elemento storį, sienelė taps tokio pat storio, kaip ir pats elementas. Jis išreiškiamas procentais nuo purkštuko skersmens." +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "Aptikti siaurus vidinius vientisus užpildus" @@ -16464,12 +17137,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibravimas nepalaikomas" -msgid "Error desc" -msgstr "Klaidos aprašymas" - -msgid "Extra info" -msgstr "Papildoma informacija" - msgid "Flow Dynamics" msgstr "Srauto dinamika" @@ -16665,6 +17332,12 @@ msgstr "Įveskite pavadinimą, kurį norite įrašyti į spausdintuvą." msgid "The name cannot exceed 40 characters." msgstr "Pavadinimas negali būti ilgesnis nei 40 simbolių." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Raskite geriausią liniją ant pagrindo" @@ -16754,9 +17427,6 @@ msgstr "AMS ir purkštuko informacija sinchronizuota" msgid "Nozzle Flow" msgstr "Purkštuko srautas" -msgid "Nozzle Info" -msgstr "Purkštuko informacija" - msgid "Filament position" msgstr "Gijos padėtis" @@ -16830,6 +17500,10 @@ msgstr "Sėkmingai gauti senesnį rezultatą" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "Veiksmas" @@ -18569,6 +19243,12 @@ msgstr "Spausdinimas nepavyko" msgid "Removed" msgstr "Pašalinta" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Daugiau neberodyti šio priminimo" @@ -18602,12 +19282,25 @@ msgstr "Vaizdo pamoka" msgid "(Sync with printer)" msgstr "(Sinchronizuoti su spausdintuvu)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Pjaustymas bus atliekamas pagal šį priskyrimo metodą:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Patarimas: galite vilkti gijas, kad priskirtumėte jas kitiems purkštukams." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Dabartinio pagrindo gijų priskyrimo metodą lemia išskleidžiamojo sąrašo parinktis, esanti prie pagrindo pjaustymo mygtuko." @@ -18839,9 +19532,6 @@ msgstr "Šio veiksmo atšaukti nebus galima. Tęsti?" msgid "Skipping objects." msgstr "Praleidžiami objektai." -msgid "Select Filament" -msgstr "Pasirinkti giją" - msgid "Null Color" msgstr "Be spalvos" @@ -19346,6 +20036,77 @@ msgstr "" "Venkite deformacijų (warping)\n" "Ar žinojote, kad spausdinant medžiagas, kurios yra linkusios trauktis ir riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas gali sumažinti deformacijų (warping) tikimybę?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Realistiniame vaizde atvaizduoja krentančius šešėlius ant spausdinimo pagrindo." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "Realistiškam vaizdui pritaiko glotnias normales.\n" +#~ "\n" +#~ "Kad pakeitimai įsigaliotų, reikia rankiniu būdu perkrauti sceną (dešiniuoju pelės mygtuku spustelėkite 3D vaizdą → „Perkrauti viską“)." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Tęsti gijų sinchronizavimą" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Atšaukti" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Išorinių tiltelių kampo perrašymas.\n" +#~ "Palikus 0, tiltelio kampas bus apskaičiuojamas automatiškai kiekvienam konkrečiam tilteliui.\n" +#~ "Kitu atveju nurodytas kampas bus naudojamas pagal:\n" +#~ " - absoliučiąsias koordinates;\n" +#~ " - absoliučiąsias koordinates + modelio pasukimą: jei įjungta „Sulygiuoti užpildo kryptį su modeliu“;\n" +#~ " - optimalų automatinį kampą + šią reikšmę: jei įjungta „Santykinis tiltelio kampas“.\n" +#~ "\n" +#~ "Naudokite 180° nulinėms absoliučiosioms koordinatėms." + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "Vidinių tiltelių kampo perrašymas.\n" +#~ "Palikus 0, tiltelio kampas bus apskaičiuojamas automatiškai kiekvienam konkrečiam tilteliui.\n" +#~ "Kitu atveju nurodytas kampas bus naudojamas pagal:\n" +#~ " - absoliučiąsias koordinates;\n" +#~ " - absoliučiąsias koordinates + modelio pasukimą: jei įjungta „Sulygiuoti užpildo kryptį su modeliu“;\n" +#~ " - optimalų automatinį kampą + šią reikšmę: jei įjungta „Santykinis tiltelio kampas“.\n" +#~ "\n" +#~ "Naudokite 180° nulinėms absoliučiosioms koordinatėms." + +#~ msgid "Align infill direction to model" +#~ msgstr "Suderinti užpildo kryptį su modeliu" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "Sulygiuoja užpildo, tiltelių, lyginimo ir paviršiaus užpildymo kryptis pagal modelio orientaciją ant pagrindo.\n" +#~ "Kai įjungta, kryptys sukasi kartu su modeliu, kad būtų išlaikytos optimalios tvirtumo charakteristikos." + +#~ msgid "Print" +#~ msgstr "Spausdinti" + #~ msgid "in" #~ msgstr "col." @@ -19831,9 +20592,6 @@ msgstr "" #~ msgid "Application is closing" #~ msgstr "Programa uždaroma" -#~ msgid "Delete selected" -#~ msgstr "Ištrinti pasirinkimą" - #~ msgid "Delete all" #~ msgstr "Ištrinti viską" @@ -20094,9 +20852,6 @@ msgstr "" #~ msgid "Cloud environment switched, please login again!" #~ msgstr "Pakeista debesų aplinka, prašome prisijungti iš naujo!" -#~ msgid "AMS filaments" -#~ msgstr "AMS gijos" - #~ msgid "Add/Remove filaments" #~ msgstr "Pridėti / pašalinti gijas" diff --git a/localization/i18n/nl/OrcaSlicer_nl.po b/localization/i18n/nl/OrcaSlicer_nl.po index 4a264ad25a..d70de4d1b0 100644 --- a/localization/i18n/nl/OrcaSlicer_nl.po +++ b/localization/i18n/nl/OrcaSlicer_nl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: \n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPU wordt niet ondersteund door AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -47,6 +65,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF-filamenten zijn hard en bros. Ze kunnen gemakkelijk breken of vast komen te zitten in AMS." @@ -56,10 +77,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "Standaard" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Onbekend" + +msgid "Hardened Steel" +msgstr "Gehard staal" + +msgid "Stainless Steel" +msgstr "Roestvrij staal" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "De printkop en het hot-endrek kunnen bewegen. Houd uw handen uit de buurt van de kamer." + +msgid "Warning" +msgstr "Waarschuwing" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Hot-end informatie kan onnauwkeurig zijn. Wilt u de hot-end opnieuw uitlezen? (Hot-end informatie kan veranderen tijdens het uitschakelen)." + +msgid "I confirm all" +msgstr "Ik bevestig alles" + +msgid "Re-read all" +msgstr "Alles opnieuw lezen" + +msgid "Reading the hotends, please wait." +msgstr "De hotends worden gelezen. Even geduld." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Tijdens de hot-end upgrade beweegt de printkop. Steek uw hand niet in de kamer." + +msgid "Update" +msgstr "Updaten" + msgid "Current AMS humidity" msgstr "" @@ -90,6 +191,85 @@ msgstr "Versie:" msgid "Latest version" msgstr "Nieuwste versie" +msgid "Row A" +msgstr "Rij A" + +msgid "Row B" +msgstr "Rij B" + +msgid "Toolhead" +msgstr "Printkop" + +msgid "Empty" +msgstr "Leeg" + +msgid "Error" +msgstr "Fout" + +msgid "Induction Hotend Rack" +msgstr "Inductie Hot-end rek" + +msgid "Hotends Info" +msgstr "Hot-end Informatie" + +msgid "Read All" +msgstr "Alles lezen" + +msgid "Reading " +msgstr "Lezen " + +msgid "Please wait" +msgstr "Even geduld" + +msgid "Running..." +msgstr "Bezig met uitvoeren..." + +msgid "Raised" +msgstr "Verhoogd" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "De hot-end bevindt zich in een abnormale staat en is momenteel niet beschikbaar. Ga naar 'Apparaat -> Upgrade' om de firmware bij te werken." + +msgid "Abnormal Hotend" +msgstr "Abnormale hot-end" + +msgid "Refresh" +msgstr "Vernieuwen" + +msgid "Refreshing" +msgstr "Vernieuwen" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Hotendstatus abnormaal, momenteel niet beschikbaar. Werk de firmware bij en probeer het opnieuw." + +msgid "Cancel" +msgstr "Annuleren" + +msgid "Jump to the upgrade page" +msgstr "Ga naar de upgradepagina" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Versie" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Gebruikte tijd: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Dynamische nozzles zijn toegewezen op de huidige plaat. Het selecteren van een hotend wordt niet ondersteund." + +msgid "Hotend Rack" +msgstr "Hot-end rek" + +msgid "ToolHead" +msgstr "Printkop" + +msgid "Nozzle information needs to be read" +msgstr "Nozzle-informatie moet worden uitgelezen" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Ondersteuning (Support) tekenen" @@ -162,6 +342,12 @@ msgstr "Vullen" msgid "Gap Fill" msgstr "Gatvulling" +msgid "Vertical" +msgstr "Verticaal" + +msgid "Horizontal" +msgstr "Horizontaal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Staat alleen schilderen toe op facetten geselecteerd met: \"%1%\"" @@ -257,12 +443,6 @@ msgstr "Driehoek" msgid "Height Range" msgstr "Hoogtebereik" -msgid "Vertical" -msgstr "Verticaal" - -msgid "Horizontal" -msgstr "Horizontaal" - msgid "Remove painted color" msgstr "Geschilderd kleur verwijderen" @@ -327,6 +507,7 @@ msgstr "Roteren" msgid "Optimize orientation" msgstr "Oriëntatie optimaliseren" +msgctxt "Verb" msgid "Scale" msgstr "Schalen" @@ -371,6 +552,9 @@ msgstr "Schaalverhoudingen" msgid "Object operations" msgstr "Objectbewerkingen" +msgid "Scale" +msgstr "Schalen" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Volumebewerkingen" @@ -422,6 +606,10 @@ msgstr "" msgid "Reset current rotation to real zeros." msgstr "" +msgctxt "Noun" +msgid "Scale" +msgstr "Schalen" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Maat" @@ -599,9 +787,6 @@ msgstr "" msgid "Confirm connectors" msgstr "Verbindingen bevestigen" -msgid "Cancel" -msgstr "Annuleren" - msgid "Flip cut plane" msgstr "" @@ -642,12 +827,12 @@ msgstr "In delen knippen" msgid "Reset cutting plane and remove connectors" msgstr "" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Knippen uitvoeren" -msgid "Warning" -msgstr "Waarschuwing" - msgid "Invalid connectors detected" msgstr "Onjuiste verbindingen gevonden" @@ -678,6 +863,13 @@ msgstr "" msgid "Connector" msgstr "Verbinding" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Snij met behulp van vlak" @@ -725,9 +917,6 @@ msgstr "Vereenvoudigen" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Vereenvoudiging is momenteel alleen toegestaan wanneer één enkel onderdeel is geselecteerd" -msgid "Error" -msgstr "Fout" - msgid "Extra high" msgstr "Extra hoog" @@ -1978,6 +2167,9 @@ msgstr "" msgid "Loading user preset" msgstr "Gebruikersvoorinstelling laden" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -1991,6 +2183,18 @@ msgstr "Kies de taal" msgid "Language" msgstr "Taal" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2621,6 +2825,45 @@ msgstr "Klik op het pictogram om de kleur van het object te bewerken" msgid "Click the icon to shift this object to the bed" msgstr "Klik op het pictogram om dit object te verschuiven op het printbed" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Bestand laden" @@ -2630,6 +2873,9 @@ msgstr "Fout!" msgid "Failed to get the model data in the current file." msgstr "Kon de modelinformatie niet laden uit het huidige bestand." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Algemeen" @@ -2642,6 +2888,12 @@ msgstr "Schakel over naar de instellingsmodus per object om procesinstellingen v msgid "Remove paint-on fuzzy skin" msgstr "" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "" + msgid "Delete connector from object which is a part of cut" msgstr "Verwijder verbinding van object dat deel is van een knipbewerking" @@ -2672,12 +2924,24 @@ msgstr "Verwijder alle vberbindingen" msgid "Deleting the last solid part is not allowed." msgstr "Het is niet toegestaand om het laaste vaste deel te verwijderen." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "" +msgid "Split to parts" +msgstr "Opsplitsten in delen" + msgid "Assembly" msgstr "Montage" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "" @@ -2711,6 +2975,9 @@ msgstr "Hoogtebereiken" msgid "Settings for height range" msgstr "Instellingen voor hoogtebereik" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Laag" @@ -2733,6 +3000,9 @@ msgstr "" msgid "Choose part type" msgstr "Kies het onderdeel type" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Voer nieuwe naam in" @@ -2760,6 +3030,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Extra procesvoorinstelling" @@ -2769,9 +3042,6 @@ msgstr "Verwijder parameter" msgid "to" msgstr "naar" -msgid "Remove height range" -msgstr "" - msgid "Add height range" msgstr "" @@ -2983,6 +3253,9 @@ msgstr "Kies een AMS-sleuf en druk op de knop \"Laden\" of \"Lossen\" om automat msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3105,6 +3378,24 @@ msgstr "Bevestig geëxtrudeerd" msgid "Check filament location" msgstr "Controleer de positie van het filament" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3158,6 +3449,62 @@ msgstr "Ontwikkelmodus" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Stel het aantal nozzles in" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Fout: Kan niet beide nozzles op nul instellen." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Fout: Het aantal nozzles mag niet meer zijn dan %d." + +msgid "Confirm" +msgstr "Bevestigen" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "Nozzle selectie" + +msgid "Available Nozzles" +msgstr "Beschikbare nozzles" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "Synchroniseer nozzlestatus" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Waarschuwing: Het combineren van nozzle-diameters in één print wordt niet ondersteund. Als de geselecteerde maat slechts op één extruder aanwezig is, wordt het printen met een enkele extruder afgedwongen." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Vernieuwen %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Onbekende nozzle gedetecteerd. Vernieuw om informatie bij te werken (niet-vernieuwde nozzles worden tijdens het slicen uitgesloten). Controleer nozzle diameter en debiet tegen de weergegeven waarden." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Onbekende nozzle gedetecteerd. Vernieuw om bij te werken (niet-vernieuwde mondstukken worden overgeslagen bij het slicen)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Bevestigt u of de vereiste nozzle diameter en doorvoersnelheid overeenkomen met de momenteel weergegeven waarden." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Uw printer heeft verschillende nozzles. Selecteer een spuitmondje voor deze print." + +msgid "Ignore" +msgstr "Negeer" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3490,15 +3837,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Versie" - msgid "AMS Materials Setting" msgstr "AMS Materiaal instellingen" -msgid "Confirm" -msgstr "Bevestigen" - msgid "Close" msgstr "Sluiten" @@ -3519,12 +3860,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "De invoerwaarde moet groter zijn dan %1% en kleiner dan %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Factoren van Flow Dynamics Calibration" +msgid "Wiki Guide" +msgstr "" + msgid "PA Profile" msgstr "PA-profiel" @@ -3611,7 +3952,7 @@ msgstr "Kalibratie voltooid. Zoek de meest uniforme extrusielijn op uw hotbed, z msgid "Save" msgstr "Bewaar" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Achterzijde" @@ -3686,6 +4027,19 @@ msgstr "Rechter nozzle" msgid "Nozzle" msgstr "Mondstuk" +msgid "Select Filament && Hotends" +msgstr "Selecteer Filament && hot-ends" + +msgid "Select Filament" +msgstr "Selecteer filament" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Printen met de huidige nozzle kan een extra %0.2f g afval opleveren." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4384,9 +4738,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "Onbekend" - msgid "Update successful." msgstr "Update gelukt." @@ -4898,9 +5249,6 @@ msgstr "" msgid "Regroup filament" msgstr "" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "tot" @@ -4937,8 +5285,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Ventilator snelheid (%)" -msgid "Temperature (°C)" -msgstr "Temperatuur (°C)" +msgid "Temperature (℃)" +msgstr "Temperatuur (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Volumestroom (mm³/s)" @@ -4956,9 +5304,6 @@ msgstr "Filament wisselingen" msgid "Options" msgstr "Opties" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "Kosten" @@ -4971,6 +5316,7 @@ msgstr "Toolwisselingen" msgid "Color change" msgstr "Kleur veranderen" +msgctxt "Noun" msgid "Print" msgstr "" @@ -5129,11 +5475,15 @@ msgstr "Vermijd het extrusie kalibratie gebied" msgid "Align to Y axis" msgstr "Uitlijnen op Y-as" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Achterzijde" + +msgctxt "Camera View" msgid "Left" msgstr "Links" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Rechts" @@ -5158,9 +5508,6 @@ msgstr "Rangschikt de objecten op de gelecteerde printbedden" msgid "Split to objects" msgstr "Opsplitsen in objecten" -msgid "Split to parts" -msgstr "Opsplitsten in delen" - msgid "Assembly View" msgstr "Montageweergave" @@ -5457,6 +5804,10 @@ msgstr "Printplaat" msgid "Export G-code file" msgstr "G-codebestand exporteren" +msgctxt "Verb" +msgid "Print" +msgstr "" + msgid "Export plate sliced file" msgstr "Exporteer plate sliced bestand" @@ -5630,15 +5981,6 @@ msgstr "Huidige configuratie exporteren naar bestanden" msgid "Export" msgstr "Exporteren" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Stop" @@ -5755,6 +6097,15 @@ msgstr "Weergave" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5875,6 +6226,9 @@ msgstr "Exporteer resultaat" msgid "Select profile to load:" msgstr "Selecteer het te laden profiel:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6036,9 +6390,6 @@ msgstr "Download geselecteerde bestanden van de printer." msgid "Batch manage files." msgstr "Batchbeheer van bestanden." -msgid "Refresh" -msgstr "Vernieuwen" - msgid "Reload file list from printer." msgstr "" @@ -6349,6 +6700,9 @@ msgstr "Print Opties" msgid "Safety Options" msgstr "Veiligheidsopties" +msgid "Hotends" +msgstr "Hot-ends" + msgid "Lamp" msgstr "Licht" @@ -6382,6 +6736,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6432,9 +6792,6 @@ msgstr "Dit is alleen van kracht tijdens het printen" msgid "Silent" msgstr "Stille" -msgid "Standard" -msgstr "Standaard" - msgid "Sport" msgstr "" @@ -6468,6 +6825,12 @@ msgstr "Foto toevoegen" msgid "Delete Photo" msgstr "Foto verwijderen" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Indienen" @@ -6644,6 +7007,9 @@ msgstr "" msgid "Don't show this dialog again" msgstr "" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "3D-muis losgekoppeld." @@ -6898,26 +7264,17 @@ msgstr "Doorstroming" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "Gehard staal" - -msgid "Stainless Steel" -msgstr "Roestvrij staal" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "Messing" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" -msgstr "Vernieuwen" +msgid "No wiki link available for this printer." +msgstr "" msgid "Unavailable while heating maintenance function is on." msgstr "" @@ -7041,6 +7398,15 @@ msgstr "" msgid "Configuration incompatible" msgstr "De configuratie is niet geschikt" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "" + msgid "Sync printer information" msgstr "" @@ -7067,6 +7433,9 @@ msgstr "Klik om de instelling te veranderen" msgid "Project Filaments" msgstr "Projectfilamenten" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volumes schoonmaken" @@ -7290,9 +7659,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "" - msgid "The file does not contain any geometry data." msgstr "Het bestand bevat geen geometriegegevens." @@ -7343,9 +7709,21 @@ msgstr "" "This action will break a cut correspondence.\n" "After that model consistency can't be guaranteed." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Het geselecteerde object kan niet opgesplitst worden." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7372,6 +7750,9 @@ msgstr "Selecteer een nieuw bestand" msgid "File for the replacement wasn't selected" msgstr "Het bestand voor de vervanging is niet geselecteerd" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7418,6 +7799,9 @@ msgstr "Kan niet herladen:" msgid "Error during reload" msgstr "Fout tijdens herladen" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Er zijn waarschuwingen na het slicen van modellen:" @@ -8173,6 +8557,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8188,16 +8581,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8479,6 +8863,9 @@ msgstr "Onbruikbare voorinstellingen" msgid "My Printer" msgstr "Mijn printer" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8498,6 +8885,9 @@ msgstr "Voorinstellingen toevoegen/verwijderen" msgid "Edit preset" msgstr "Voorinstelling bewerken" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Niet gespecificeerd" @@ -8529,9 +8919,6 @@ msgstr "Printers selecteren/verwijderen (systeemvoorinstellingen)" msgid "Create printer" msgstr "Printer maken" -msgid "Empty" -msgstr "Leeg" - msgid "Incompatible" msgstr "Incompatibel" @@ -8756,11 +9143,41 @@ msgstr "versturen gelukt" msgid "Error code" msgstr "Foutcode" -msgid "High Flow" +msgid "Error desc" +msgstr "Fout beschrijving" + +msgid "Extra info" +msgstr "Extra informatie" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, c-format, boost-format @@ -8825,7 +9242,37 @@ msgstr "" msgid "nozzle" msgstr "" -msgid "both extruders" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8839,10 +9286,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -8953,9 +9407,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -9139,6 +9590,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Klik om alle instellingen terug te zetten naar de laatst opgeslagen voorinstelling." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Prime tower is vereist voor het wisselen van de nozzle. Er kunnen fouten in het model zitten zonder prime tower. Weet je zeker dat je prime tower wilt uitschakelen?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Een Prime-toren is vereist voor een vloeiende timeplase-modus. Er kunnen gebreken ontstaan aan het model zonder prime-toren. Weet je zeker dat je de prime-toren wilt uitschakelen?" @@ -9213,9 +9667,6 @@ msgstr "Automatisch aanpassen aan het ingestelde bereik?\n" msgid "Adjust" msgstr "Aanpassen" -msgid "Ignore" -msgstr "Negeer" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Experimentele functie: Het filament op grotere afstand terugtrekken en afsnijden tijdens filamentwisselingen om flush te minimaliseren. Hoewel het het doorspoelen aanzienlijk kan verminderen, kan het ook het risico op een verstopt mondstuk of andere printcomplicaties vergroten." @@ -9719,6 +10170,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Weet u zeker dat u de geselecteerde preset wilt %1%?" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9938,6 +10395,12 @@ msgstr "" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Bestand toevoegen" @@ -10185,13 +10648,9 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" +msgid "Do you want to continue to sync filaments?" msgstr "" -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Annuleren" - msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10298,6 +10757,9 @@ msgstr "Inloggen" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10612,6 +11074,9 @@ msgstr "" msgid "Where to find your printer's IP and Access Code?" msgstr "Waar vind je het IP-adres en de toegangscode van je printer?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Verbinden" @@ -10676,6 +11141,9 @@ msgstr "" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10694,6 +11162,9 @@ msgstr "Bijwerken mislukt" msgid "Update successful" msgstr "Update geslaagd" +msgid "Hotends on Rack" +msgstr "Hot-ends op rek" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Weet u zeker dat u de firmware wilt bijwerken? Dit duurt ongeveer 10 minuten. Zet de printer NIET uit tijdens dit proces." @@ -10802,6 +11273,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "" @@ -11488,7 +11962,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11502,7 +11976,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11888,9 +12362,6 @@ msgid "" "0 to deactivate." msgstr "" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "opwaarts compatibele machine" @@ -11901,9 +12372,6 @@ msgstr "Voorwaarde" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Een waar/niet waar aanduiding die gebruik maakt van configuratiewaarden van een actief printerprofiel. Als deze aanduiding op waar staat, wordt dit profiel beschouwd als geschikt voor het actieve printerprofiel." -msgid "Select profiles" -msgstr "" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Een waar/niet waar aanduiding die gebruik maakt van configuratiewaarden van een actief printprofiel. Als deze aanduiding op waar staat, wordt dit profiel beschouwd als geschikt voor het actieve printprofiel." @@ -12146,6 +12614,42 @@ msgstr "" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Bodem oppvlakte patroon" @@ -12437,12 +12941,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "Handleiding nozzle" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12700,6 +13210,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Verzachtingstemperatuur" @@ -12762,12 +13278,12 @@ msgstr "Vulling percentage" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13269,6 +13785,15 @@ msgstr "Beste automatisch schikkende positie in het bereik [0,1] met betrekking msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13329,6 +13854,12 @@ msgid "" "G-code command: M106 P3 S(0-255)" msgstr "" +msgid "Use cooling filter" +msgstr "Gebruik koelfilter" + +msgid "Enable this if printer support cooling filter" +msgstr "Schakel dit in als de printer koelingsfilter ondersteunt" + msgid "G-code flavor" msgstr "G-code type" @@ -13841,6 +14372,30 @@ msgstr "Minimale snelheid voor verplaatsing" msgid "Minimum travel speed (M205 T)" msgstr "Minimale snelheid voor verplaatsing (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Maximale kracht van de Y-as" + +msgid "The allowed maximum output force of Y axis" +msgstr "De maximaal toegestane uitgangskracht van de Y-as" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Bedmassa van de Y-as" + +msgid "The machine bed mass load of Y axis" +msgstr "De massabelasting van het machinebed op de Y-as" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "De maximaal toegestane printmassa" + +msgid "The allowed max printed mass on a plate" +msgstr "De maximaal toegestane printmassa op een plaat" + msgid "Maximum acceleration for extruding" msgstr "Maximale extruding versnelling " @@ -14361,6 +14916,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Hybride" + msgid "Enable filament dynamic map" msgstr "" @@ -14396,6 +14954,12 @@ msgstr "Snelheid van terugtrekken (deretraction)" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Gebruik firmware retractie" @@ -14427,6 +14991,10 @@ msgstr "Uitgelijnd" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Achterzijde" + msgid "Random" msgstr "Willekeurig" @@ -14683,6 +15251,12 @@ msgstr "Als de vloeiende of traditionele modus is geselecteerd, wordt voor elke msgid "Traditional" msgstr "Traditioneel" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Temperatuur variatie" @@ -14770,6 +15344,18 @@ msgstr "Veeg alle printextruders af" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Alle extruders worden afgeveegd aan de voorzijde van het printbed aan het begin van de print als dit is ingeschakeld." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Sluitingsradius van de gap" @@ -15144,7 +15730,7 @@ msgid "" msgstr "" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15199,6 +15785,45 @@ msgstr "Dikte bovenkant" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Het aantal bovenste solide lagen wordt verhoogd tijdens het slicen als de totale dikte van de bovenste lagen lager is dan deze waarde. Dit zorgt ervoor dat de schaal niet te dun is bij een lage laaghoogte. 0 betekend dat deze instelling niet actief is en dat de dikte van de bovenkant bepaald wordt door het aantal bodem lagen." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Dit is de snelheid waarmee verplaatsingen zullen worden gedaan." @@ -15242,6 +15867,12 @@ msgstr "Flush-vermenigvuldiger" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "De werkelijke flushvolumes zijn gelijk aan de flush vermenigvuldigingswaarde vermenigvuldigd met de flushvolumes in de tabel." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Prime-volume" @@ -15249,6 +15880,18 @@ msgstr "Prime-volume" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Dit is het volume van het materiaal dat de extruder op de prime toren uitwerpt." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Dit is de breedte van de prime toren." @@ -15520,6 +16163,57 @@ msgstr "Minimale wandbreedte" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Breedte van de muur die dunne delen (volgens de minimale functiegrootte) van het model zal vervangen. Als de minimale wandbreedte dunner is dan de dikte van het element, wordt de muur net zo dik als het object zelf. Dit wordt uitgedrukt als een percentage ten opzichte van de diameter van het mondstuk" +msgid "Hotend change time" +msgstr "Tijd voor hot-end wisseling" + +msgid "Time to change hotend." +msgstr "Tijd om de hot-end te vervangen." + +msgid "Hotend change" +msgstr "Hot-end vervangen" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Als u de hot-end verwisselt, is het aan te raden om een bepaalde lengte filament uit de oorspronkelijke nozzle te extruderen. Dit helpt het druipen van de nozzle te minimaliseren." + +msgid "Extruder change" +msgstr "Extruder wisselen" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Om doorsijpelen te voorkomen, zal de nozzle na het rammen gedurende een bepaalde tijd een omgekeerde beweging uitvoeren. De instelling bepaalt de rijtijd." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Om doorsijpelen te voorkomen, wordt de temperatuur van de nozzle afgekoeld tijdens het rammen. Daarom moet de rammingtijd groter zijn dan de afkoeltijd. 0 betekent uitgeschakeld." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "De maximale volumetrische snelheid voor het rammen vóór extruderwissel, waarbij -1 betekent dat de maximale volumetrische snelheid wordt gebruikt." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Om druipen te voorkomen, wordt de nozzle-temperatuur tijdens het rammen afgekoeld. Opmerking: alleen een koelcommando en ventilatoractivatie worden geactiveerd, het bereiken van de doeldtemperatuur wordt niet gegarandeerd. 0 betekent uitgeschakeld." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "De maximale volumetrische snelheid voor het rammen vóór een hot-end wissel, waarbij -1 betekent dat de maximale volumetrische snelheid wordt gebruikt." + +msgid "length when change hotend" +msgstr "lengte bij het verwisselen van de hot-end" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Wanneer deze terugtrekwaarde wordt aangepast, wordt deze gebruikt als de hoeveelheid filament die binnen de hot-end wordt teruggetrokken voordat de hot-ends worden verwisseld." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Het volume materiaal dat nodig is om de extruder te primen voor een hot-end wissel op de toren." + +msgid "Preheat temperature delta" +msgstr "Voorverwarmingstemperatuurverschil" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Temperatuurverschil toegepast tijdens het voorverwarmen vóór het wisselen van gereedschap." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Detecteer dichte interne solide vulling (infill)" @@ -16268,12 +16962,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibratie wordt niet ondersteund" -msgid "Error desc" -msgstr "Fout beschrijving" - -msgid "Extra info" -msgstr "Extra informatie" - msgid "Flow Dynamics" msgstr "Flowdynamiek" @@ -16462,6 +17150,12 @@ msgstr "Voer de naam in die u op de printer wilt opslaan." msgid "The name cannot exceed 40 characters." msgstr "De naam mag niet langer zijn dan 40 tekens." +msgid "Nozzle ID" +msgstr "Nozzle-ID" + +msgid "Standard Flow" +msgstr "Standaardstroom" + msgid "Please find the best line on your plate" msgstr "Zoek de beste regel op je bord" @@ -16552,9 +17246,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "filament positie" @@ -16629,6 +17320,10 @@ msgstr "Succes om geschiedenisresultaat te krijgen" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "De vorige Flow Dynamics kalibratierecords vernieuwen" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Opmerking: Het nummer van de hot-end op de %s is gekoppeld aan de houder. Wanneer de hot-end naar een nieuwe houder wordt verplaatst, wordt het nummer automatisch bijgewerkt." + msgid "Action" msgstr "Actie" @@ -18323,6 +19018,12 @@ msgstr "" msgid "Removed" msgstr "Verwijderd" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -18356,12 +19057,25 @@ msgstr "Instructie video" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -18594,9 +19308,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "Selecteer filament" - msgid "Null Color" msgstr "Geen kleur" @@ -19115,6 +19826,10 @@ msgstr "" "Kromtrekken voorkomen\n" "Wist je dat bij het printen van materialen die gevoelig zijn voor kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het warmtebed de kans op kromtrekken kan verkleinen?" +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Annuleren" + #~ msgid "in" #~ msgstr "in" @@ -19806,9 +20521,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Kan niet starten zonder SD-kaart." -#~ msgid "Update" -#~ msgstr "Updaten" - #~ msgid "Sensitivity of pausing is" #~ msgstr "De gevoeligheid van het pauzeren is" @@ -20321,10 +21033,6 @@ msgstr "" #~ msgid "Thick bridges" #~ msgstr "Dikke bruggen" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Schalen" - #~ msgid "Z-hop when retract" #~ msgstr "Z-hop tijdens terugtrekken (retraction)" diff --git a/localization/i18n/pl/OrcaSlicer_pl.po b/localization/i18n/pl/OrcaSlicer_pl.po index 63ea040cc2..df50298f17 100644 --- a/localization/i18n/pl/OrcaSlicer_pl.po +++ b/localization/i18n/pl/OrcaSlicer_pl.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer 2.3.0-rc\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: \n" "Last-Translator: Krzysztof Morga <>\n" "Language-Team: \n" @@ -36,6 +36,24 @@ msgstr "TPU nie jest obsługiwane przez AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS nie obsługuje \"Bambu Lab PET-CF\"." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Przed drukiem z TPU należy wykonać cold pull, aby uniknąć zatkania. Można użyć opcji cold pull na drukarce." @@ -48,6 +66,9 @@ msgstr "Wilgotny PVA jest elastyczny i może utknąć w ekstruderze. Przed użyc msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "Chropowata powierzchnia PLA Glow może przyspieszyć zużycie systemu AMS, w szczególności wewnętrznych elementów AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Filamenty CF/GF są twarde i kruche, łatwo je złamać i zaklinować w AMS, proszę używać ostrożnie." @@ -57,10 +78,90 @@ msgstr "PPS-CF jest kruchy i może pęknąć w wygiętym fragmencie rurki PTFE n msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF jest kruchy i może pęknąć w wygiętym fragmencie rurki PTFE nad głowicą." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s nie jest obsługiwane przez ekstruder %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Wysoki przepływ" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "TPU wysoki przepływ" + +msgid "Unknown" +msgstr "Nieznany" + +msgid "Hardened Steel" +msgstr "Stal hartowana" + +msgid "Stainless Steel" +msgstr "Stal nierdzewna" + +msgid "Tungsten Carbide" +msgstr "Węglik wolframu" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Głowica i uchwyt na hotendy mogą się poruszać. Proszę trzymać ręce z dala od komory." + +msgid "Warning" +msgstr "Ostrzeżenie" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Informacje o hotendzie mogą być niedokładne. Czy chcesz ponownie odczytać dane o hotendzie? (Informacje o hotendzie mogły się zmienić podczas wyłączenia zasilania)." + +msgid "I confirm all" +msgstr "Potwierdzam wszystko" + +msgid "Re-read all" +msgstr "Odczytaj ponownie wszystko" + +msgid "Reading the hotends, please wait." +msgstr "Odczytywanie hotendów, proszę czekać." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Podczas aktualizacji hotendu, głowica będzie się poruszać. Nie wkładaj rąk do komory." + +msgid "Update" +msgstr "Aktualizacja" + msgid "Current AMS humidity" msgstr "Aktualna wilgotność AMS" @@ -91,6 +192,85 @@ msgstr "Wersja:" msgid "Latest version" msgstr "Najnowsza wersja" +msgid "Row A" +msgstr "Rząd A" + +msgid "Row B" +msgstr "Rząd B" + +msgid "Toolhead" +msgstr "Głowica" + +msgid "Empty" +msgstr "Puste" + +msgid "Error" +msgstr "Błąd" + +msgid "Induction Hotend Rack" +msgstr "Indukcyjny uchwyt na hotendy" + +msgid "Hotends Info" +msgstr "Informacje o hotendach" + +msgid "Read All" +msgstr "Odczytaj wszystko" + +msgid "Reading " +msgstr "Odczyt " + +msgid "Please wait" +msgstr "Proszę czekać" + +msgid "Running..." +msgstr "Uruchamianie..." + +msgid "Raised" +msgstr "Podniesiony" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Hotend jest w nieprawidłowym stanie i jest obecnie niedostępny. Przejdź do \"Urządzenie -> Aktualizacja\" w celu aktualizacji firmware" + +msgid "Abnormal Hotend" +msgstr "Nieprawidłowy hotend" + +msgid "Refresh" +msgstr "Odśwież" + +msgid "Refreshing" +msgstr "Odświeżanie" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Stan hotendu jest nieprawidłowy i obecnie nie jest dostępny. Proszę zaktualizować firmware i spróbować ponownie." + +msgid "Cancel" +msgstr "Anuluj" + +msgid "Jump to the upgrade page" +msgstr "Przejdź do strony aktualizacji" + +msgid "SN" +msgstr "Numer seryjny" + +msgid "Version" +msgstr "Wersja" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Czas użycia: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Dysze dynamiczne zostały przydzielane do bieżącej płyty. Wybór hotendu nie jest obsługiwany." + +msgid "Hotend Rack" +msgstr "Uchwyt na hotendy" + +msgid "ToolHead" +msgstr "Głowica" + +msgid "Nozzle information needs to be read" +msgstr "Należy odczytać informacje o dyszy" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Malowanie podpór" @@ -163,6 +343,13 @@ msgstr "Wypełnienie" msgid "Gap Fill" msgstr "Wypełnienie szczelin" +# +++++++++++++++++++++ +msgid "Vertical" +msgstr "Pionowa linia" + +msgid "Horizontal" +msgstr "Pozioma linia" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Pozwala malować tylko na wybranych powierzchniach za pomocą: „%1%”" @@ -258,13 +445,6 @@ msgstr "Trójkąt" msgid "Height Range" msgstr "Przedział" -# +++++++++++++++++++++ -msgid "Vertical" -msgstr "Pionowa linia" - -msgid "Horizontal" -msgstr "Pozioma linia" - msgid "Remove painted color" msgstr "Usuń pomalowany kolor" @@ -329,6 +509,7 @@ msgstr "Uchwyt-Obróć" msgid "Optimize orientation" msgstr "Optymalizuj orientację" +msgctxt "Verb" msgid "Scale" msgstr "Skaluj" @@ -373,6 +554,9 @@ msgstr "Współczynniki skali" msgid "Object operations" msgstr "Operacje na obiekcie" +msgid "Scale" +msgstr "Skaluj" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Operacje na objętości" @@ -424,6 +608,10 @@ msgstr "Zresetuj bieżący obrót do wartości ustawionej przy otwarciu narzędz msgid "Reset current rotation to real zeros." msgstr "Zresetuj bieżący obrót do wartości zerowej." +msgctxt "Noun" +msgid "Scale" +msgstr "Skaluj" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Rozmiar" @@ -606,9 +794,6 @@ msgstr "Proporcja przestrzeni do promienia" msgid "Confirm connectors" msgstr "Potwierdź łączniki" -msgid "Cancel" -msgstr "Anuluj" - msgid "Flip cut plane" msgstr "Obróć przekrój" @@ -649,12 +834,12 @@ msgstr "Podziel na części" msgid "Reset cutting plane and remove connectors" msgstr "Resetuj płaszczyznę przecinania i usuń łączniki" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Wykonaj cięcie" -msgid "Warning" -msgstr "Ostrzeżenie" - msgid "Invalid connectors detected" msgstr "Wykryto nieprawidłowe łączniki" @@ -687,6 +872,13 @@ msgstr "Płaszczyzna cięcia z rowkiem jest nieprawidłowa" msgid "Connector" msgstr "Łącznik" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Cięcie płaszczyzną" @@ -734,9 +926,6 @@ msgstr "Uprość" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Obecnie upraszczanie jest dozwolone tylko przy wybranej pojedynczej części" -msgid "Error" -msgstr "Błąd" - msgid "Extra high" msgstr "Bardzo wysoki" @@ -2001,6 +2190,9 @@ msgstr "" msgid "Loading user preset" msgstr "Ładowanie ustawień użytkownika" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2014,6 +2206,18 @@ msgstr "Wybierz język" msgid "Language" msgstr "Język" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2650,6 +2854,45 @@ msgstr "Kliknij ikonę, aby edytować kolory obiektu" msgid "Click the icon to shift this object to the bed" msgstr "Kliknij ikonę, aby przenieść ten obiekt na stół" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Wczytywanie pliku" @@ -2659,6 +2902,9 @@ msgstr "Błąd!" msgid "Failed to get the model data in the current file." msgstr "Nie udało się uzyskać danych modelu z bieżącego pliku." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Źródłowy" @@ -2671,6 +2917,12 @@ msgstr "Przełącz się w tryb edycji ustawień druku dla każdego obiektu, aby msgid "Remove paint-on fuzzy skin" msgstr "Usuń malowanie Fuzzy Skin" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Usuń zakres wysokości" + msgid "Delete connector from object which is a part of cut" msgstr "Usuń łącznik z obiektu będącego częścią przecięcia" @@ -2701,12 +2953,24 @@ msgstr "Usuń wszystkie łączniki" msgid "Deleting the last solid part is not allowed." msgstr "Usunięcie ostatniej części bryły jest niedozwolone." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Obiekt docelowy zawiera tylko jedną i nie może zostać podzielony." +msgid "Split to parts" +msgstr "Podziel na części" + msgid "Assembly" msgstr "Złożenie" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Usuń informacje o łącznikach" @@ -2740,6 +3004,9 @@ msgstr "Zakresy wysokości" msgid "Settings for height range" msgstr "Ustawienia dla zakresu wysokości" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Warstwa" @@ -2762,6 +3029,9 @@ msgstr "Rodzaj:" msgid "Choose part type" msgstr "Wybierz rodzaj części" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Wprowadź nową nazwę" @@ -2791,6 +3061,9 @@ msgstr "\"%s\" przekroczy 1 milion ścian po tym podziale, co może wydłużyć msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "Siatka części \"%s\" zawiera błędy. Proszę najpierw ją naprawić." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Dodatkowa predefinicja procesu" @@ -2800,9 +3073,6 @@ msgstr "Usuń parametr" msgid "to" msgstr "do" -msgid "Remove height range" -msgstr "Usuń zakres wysokości" - msgid "Add height range" msgstr "Dodaj zakres wysokości" @@ -3014,6 +3284,9 @@ msgstr "Wybierz gniazdo AMS, a następnie naciśnij przycisk „Ładuj” lub msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Nie rozpoznano typu filamentu, a jest on wymagany do przeprowadzenia tej akcji. Proszę wprowadzić informacje o filamencie." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Zmiana prędkości wentylatora podczas drukowania może mieć wpływ na jakość wydruku. Wybierz z rozwagą." @@ -3138,6 +3411,24 @@ msgstr "Potwierdź wytłaczanie" msgid "Check filament location" msgstr "Sprawdź lokalizację filamentu" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Maksymalna temperatura nie może przekroczyć " @@ -3191,6 +3482,62 @@ msgstr "Tryb deweloperski" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Proszę ustawić liczbę dysz" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Błąd: Nie można ustawić liczby obu dysz na zero." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Błąd: Liczba dysz nie może przekraczać %d." + +msgid "Confirm" +msgstr "Potwierdź" + +msgid "Extruder" +msgstr "Ekstruder" + +msgid "Nozzle Selection" +msgstr "Wybór dyszy" + +msgid "Available Nozzles" +msgstr "Dostępne dysze" + +msgid "Nozzle Info" +msgstr "Informacje o dyszy" + +msgid "Sync Nozzle status" +msgstr "Synchronizuj status dyszy" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Uwaga: Mieszanie średnic dysz w jednym wydruku nie jest obsługiwane. Jeśli wybrany rozmiar jest dostępny tylko na jednym ekstruderze, zostanie wymuszony druk jednym ekstruderem." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Odśwież %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Wykryto nieznaną dyszę. Odśwież informacje (dysze nieodświeżone zostaną pominięte podczas cięcia). Sprawdź średnicę dyszy oraz przepływ względem wyświetlanych wartości." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Wykryto nieznaną dyszę. Odśwież, aby zaktualizować (nieodświeżone dysze zostaną pominięte podczas cięcia)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Sprawdź, czy wymagana średnica dyszy i natężenie przepływu odpowiadają aktualnie wyświetlanym wartościom." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "W Twojej drukarce są zainstalowane różne dysze. Wybierz dyszę do tego wydruku." + +msgid "Ignore" +msgstr "Ignoruj" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3524,15 +3871,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Wersja" - msgid "AMS Materials Setting" msgstr "Ustawienia filamentów AMS" -msgid "Confirm" -msgstr "Potwierdź" - msgid "Close" msgstr "Zamknij" @@ -3553,12 +3894,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "Wartość wejściowa powinna być większa niż %1% i mniejsza niż %2%" -msgid "SN" -msgstr "Numer seryjny" - msgid "Factors of Flow Dynamics Calibration" msgstr "współczynnik kalibracji dynamiki przepływu" +msgid "Wiki Guide" +msgstr "" + msgid "PA Profile" msgstr "Profil PA" @@ -3649,7 +3990,7 @@ msgstr "Kalibracja zakończona. Proszę znaleźć na płycie roboczej, linie eks msgid "Save" msgstr "Zapisz" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Tył" @@ -3733,6 +4074,19 @@ msgstr "Prawa dysza" msgid "Nozzle" msgstr "Dysza" +msgid "Select Filament && Hotends" +msgstr "Wybierz filament i hotendy" + +msgid "Select Filament" +msgstr "Wybierz filament" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Drukowanie przy użyciu obecnej dyszy może powodować powstanie dodatkowych %0.2f g odpadów." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Uwaga: typ filamentu(%s) nie jest zgodny z typem filamentu(%s) w pociętym pliku. Jeśli chcesz używać tego gniazda, możesz zainstalować %s zamiast %s i zmienić informacje o gnieździe na stronie \"Urządzenie\"." @@ -4436,9 +4790,6 @@ msgstr "Pomiar powierzchni" msgid "Calibrating the detection position of nozzle clumping" msgstr "Kalibracja pozycji wykrywania zalepiania dyszy" -msgid "Unknown" -msgstr "Nieznany" - msgid "Update successful." msgstr "Aktualizacja udana." @@ -4950,9 +5301,6 @@ msgstr "Ustaw na optymalne" msgid "Regroup filament" msgstr "Zmień grupowanie filamentu" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "do" @@ -4989,8 +5337,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Prędkość wentylatora (%)" -msgid "Temperature (°C)" -msgstr "Temperatura (°C)" +msgid "Temperature (℃)" +msgstr "Temperatura (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Natężenie przepływu (mm³/s)" @@ -5008,9 +5356,6 @@ msgstr "Zmiany filamentu" msgid "Options" msgstr "Opcje" -msgid "Extruder" -msgstr "Ekstruder" - msgid "Cost" msgstr "Koszt" @@ -5023,6 +5368,7 @@ msgstr "Zmiany narzędzi" msgid "Color change" msgstr "Zmiana koloru" +msgctxt "Noun" msgid "Print" msgstr "Drukuj" @@ -5186,11 +5532,15 @@ msgstr "Unikaj obszaru kalibracji ekstruzji" msgid "Align to Y axis" msgstr "Wyrównaj do osi Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Tył" + +msgctxt "Camera View" msgid "Left" msgstr "Lewy" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Prawy" @@ -5215,9 +5565,6 @@ msgstr "Rozmieść obiekty na wybranych płytach" msgid "Split to objects" msgstr "Podziel na obiekty" -msgid "Split to parts" -msgstr "Podziel na części" - msgid "Assembly View" msgstr "Widok montażu" @@ -5518,6 +5865,10 @@ msgstr "Drukuj aktualną płytę" msgid "Export G-code file" msgstr "Eksportuj plik G-code" +msgctxt "Verb" +msgid "Print" +msgstr "Drukuj" + msgid "Export plate sliced file" msgstr "Eksportuj plik pociętej płyty" @@ -5691,15 +6042,6 @@ msgstr "Eksportuj bieżącą konfigurację do plików" msgid "Export" msgstr "Eksportuj" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Zakończ" @@ -5816,6 +6158,15 @@ msgstr "Widok" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5937,6 +6288,9 @@ msgstr "Wynik eksportu" msgid "Select profile to load:" msgstr "Wybierz profil do wczytania:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6102,9 +6456,6 @@ msgstr "Pobierz wybrane pliki z drukarki." msgid "Batch manage files." msgstr "Partycjonuj zarządzanie plikami." -msgid "Refresh" -msgstr "Odśwież" - msgid "Reload file list from printer." msgstr "Przeładuj listę plików z drukarki." @@ -6420,6 +6771,9 @@ msgstr "Opcje drukowania" msgid "Safety Options" msgstr "Opcje bezpieczeństwa" +msgid "Hotends" +msgstr "Hotendy" + msgid "Lamp" msgstr "LED" @@ -6453,6 +6807,12 @@ msgstr "Gdy drukowanie jest wstrzymane, ładowanie i rozładowywanie filamentu j msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6503,9 +6863,6 @@ msgstr "To działa tylko podczas drukowania" msgid "Silent" msgstr "Cichy" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "" @@ -6539,6 +6896,12 @@ msgstr "Dodaj zdjęcie" msgid "Delete Photo" msgstr "Usuń zdjęcie" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Prześlij" @@ -6723,6 +7086,9 @@ msgstr "Jak korzystać z trybu tylko LAN" msgid "Don't show this dialog again" msgstr "Nie pokazuj tego okna dialogowego ponownie" +msgid "Please refer to Wiki before use->" +msgstr "Przed użyciem zapoznaj się z Wiki->" + msgid "3D Mouse disconnected." msgstr "Mysz 3D niepodłączona." @@ -6981,27 +7347,18 @@ msgstr "Przepływ" msgid "Please change the nozzle settings on the printer." msgstr "Proszę zmienić ustawienia dyszy na drukarce." -msgid "Hardened Steel" -msgstr "Stal hartowana" - -msgid "Stainless Steel" -msgstr "Stal nierdzewna" - -msgid "Tungsten Carbide" -msgstr "Węglik wolframu" - msgid "Brass" msgstr "Mosiądz" msgid "High flow" msgstr "Wysoki przepływ" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Brak odnośnika do wiki dla tej drukarki." -msgid "Refreshing" -msgstr "Odświeżanie" - msgid "Unavailable while heating maintenance function is on." msgstr "Niedostępne, gdy włączona jest funkcja podtrzymywania ogrzewania." @@ -7124,6 +7481,15 @@ msgstr "Zmiana średnicy" msgid "Configuration incompatible" msgstr "Niekompatybilna konfiguracja" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Wskazówki" + msgid "Sync printer information" msgstr "Synchronizacja informacji o drukarce" @@ -7152,6 +7518,9 @@ msgstr "Kliknij, aby edytować profil" msgid "Project Filaments" msgstr "Filamenty projektu" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Objętość płukania" @@ -7377,9 +7746,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "Wskazówki" - msgid "The file does not contain any geometry data." msgstr "Plik nie zawiera żadnych danych geometrycznych." @@ -7430,9 +7796,21 @@ msgstr "" "To działanie przerwie korespondencję wycięcia.\n" "Po tym konsystencja modelu nie może być zagwarantowana." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Nie można podzielić wybranego obiektu." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7459,6 +7837,9 @@ msgstr "Wybierz nowy plik" msgid "File for the replacement wasn't selected" msgstr "Plik do zastąpienia nie został wybrany" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7505,6 +7886,9 @@ msgstr "Nie można wczytać:" msgid "Error during reload" msgstr "Błąd podczas przeładowywania" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Po wykonaniu cięcia modeli występują ostrzeżenia:" @@ -8266,6 +8650,15 @@ msgstr "Wyłącz synchronizację profilu drukarki po załadowaniu pliku." msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8281,16 +8674,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8569,6 +8953,9 @@ msgstr "Profile niekompatybilne" msgid "My Printer" msgstr "Moja drukarka" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filamenty z lewej" @@ -8588,6 +8975,9 @@ msgstr "Dodaj/Usuń profile" msgid "Edit preset" msgstr "Edytuj profil" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Nieokreślony" @@ -8619,9 +9009,6 @@ msgstr "Wybierz/Usuń drukarki (profile systemowe)" msgid "Create printer" msgstr "Utwórz drukarkę" -msgid "Empty" -msgstr "Puste" - msgid "Incompatible" msgstr "Niekompatybilne" @@ -8853,12 +9240,42 @@ msgstr "wysłanie zakończone" msgid "Error code" msgstr "Kod błędu" -msgid "High Flow" -msgstr "Wysoki przepływ" +msgid "Error desc" +msgstr "Opis błędu" + +msgid "Extra info" +msgstr "Dodatkowe informacje" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "Ustawienie przepływu %s (%s) nie pasuje do dyszy w pliku cięcia (%s). Upewnij się, że zainstalowana dysza jest zgodna z ustawieniami drukarki, a następnie ustaw odpowiednią konfigurację drukarki podczas cięcia." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8924,8 +9341,38 @@ msgstr "Zużycie filamentu wzrośnie o %dg, a liczba zmian o %d w porównaniu do msgid "nozzle" msgstr "Dysza" -msgid "both extruders" -msgstr "oba ekstrudery" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "Ustawienie przepływu %s (%s) nie pasuje do dyszy w pliku cięcia (%s). Upewnij się, że zainstalowana dysza jest zgodna z ustawieniami drukarki, a następnie ustaw odpowiednią konfigurację drukarki podczas cięcia." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Wskazówka: Jeśli ostatnio zmieniłeś dyszę , przejdź do opcji \"Urządzenie ->; Części drukarki\", aby zmienić ustawienia dyszy." @@ -8938,10 +9385,17 @@ msgstr "Średnica %s (%.1fmm) bieżącej drukarki nie jest zgodna z plikiem cię msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Bieżąca średnica dyszy (%.1fmm) nie jest zgodna z plikiem cięcia (%.1fmm). Upewnij się, że zainstalowana dysza jest zgodna z ustawieniami drukarki, a następnie ustaw odpowiednie ustawienia drukarki podczas krojenia." +msgid "both extruders" +msgstr "oba ekstrudery" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Twardość obecnego materiału (%s) przekracza twardość %s(%s). Sprawdź ustawienia dyszy lub materiału i spróbuj ponownie." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -9052,9 +9506,6 @@ msgstr "Aktualne firmware obsługuje maksymalnie 16 materiałów. Możesz zmniej msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "Przed użyciem zapoznaj się z Wiki->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Aktualne firmware nie obsługuje przesyłania plików do pamięci wewnętrznej." @@ -9238,6 +9689,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Proszę kliknąć, aby przywrócić wszystkie ustawienia do ostatnio zapisanego profilu." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Wieża czyszcząca jest wymagana do wymiany dyszy. Brak wieży czyszczącej może spowodować wystąpienie wad na modelu. Czy na pewno chcesz ją wyłączyć?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Wieża czyszcząca jest wymagana dla płynnego timelapse. Możliwe są wady na modelu bez wieży czyszczącej. Czy na pewno wyłączyć wieżę czyszczącą?" @@ -9315,9 +9769,6 @@ msgstr "Dostosować automatycznie do ustawionego zakresu?\n" msgid "Adjust" msgstr "Dostosuj" -msgid "Ignore" -msgstr "Ignoruj" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Funkcja eksperymentalna: Polega na wycofywaniu filamentu na większą odległość w celu zminimalizowania płukania, a następne jego odcięcie. Choć może to znacząco zmniejszyć ilość zużytego filamentu, może również zwiększyć ryzyko zatknięcia dyszy lub innych problemów z drukowaniem." @@ -9826,6 +10277,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Czy na pewno %1% wybrane ustawienia?" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10053,6 +10510,12 @@ msgstr "Przenieś wartości z lewej do prawej" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Jeśli ta opcja jest aktywowana, to okno dialogowe może być używane do przenoszenia wybranych wartości z profilu po lewej do profilu po prawej stronie." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Dodaj plik" @@ -10308,12 +10771,8 @@ msgstr "Pomyślnie zsynchronizowano informacje o dyszy." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Pomyślnie zsynchronizowano dyszę z informacjami numeru AMS." -msgid "Continue to sync filaments" -msgstr "Kontynuuj aby zsynchronizować filamenty" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Anuluj" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10421,6 +10880,9 @@ msgstr "Logowanie" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10735,6 +11197,9 @@ msgstr "Nazwa drukarki" msgid "Where to find your printer's IP and Access Code?" msgstr "Gdzie znaleźć adres IP i kod dostępu do drukarki?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Połącz" @@ -10799,6 +11264,9 @@ msgstr "Moduł tnący" msgid "Auto Fire Extinguishing System" msgstr "Automatyczny system gaśniczy" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10817,6 +11285,9 @@ msgstr "Aktualizacja nieudana" msgid "Update successful" msgstr "Aktualizacja udana" +msgid "Hotends on Rack" +msgstr "Hotendy w uchwycie" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Czy na pewno zaktualizować? To zajmie około 10 minut. Proszę nie wyłączać zasilania podczas aktualizacji drukarki." @@ -10923,6 +11394,9 @@ msgstr "Błąd grupowania: " msgid " can not be placed in the " msgstr " nie może być umieszczony w " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Wewnętrzny most" @@ -11633,7 +12107,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11647,7 +12121,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12066,9 +12540,6 @@ msgstr "" "Kształt zostanie zredukowany przed wykryciem ostrych kątów. Ten parametr wskazuje minimalną długość odchylenia dla redukcji.\n" "0, aby dezaktywować" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "drukarka kompatybilna i wzwyż" @@ -12079,9 +12550,6 @@ msgstr "" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Wyrażenie logiczne (Boole'owskie) używające wartości konfiguracji aktywnego profilu drukarki. Jeśli to wyrażenie jest prawdziwe to znaczy, że aktywny profil jest kompatybilny z drukarką." -msgid "Select profiles" -msgstr "" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Wyrażenie logiczne (Boole'owskie) używające wartości konfiguracji aktywnego profilu druku. Jeśli to wyrażenie jest prawdziwe to znaczy, że aktywny profil jest kompatybilny z aktywnym profilem druku." @@ -12356,6 +12824,42 @@ msgstr "Gęstość górnej powierzchni" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Wzór dolnej powierzchni" @@ -12676,12 +13180,18 @@ msgstr "Automatyczne płukanie" msgid "Auto For Match" msgstr "Automatyczne dopasowanie" +msgid "Nozzle Manual" +msgstr "Instrukcja dyszy" + msgid "Flush temperature" msgstr "Temperatura spłukiwania" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Prędkość przepływu spłukiwania" @@ -12944,6 +13454,12 @@ msgstr "Filament do druku" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Temperatura mięknięcia" @@ -13006,12 +13522,12 @@ msgstr "Gęstość wypełnienia" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Gęstość wewnętrznego rzadkiego wypełnienia, 100% przekształca całe rzadkie wypełnienie w wypełnienie pełne, a użyty zostanie wzór wewnętrznego pełnego wypełnienia" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13519,6 +14035,15 @@ msgstr "Najlepsza automatyczna pozycja w zakresie [0,1] w stosunku do kształtu msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Włącz tę opcję, jeśli urządzenie ma dodatkowy wentylator chłodzenia części. Polecenie G-code: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13594,6 +14119,12 @@ msgstr "" "Włącz to, jeśli drukarka obsługuje filtrację powietrza\n" "Polecenie G-code: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "Użyj filtra przy chłodzeniu" + +msgid "Enable this if printer support cooling filter" +msgstr "Włącz tę opcję, jeśli drukarka może korzystać z filtra przy chłodzeniu." + msgid "G-code flavor" msgstr "Rodzaj G-code" @@ -14123,6 +14654,30 @@ msgstr "Minimalna prędkość podczas przemieszczania się" msgid "Minimum travel speed (M205 T)" msgstr "Minimalna prędkość podczas przemieszczania się (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Maksymalna siła na osi Y" + +msgid "The allowed maximum output force of Y axis" +msgstr "Dopuszczalna maksymalna siła wyjściowa na osi Y" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Masa stołu dla osi Y" + +msgid "The machine bed mass load of Y axis" +msgstr "Obciążenie masowe stołu maszyny na osi Y" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "Dopuszczalna maksymalna masa wydruku" + +msgid "The allowed max printed mass on a plate" +msgstr "Maksymalna dopuszczalna masa nadruku na płycie" + msgid "Maximum acceleration for extruding" msgstr "Maks. przyspieszenie ekstruzji" @@ -14672,6 +15227,9 @@ msgstr "Napęd bezpośredni" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "Hybryda" + msgid "Enable filament dynamic map" msgstr "" @@ -14707,6 +15265,12 @@ msgstr "Prędkość deretrakcji" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Użyj retrakcji sterowanej przez firmware." @@ -14738,6 +15302,10 @@ msgstr "Wyrównany" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Tył" + msgid "Random" msgstr "Losowo" @@ -15012,6 +15580,12 @@ msgstr "Jeśli wybrany jest tryb „Tradycyjny”, dla każdego wydruku będzie msgid "Traditional" msgstr "Tradycyjny" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Zmiana temperatury" @@ -15100,6 +15674,18 @@ msgstr "Wyczyść wszystkie używane ekstrudery" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Jeśli włączone, wszystkie extrudery do drukowania będą przygotowane na przedniej krawędzi stołu drukującego na początku druku." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Promień zamykania szpar" @@ -15483,7 +16069,7 @@ msgstr "" "Jeśli włączona, ten parametr ustawia także zmienną gcode o nazwie chamber_temperature, która może być użyta do przekazania żądanej temperatury komory do makra rozpoczynającego drukowanie, lub makra utrzymywania ciepła, na przykład: PRINT_START (inne zmienne) CHAMBER_TEMP=[chamber_temperature]. Może to być przydatne, jeśli twoja drukarka nie obsługuje poleceń M141/M191 lub jeśli chcesz zarządzać utrzymywaniem ciepła w makrze rozpoczynającym drukowanie, jeśli nie jest zainstalowany aktywna podgrzewacz komory." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15538,6 +16124,45 @@ msgstr "Grubość górnej powłoki" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Liczba górnych zwartych warstw jest zwiększana podczas cięcia, jeśli grubość obliczona przez górną warstwe powłoki jest cieńsza niż ta wartość. Można w ten sposób uniknąć zbyt cienkiej powłoki, gdy wysokość warstwy jest mała. 0 oznacza, że to ustawienie jest wyłączone, a grubość górnej powłoki jest absolutnie określona przez górne warstwy powłoki" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Prędkość przemieszczania, która jest szybsza i bez ekstruzji" @@ -15586,6 +16211,12 @@ msgstr "Mnożnik płukania" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Aktualna objętość płukania jest równa mnożnikowi płukania pomnożonemu przez objętości płukania w tabeli." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Objętość czyszczenia" @@ -15593,6 +16224,18 @@ msgstr "Objętość czyszczenia" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Objętość materiału, który ekstruder powinien upuścić na wieży czyszczącej." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Szerokość wieży czyszczącej" @@ -15882,6 +16525,57 @@ msgstr "Minimalna szerokość ściany" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Szerokość obrysu, który zastąpi cienkie detale modelu (zgodnie z minimalnym rozmiarem detalu). Jeśli minimalna szerokość obrysu jest mniejsza niż grubość detalu, obrys będzie miał taką samą grubość jak sam element. Jest wyrażona w procentach i zostanie obliczona na podstawie średnicy dyszy." +msgid "Hotend change time" +msgstr "Czas zmiany hotendu" + +msgid "Time to change hotend." +msgstr "Czas na zmianę hotendu." + +msgid "Hotend change" +msgstr "Zmiana hotendu" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Podczas zmiany hotendu zaleca się ekstruzję określonej długości filamentu z oryginalnej dyszy. Pomaga to zminimalizować wyciek filamentu z dyszy." + +msgid "Extruder change" +msgstr "Zmiana ekstrudera" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Aby zapobiec wyciekaniu filamentu, dysza wykona ruch wsteczny przez określony czas po zakończeniu wyciskania materiału. Ustawienie określa czas tego ruchu." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Aby zapobiec wyciekaniu, temperatura dyszy zostanie zmniejszona podczas wyciskania. Dlatego, czas wyciskania musi być większy niż czas schładzania. 0 oznacza wyłączony." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "Maksymalna prędkość przepływu dla wyciskania, gdzie -1 oznacza użycie prędkości maksymalnej." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Aby zapobiec wyciekom, temperatura dyszy będzie obniżana podczas wyciskania. Uwaga: wywoływane jest jedynie polecenie chłodzenia i aktywacja wentylatora, osiągnięcie docelowej temperatury nie jest gwarantowane. Wartość 0 oznacza wyłączenie." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "Maksymalna prędkość przepływu dla wyciskania przed zmianą hotendu, gdzie -1 oznacza użycie prędkości maksymalnej." + +msgid "length when change hotend" +msgstr "długość przy zmianie hotendu" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Po modyfikacji tej wartości retrakcji będzie ona używana jako ilość cofniętego filamentu wewnątrz hotendu przed każdą jego zmianą." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Objętość materiału wymagana do oczyszczania ekstrudera na wieży przed zmianą hotendu." + +msgid "Preheat temperature delta" +msgstr "Delta temperatur podgrzewania wstępnego" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Delta temperatur stosowana podczas podgrzewania wstępnego przed wymianą narzędzia." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Wykryj wąskie wewnętrzne pełne wypełnienie" @@ -16642,12 +17336,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibracja nie jest obsługiwana" -msgid "Error desc" -msgstr "Opis błędu" - -msgid "Extra info" -msgstr "Dodatkowe informacje" - msgid "Flow Dynamics" msgstr "Dynamika przepływu" @@ -16848,6 +17536,12 @@ msgstr "Proszę wprowadzić nazwę, którą chcesz zapisać w drukarce." msgid "The name cannot exceed 40 characters." msgstr "Nazwa nie może przekraczać 40 znaków." +msgid "Nozzle ID" +msgstr "Identyfikator dyszy" + +msgid "Standard Flow" +msgstr "Przepływ standardowy" + msgid "Please find the best line on your plate" msgstr "Znajdź najlepszą linię na swojej płycie" @@ -16938,9 +17632,6 @@ msgstr "Zsynchronizowano informacje AMS i dyszy." msgid "Nozzle Flow" msgstr "Przepływ dyszy" -msgid "Nozzle Info" -msgstr "Informacje o dyszy" - msgid "Filament position" msgstr "pozycja filamentu" @@ -17015,6 +17706,10 @@ msgstr "Pomyślnie załadowano historie wyników" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Odświeżanie zapisanej historii kalibracji dynamika przepływu" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Uwaga: Numer hotendu na %s jest powiązany z uchwytem. Po przeniesieniu hotendu na nowy uchwyt jego numer zostanie automatycznie zaktualizowany." + msgid "Action" msgstr "Akcja" @@ -18747,6 +19442,12 @@ msgstr "Drukowanie nie powiodło się" msgid "Removed" msgstr "Usunięto" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Nie przypominaj mi ponownie" @@ -18780,12 +19481,25 @@ msgstr "Samouczek wideo" msgid "(Sync with printer)" msgstr "(Synchronizuj z drukarką)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Potniemy zgodnie z tą metodą grupowania:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Metoda grupowania materiału dla obecnej płyty jest zależna od opcji w menu, wyświetlanym po najechaniu na przycisk Potnij aktualną płytę." @@ -19018,9 +19732,6 @@ msgstr "Tego działania nie będzie można cofnąć. Kontynuować?" msgid "Skipping objects." msgstr "Pomijanie obiektów." -msgid "Select Filament" -msgstr "Wybierz filament" - msgid "Null Color" msgstr "Bez koloru" @@ -19542,6 +20253,16 @@ msgstr "" "Unikaj odkształceń\n" "Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?" +#~ msgid "Continue to sync filaments" +#~ msgstr "Kontynuuj aby zsynchronizować filamenty" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Anuluj" + +#~ msgid "Print" +#~ msgstr "Drukuj" + #~ msgid "in" #~ msgstr "cal" @@ -20252,9 +20973,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Nie można rozpocząć bez karty SD." -#~ msgid "Update" -#~ msgstr "Aktualizacja" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Czułość pauzy wynosi" @@ -21000,10 +21718,6 @@ msgstr "" #~ msgid "Unselect" #~ msgstr "Odznacz" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Skala" - #~ msgid "Lift Z Enforcement" #~ msgstr "Wymuszenie podniesienia osi Z" @@ -21709,8 +22423,8 @@ msgstr "" #~ msgid "Enter the nozzle_temperature needed for extruding your filament." #~ msgstr "Wprowadź temperaturę dyszy potrzebną do ekstruzji filamentu." -#~ msgid "A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS." -#~ msgstr "Generalną zasadą jest 160 do 230 °C dla PLA i 215 do 250 °C dla ABS." +#~ msgid "A rule of thumb is 160 to 230℃ for PLA, and 215 to 250℃ for ABS." +#~ msgstr "Generalną zasadą jest 160 do 230℃ dla PLA i 215 do 250℃ dla ABS." #~ msgid "Extrusion Temperature:" #~ msgstr "Temperatura ekstrudera:" @@ -21718,8 +22432,8 @@ msgstr "" #~ msgid "Enter the bed temperature needed for getting your filament to stick to your heated bed." #~ msgstr "Wprowadź temperaturę potrzebną do dobrego przylegania filamentu do powierzchni podgrzewanego stołu." -#~ msgid "A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed." -#~ msgstr "Generalną zasadą jest 60 °C dla PLA i 110 °C dla ABS. Ustaw zero, jeśli nie masz podgrzewanego stołu." +#~ msgid "A rule of thumb is 60℃ for PLA and 110℃ for ABS. Leave zero if you have no heated bed." +#~ msgstr "Generalną zasadą jest 60℃ dla PLA i 110℃ dla ABS. Ustaw zero, jeśli nie masz podgrzewanego stołu." #~ msgid "Bed Temperature:" #~ msgstr "Temperatura stołu" diff --git a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po index 9b40d74f18..985c56e0da 100644 --- a/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po +++ b/localization/i18n/pt_BR/OrcaSlicer_pt_BR.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-07-04 11:51-0300\n" "Last-Translator: Alexandre Folle de Menezes\n" "Language-Team: Portuguese, Brazilian\n" @@ -40,6 +40,24 @@ msgstr "TPU não é suportado pelo AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS não suporta 'Bambu Lab PET-CF'." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Recomenda-se realizar um processo de 'cold pull' antes de imprimir em TPU para evitar entupimentos. Você pode utilizar esse processo de manutenção na impressora." @@ -52,6 +70,9 @@ msgstr "O PVA úmido é flexível e pode ficar preso na extrusora. Seque-o antes msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "A superfície áspera do PLA Glow pode acelerar o desgaste do sistema AMS, particularmente nos componentes internos do AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Os filamentos CF/GF são duros e quebradiços, é fácil quebrar ou ficar preso no AMS, por favor use com cautela." @@ -61,10 +82,90 @@ msgstr "O PPS-CF é quebradiço e pode quebrar no tubo de PTFE dobrado acima do msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "O PPA-CF é quebradiço e pode quebrar no tubo de PTFE dobrado acima do cabeçote." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s não é suportado pela extrusora %s." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Alto Fluxo" + +msgid "Standard" +msgstr "Padrão" + +msgid "TPU High Flow" +msgstr "TPU Alto fluxo" + +msgid "Unknown" +msgstr "Desconhecido" + +msgid "Hardened Steel" +msgstr "Aço Endurecido" + +msgid "Stainless Steel" +msgstr "Aço Inoxidável" + +msgid "Tungsten Carbide" +msgstr "Carbeto de Tungstênio" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "O toolhead e o suporte do hotend podem se mover. Por favor, mantenha suas mãos afastadas da câmara." + +msgid "Warning" +msgstr "Aviso" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "As informações do hotend podem estar imprecisas. Deseja reler o hotend? (As informações do hotend podem mudar durante o desligamento)." + +msgid "I confirm all" +msgstr "Confirmo todos" + +msgid "Re-read all" +msgstr "Releia tudo" + +msgid "Reading the hotends, please wait." +msgstr "Lendo os hotends, por favor, espere." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Durante a atualização do hotend, o toolhead se moverá. Não coloque a mão dentro da câmara." + +msgid "Update" +msgstr "Atualizar" + msgid "Current AMS humidity" msgstr "Umidade AMS atual" @@ -95,6 +196,85 @@ msgstr "Versão:" msgid "Latest version" msgstr "Última versão" +msgid "Row A" +msgstr "Linha A" + +msgid "Row B" +msgstr "Linha B" + +msgid "Toolhead" +msgstr "Cabeça da ferramenta" + +msgid "Empty" +msgstr "Vazio" + +msgid "Error" +msgstr "Erro" + +msgid "Induction Hotend Rack" +msgstr "Suporte para Hotend por Indução" + +msgid "Hotends Info" +msgstr "Informações sobre Hotends" + +msgid "Read All" +msgstr "Ler tudo" + +msgid "Reading " +msgstr "Leitura " + +msgid "Please wait" +msgstr "Por favor, aguarde" + +msgid "Running..." +msgstr "Executando..." + +msgid "Raised" +msgstr "Elevado" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "O hotend está em um estado anormal e atualmente indisponível. Por favor, vá em 'Dispositivo -> Atualizar' para atualizar o firmware." + +msgid "Abnormal Hotend" +msgstr "Hotend anormal" + +msgid "Refresh" +msgstr "Atualizar" + +msgid "Refreshing" +msgstr "Refrescando" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "O status do hotend está anormal e indisponível no momento. Atualize o firmware e tente novamente." + +msgid "Cancel" +msgstr "Cancelar" + +msgid "Jump to the upgrade page" +msgstr "Ir para a página de atualização" + +msgid "SN" +msgstr "SN" + +msgid "Version" +msgstr "Versão" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Tempo de uso: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Os bicos dinâmicos são alocados na placa atual. A seleção do hotend não é suportada." + +msgid "Hotend Rack" +msgstr "Rack para Hotend" + +msgid "ToolHead" +msgstr "Cabeça de ferramenta" + +msgid "Nozzle information needs to be read" +msgstr "As informações do bico precisam ser lidas" + msgid "Support Painting" msgstr "Pintura de Suportes" @@ -164,6 +344,12 @@ msgstr "Preencher" msgid "Gap Fill" msgstr "Preencher vão" +msgid "Vertical" +msgstr "Vertical" + +msgid "Horizontal" +msgstr "Horizontal" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Permite pintura apenas em facetas selecionadas por: \"%1%\"" @@ -256,12 +442,6 @@ msgstr "Triângulo" msgid "Height Range" msgstr "Intervalo de Altura" -msgid "Vertical" -msgstr "Vertical" - -msgid "Horizontal" -msgstr "Horizontal" - msgid "Remove painted color" msgstr "Remover cor pintada" @@ -326,8 +506,9 @@ msgstr "Gizmo-Rotacionar" msgid "Optimize orientation" msgstr "Otimizar orientação" +msgctxt "Verb" msgid "Scale" -msgstr "Escala" +msgstr "Escalar" msgid "Gizmo-Scale" msgstr "Gizmo-Dimensionar" @@ -337,7 +518,7 @@ msgstr "Erro: Por favor, feche todos os menus da barra de ferramentas primeiro" msgctxt "inches" msgid "in" -msgstr "" +msgstr "pol" msgid "mm" msgstr "mm" @@ -369,6 +550,9 @@ msgstr "Proporções de escala" msgid "Object operations" msgstr "Operações de objeto" +msgid "Scale" +msgstr "Escala" + msgid "Volume operations" msgstr "Operações de volume" @@ -414,6 +598,10 @@ msgstr "Redefinir rotação para o valor de abertura da ferramenta de rotação. msgid "Reset current rotation to real zeros." msgstr "Redefinir rotação atual para zeros reais." +msgctxt "Noun" +msgid "Scale" +msgstr "Escala" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Tamanho" @@ -596,9 +784,6 @@ msgstr "Proporção de espaço em relação ao raio" msgid "Confirm connectors" msgstr "Confirmar conectores" -msgid "Cancel" -msgstr "Cancelar" - msgid "Flip cut plane" msgstr "Virar plano de corte" @@ -639,12 +824,12 @@ msgstr "Cortar em peças" msgid "Reset cutting plane and remove connectors" msgstr "Redefinir plano de corte e remover conectores" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Executar corte" -msgid "Warning" -msgstr "Aviso" - msgid "Invalid connectors detected" msgstr "Conectores inválidos detectados" @@ -675,6 +860,13 @@ msgstr "Plano de corte com cavidade é inválido" msgid "Connector" msgstr "Conector" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Cortar por Plano" @@ -721,9 +913,6 @@ msgstr "Simplificar" msgid "Simplification is currently only allowed when a single part is selected" msgstr "A simplificação só é permitida atualmente quando uma única peça está selecionada" -msgid "Error" -msgstr "Erro" - msgid "Extra high" msgstr "Extra alto" @@ -1996,6 +2185,9 @@ msgstr "Acesso ao pacote %s não é autorizado." msgid "Loading user preset" msgstr "Carregando predefinição de usuário" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s foi removido." @@ -2009,6 +2201,18 @@ msgstr "Selecione o idioma" msgid "Language" msgstr "Idioma" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2605,6 +2809,45 @@ msgstr "Clique no ícone para editar a pintura de cor do objeto" msgid "Click the icon to shift this object to the bed" msgstr "Clique no ícone para mover este objeto para a mesa" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Carregando arquivo" @@ -2614,6 +2857,9 @@ msgstr "Erro!" msgid "Failed to get the model data in the current file." msgstr "Falha ao obter os dados do modelo no arquivo atual." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Genérico" @@ -2626,6 +2872,12 @@ msgstr "Mude para o modo de configuração por objeto para editar processos dos msgid "Remove paint-on fuzzy skin" msgstr "Remover textura difusa pintada" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Remover intervalo de altura" + msgid "Delete connector from object which is a part of cut" msgstr "Excluir conector do objeto que é parte do corte" @@ -2655,12 +2907,24 @@ msgstr "Excluir todos os conectores" msgid "Deleting the last solid part is not allowed." msgstr "Não é permitido excluir a última peça sólida." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "O objeto de destino contém apenas uma peça e não pode ser dividido." +msgid "Split to parts" +msgstr "Dividir em peças" + msgid "Assembly" msgstr "Montagem" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Informação de Conectores de Corte" @@ -2691,6 +2955,9 @@ msgstr "Intervalos de altura" msgid "Settings for height range" msgstr "Configurações para intervalo de altura" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Camada" @@ -2712,6 +2979,9 @@ msgstr "Tipo:" msgid "Choose part type" msgstr "Escolha o tipo de peça" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Digite um novo nome" @@ -2739,6 +3009,9 @@ msgstr "\"%s\" ultrapassará 1 milhão de faces após esta subdivisão, o que po msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "A malha da peça \"%s\" contém erros. Por favor, corrija-a primeiro." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Predefinição de processo adicional" @@ -2748,9 +3021,6 @@ msgstr "Remover parâmetro" msgid "to" msgstr "para" -msgid "Remove height range" -msgstr "Remover intervalo de altura" - msgid "Add height range" msgstr "Adicionar intervalo de altura" @@ -2953,6 +3223,9 @@ msgstr "Escolha um espaço do AMS e pressione o botão \"Carregar\" ou \"Descarr msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "O tipo de filamento necessário para realizar esta ação é desconhecido. Insira as informações do filamento desejado." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Mudar a velocidade do ventilador durante a impressão pode afetar a qualidade da impressão. Escolha com cuidado." @@ -3075,6 +3348,24 @@ msgstr "Confirmar extrusão" msgid "Check filament location" msgstr "Verificar localização do filamento" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "A temperatura máxima não pode exceder " @@ -3126,6 +3417,62 @@ msgstr "Modo de desenvolvedor" msgid "Launch troubleshoot center" msgstr "Abrir a central de solução de problemas" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Por favor, defina a contagem de bicos" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Erro: Não é possível definir a contagem de bicos como zero para ambos." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Erro: A contagem de bicos não pode exceder %d." + +msgid "Confirm" +msgstr "Confirmar" + +msgid "Extruder" +msgstr "Extrusora" + +msgid "Nozzle Selection" +msgstr "Seleção de Bocal" + +msgid "Available Nozzles" +msgstr "Bicos Disponíveis" + +msgid "Nozzle Info" +msgstr "Informações de Bico" + +msgid "Sync Nozzle status" +msgstr "Status do bico de sincronização" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Atenção: A combinação de diâmetros de bico em uma única impressão não é suportada. Se o tamanho selecionado estiver disponível apenas em um extrusor, a impressão com extrusão única será aplicada." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Atualizando %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Bico desconhecido detectado. Atualize para atualizar as informações (bicos não atualizados serão excluídos durante o fatiamento). Verifique o diâmetro do bico e a taxa de fluxo em relação aos valores exibidos." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Bico desconhecido detectado. Atualize para atualizar (bicos não atualizados serão ignorados na fatiagem)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Por favor, confirme se o diâmetro do bico e a taxa de fluxo necessários correspondem aos valores atualmente exibidos." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Sua impressora tem diferentes bico instalados. Selecione um bico para esta impressão. ." + +msgid "Ignore" +msgstr "Ignorar" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3458,15 +3805,9 @@ msgstr "O OrcaSlicer começou com esse mesmo espírito, inspirando-se no PrusaSl msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "Atualmente, o OrcaSlicer é o fatiador de código aberto mais utilizado e ativamente desenvolvido na comunidade de impressão 3D. Muitas de suas inovações foram adotadas por outros fatiadores, tornando-o uma força motriz para toda a indústria." -msgid "Version" -msgstr "Versão" - msgid "AMS Materials Setting" msgstr "Configuração de Materiais AMS" -msgid "Confirm" -msgstr "Confirmar" - msgid "Close" msgstr "Fechar" @@ -3487,12 +3828,12 @@ msgstr "mín" msgid "The input value should be greater than %1% and less than %2%" msgstr "O valor de entrada deve ser maior que %1% e menor que %2%" -msgid "SN" -msgstr "SN" - msgid "Factors of Flow Dynamics Calibration" msgstr "Fatores de Calibração de Dinâmica de Fluxo" +msgid "Wiki Guide" +msgstr "Guia Wiki" + msgid "PA Profile" msgstr "Perfil PA" @@ -3580,8 +3921,9 @@ msgstr "Calibração concluída. Por favor, encontre a linha de extrusão mais u msgid "Save" msgstr "Salvar" +msgctxt "Navigation" msgid "Back" -msgstr "Atrás" +msgstr "Voltar" msgid "Example" msgstr "Exemplo" @@ -3665,6 +4007,19 @@ msgstr "Bico Direito" msgid "Nozzle" msgstr "Bico" +msgid "Select Filament && Hotends" +msgstr "Selecionar Slot de Filamento && Bicos de Aquecimento" + +msgid "Select Filament" +msgstr "Selecionar Filamento" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Impressão com o bico atual pode produzir um desperdício extra de %0.2f g." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Nota: o tipo de filamento (%s) não corresponde ao tipo de filamento (%s) no arquivo de fatiamento. Se você quiser usar este slot, pode instalar %s em vez de %s e alterar as informações do slot na página 'Dispositivo'." @@ -4032,7 +4387,7 @@ msgid "The recommended nozzle temperature for this filament type is [%d, %d] deg msgstr "A temperatura do bico recomendada para este tipo de filamento é [%d, %d] graus Celsius." msgid "Adaptive Pressure Advance model validation failed:\n" -msgstr "" +msgstr "Falha na validação do modelo de Pressure Advance Adaptativo:\n" msgid "" "Too small max volumetric speed.\n" @@ -4360,9 +4715,6 @@ msgstr "Medindo Superfície" msgid "Calibrating the detection position of nozzle clumping" msgstr "Calibrando a posição de detecção de aglomeração no bico" -msgid "Unknown" -msgstr "Desconhecido" - msgid "Update successful." msgstr "Atualização bem-sucedida." @@ -4656,7 +5008,7 @@ msgid "Layer Time (log)" msgstr "Tempo da Camada (log)" msgid "Pressure Advance" -msgstr "Avanço de Pressão" +msgstr "Pressure Advance" msgid "Noop" msgstr "" @@ -4764,7 +5116,7 @@ msgid "Jerk: " msgstr "Jerk: " msgid "PA: " -msgstr "AP: " +msgstr "PA: " msgid "mm/s" msgstr "mm/s" @@ -4871,9 +5223,6 @@ msgstr "Definir para Ideal" msgid "Regroup filament" msgstr "Reagrupar filamento" -msgid "Wiki Guide" -msgstr "Guia Wiki" - msgid "up to" msgstr "até" @@ -4907,7 +5256,7 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Velocidade do ventilador (%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "Temperatura (℃)" msgid "Volumetric flow rate (mm³/s)" @@ -4925,9 +5274,6 @@ msgstr "Mudanças de filamento" msgid "Options" msgstr "Opções" -msgid "Extruder" -msgstr "Extrusora" - msgid "Cost" msgstr "Custo" @@ -4940,8 +5286,9 @@ msgstr "Trocas de ferramenta" msgid "Color change" msgstr "Mudança de cor" +msgctxt "Noun" msgid "Print" -msgstr "Imprimir" +msgstr "Impressão" msgid "Printer" msgstr "Impressora" @@ -5102,11 +5449,15 @@ msgstr "Evitar a região de calibração da extrusão" msgid "Align to Y axis" msgstr "Alinhar com o eixo Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Atrás" + +msgctxt "Camera View" msgid "Left" msgstr "Esquerda" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Direita" @@ -5131,9 +5482,6 @@ msgstr "Organizar objetos nas placas selecionadas" msgid "Split to objects" msgstr "Dividir em objetos" -msgid "Split to parts" -msgstr "Dividir em peças" - msgid "Assembly View" msgstr "Vista de Montagem" @@ -5433,6 +5781,10 @@ msgstr "Imprimir placa" msgid "Export G-code file" msgstr "Exportar arquivo G-code" +msgctxt "Verb" +msgid "Print" +msgstr "Imprimir" + msgid "Export plate sliced file" msgstr "Exportar arquivo de placa fatiada" @@ -5606,15 +5958,6 @@ msgstr "Exportar configuração atual para arquivos" msgid "Export" msgstr "Exportar" -msgid "Sync Presets" -msgstr "Sincronizar Predefinições" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "Baixar e aplicar as predefinições mais recentes do OrcaCloud" - -msgid "You must be logged in to sync presets from cloud." -msgstr "Você precisa estar logado para sincronizar as predefinições da nuvem." - msgid "Quit" msgstr "Sair" @@ -5731,6 +6074,15 @@ msgstr "Visualizar" msgid "Preset Bundle" msgstr "Pacote de Predefinições" +msgid "Sync Presets" +msgstr "Sincronizar Predefinições" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Baixar e aplicar as predefinições mais recentes do OrcaCloud" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Você precisa estar logado para sincronizar as predefinições da nuvem." + msgid "Syncing presets from cloud…" msgstr "Sincronizando predefinições da nuvem…" @@ -5744,7 +6096,7 @@ msgid "Max flowrate" msgstr "Fluxo máximo" msgid "Pressure advance" -msgstr "Avanço de pressão" +msgstr "Pressure advance" msgid "Flow ratio" msgstr "Taxa de fluxo" @@ -5851,6 +6203,9 @@ msgstr "Resultado da exportação" msgid "Select profile to load:" msgstr "Selecione o perfil para carregar:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6019,9 +6374,6 @@ msgstr "Baixar arquivos selecionados da impressora." msgid "Batch manage files." msgstr "Gerenciar arquivos em lote." -msgid "Refresh" -msgstr "Atualizar" - msgid "Reload file list from printer." msgstr "Recarregar lista de arquivos da impressora." @@ -6328,6 +6680,9 @@ msgstr "Opções de Impressão" msgid "Safety Options" msgstr "Opções de Segurança" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Lâmpada" @@ -6361,6 +6716,12 @@ msgstr "Quando a impressão está pausada, o carregamento e descarregamento do f msgid "Current extruder is busy changing filament." msgstr "A extrusora atual está ocupada trocando o filamento." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "O espaço atual já foi carregado." @@ -6409,9 +6770,6 @@ msgstr "Isso só tem efeito durante a impressão" msgid "Silent" msgstr "Silencioso" -msgid "Standard" -msgstr "Padrão" - msgid "Sport" msgstr "Esportivo" @@ -6445,6 +6803,12 @@ msgstr "Adicionar Foto" msgid "Delete Photo" msgstr "Excluir Foto" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Enviar" @@ -6628,6 +6992,9 @@ msgstr "Como usar o modo somente LAN" msgid "Don't show this dialog again" msgstr "Não mostrar esse diálogo novamente" +msgid "Please refer to Wiki before use->" +msgstr "Consulte o Wiki antes de usar->" + msgid "3D Mouse disconnected." msgstr "Mouse 3D desconectado." @@ -6875,27 +7242,18 @@ msgstr "Fluxo do Bico" msgid "Please change the nozzle settings on the printer." msgstr "Altere as configurações de bico na impressora." -msgid "Hardened Steel" -msgstr "Aço Endurecido" - -msgid "Stainless Steel" -msgstr "Aço Inoxidável" - -msgid "Tungsten Carbide" -msgstr "Carbeto de Tungstênio" - msgid "Brass" msgstr "Latão" msgid "High flow" msgstr "Alto fluxo" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Não há link wiki disponível para esta impressora." -msgid "Refreshing" -msgstr "Refrescando" - msgid "Unavailable while heating maintenance function is on." msgstr "Indisponível enquanto a função de manutenção do aquecimento estiver ativada." @@ -7018,6 +7376,15 @@ msgstr "Trocar diâmetro" msgid "Configuration incompatible" msgstr "Configuração incompatível" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Dicas" + msgid "Sync printer information" msgstr "Sincronizar informações da impressora" @@ -7046,6 +7413,9 @@ msgstr "Clique para editar predefinição" msgid "Project Filaments" msgstr "Filamentos do Projeto" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Volumes de Purga" @@ -7271,9 +7641,6 @@ msgstr "A impressora conectada é %s. Ela deve corresponder à predefinição do msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Deseja sincronizar as informações da impressora e alternar automaticamente a predefinição?" -msgid "Tips" -msgstr "Dicas" - msgid "The file does not contain any geometry data." msgstr "O arquivo não contém dados de geometria." @@ -7323,9 +7690,21 @@ msgstr "" "Essa ação quebrará uma correspondência de corte.\n" "Após isso, a consistência do modelo não pode ser garantida." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "O objeto selecionado não pôde ser dividido." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7352,6 +7731,9 @@ msgstr "Selecione um novo arquivo" msgid "File for the replacement wasn't selected" msgstr "O arquivo para a substituição não foi selecionado" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Selecione a pasta origem da substituição" @@ -7398,6 +7780,9 @@ msgstr "Não é possível recarregar:" msgid "Error during reload" msgstr "Erro durante a recarga" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Existem avisos após o fatiamento dos modelos:" @@ -8166,6 +8551,15 @@ msgstr "Limpar minha opção de sincronização da predefinição da impressora msgid "Graphics" msgstr "Gráfico" +msgid "Smooth normals" +msgstr "Normais suaves" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Sombreamento Phong" @@ -8181,20 +8575,8 @@ msgstr "Aplica SSAO em uma visualização realista." msgid "Shadows" msgstr "Sombras" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "Renderiza sombras na placa em uma visualização realista." - -msgid "Smooth normals" -msgstr "Normais suaves" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"Aplica normais suaves à visualização realista.\n" -"\n" -"Requer a recarga manual da cena para fazer efeito (clique com o botão direito na visualização 3D → \"Recarregar Tudo\")." msgid "Anti-aliasing" msgstr "Antisserrilhamento" @@ -8485,6 +8867,9 @@ msgstr "Predefinições incompatíveis" msgid "My Printer" msgstr "Minha Impressora" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Filamentos da esquerda" @@ -8504,6 +8889,9 @@ msgstr "Adicionar/Remover predefinições" msgid "Edit preset" msgstr "Editar predefinições" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Não especificado" @@ -8535,9 +8923,6 @@ msgstr "Selecionar/Remover impressoras (predefinições do sistema)" msgid "Create printer" msgstr "Criar impressora" -msgid "Empty" -msgstr "Vazio" - msgid "Incompatible" msgstr "Incompatível" @@ -8769,12 +9154,42 @@ msgstr "Envio completo" msgid "Error code" msgstr "Código de erro" -msgid "High Flow" -msgstr "Alto Fluxo" +msgid "Error desc" +msgstr "Descrição do erro" + +msgid "Extra info" +msgstr "Informação extra" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "A configuração de fluxo do bico %s(%s) não corresponde ao arquivo de fatiamento(%s). Certifique-se de que o bico instalado corresponde às configurações da impressora, então defina a predefinição de impressora correspondente durante o fatiamento." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8838,8 +9253,38 @@ msgstr "O custo de %dg de filamento e %d muda mais do que o agrupamento ideal." msgid "nozzle" msgstr "bico" -msgid "both extruders" -msgstr "ambas extrusoras" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "A configuração de fluxo do bico %s(%s) não corresponde ao arquivo de fatiamento(%s). Certifique-se de que o bico instalado corresponde às configurações da impressora, então defina a predefinição de impressora correspondente durante o fatiamento." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Dica: Se você trocou o bico da sua impressora recentemente, acesse 'Dispositivo -> Peças da impressora' para alterar as configurações do bico." @@ -8852,10 +9297,17 @@ msgstr "O diâmetro %s (%.1fmm) da impressora atual não corresponde ao arquivo msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "O diâmetro do bico atual (%.1fmm) não corresponde ao arquivo de fatiamento (%.1fmm). Certifique-se de que o bico instalado corresponde às configurações da impressora, então defina a predefinição de impressora correspondente ao fatiar." +msgid "both extruders" +msgstr "ambas extrusoras" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "A dureza do material atual (%s) excede a dureza de %s(%s). Verifique as configurações do bico ou do material e tente novamente." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] requer impressão em um ambiente de alta temperatura. Por favor feche a porta." @@ -8966,9 +9418,6 @@ msgstr "O firmware atual suporta um máximo de 16 materiais. Você pode reduzir msgid "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." msgstr "O tipo de filamento externo é desconhecido ou não corresponde ao tipo de filamento no arquivo de fatiamento. Certifique-se de ter instalado o filamento correto no carretel externo." -msgid "Please refer to Wiki before use->" -msgstr "Consulte o Wiki antes de usar->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "O firmware atual não suporta a transferência de arquivos para o armazenamento interno." @@ -9147,6 +9596,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Clique para redefinir todas as configurações para a última predefinição salva." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "A torre principal é necessária para a troca do bico. Pode haver falhas no modelo sem a torre principal. Tem certeza de que deseja desativar a torre principal?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Uma torre de preparo é necessária para um timelapse suave. Pode haver falhas no modelo sem a torre de preparo. Tem certeza de que deseja desativar a torre de preparo?" @@ -9229,9 +9681,6 @@ msgstr "Ajustar automaticamente à faixa definida?\n" msgid "Adjust" msgstr "Ajustar" -msgid "Ignore" -msgstr "Ignorar" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Funcionalidade experimental: Retrair e cortar o filamento a uma distância maior durante mudanças de filamento para minimizar a purga. Embora possa reduzir notavelmente a purga, ele também pode elevar o risco de bolhas no bico ou outras complicações de impressão." @@ -9430,7 +9879,7 @@ msgid "Recommended nozzle temperature range of this filament. 0 means not set" msgstr "Faixa de temperatura do bico recomendada para este filamento. 0 significa não definido" msgid "Flow ratio and Pressure Advance" -msgstr "Taxa de fluxo e Avanço de Pressão" +msgstr "Taxa de fluxo e Pressure Advance" msgid "Print chamber temperature" msgstr "Temperatura da câmara de impressão" @@ -9730,6 +10179,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Tem certeza de que quer %1% a predefinição selecionada?" +msgid "Select printers" +msgstr "Selecionar impressoras" + +msgid "Select profiles" +msgstr "Selecionar perfis" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9974,6 +10429,12 @@ msgstr "Transferir valores da esquerda para a direita" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Se ativo, este diálogo pode ser usado para transferir valores selecionados da predefinição da esquerda para a da direita." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Adicionar arquivo" @@ -10229,12 +10690,8 @@ msgstr "Informações do bico sincronizadas com sucesso." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Informações do bico e do número de AMS sincronizadas com sucesso." -msgid "Continue to sync filaments" -msgstr "Continue a sincronizar os filamentos" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Cancelar" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Cor de filamento da impressora sincronizado com sucesso." @@ -10342,6 +10799,9 @@ msgstr "Entrar" msgid "Login failed. Please try again." msgstr "Falha no login. Tente novamente." +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[Ação Necessária] " @@ -10648,6 +11108,9 @@ msgstr "Nome da impressora" msgid "Where to find your printer's IP and Access Code?" msgstr "Onde encontrar o IP e o Código de Acesso da sua impressora?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Conectar" @@ -10712,6 +11175,9 @@ msgstr "Módulo de Corte" msgid "Auto Fire Extinguishing System" msgstr "Sistema Automático de Extinção de Incêndio" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10730,6 +11196,9 @@ msgstr "Falha na atualização" msgid "Update successful" msgstr "Atualização bem-sucedida" +msgid "Hotends on Rack" +msgstr "Hotends no Rack" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Tem certeza de que deseja atualizar? Isso levará cerca de 10 minutos. Não desligue a energia enquanto a impressora estiver atualizando." @@ -10833,6 +11302,9 @@ msgstr "Erro de agrupamento: " msgid " can not be placed in the " msgstr " não pode ser colocado na " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Ponte interna" @@ -11164,7 +11636,7 @@ msgid "The precise wall option will be ignored for outer-inner or inner-outer-in msgstr "A opção de parede precisa será ignorada para sequências externa-interna ou interna-externa-interna." msgid "The Adaptive Pressure Advance model for one or more extruders may contain invalid values." -msgstr "" +msgstr "O modelo de Pressure Advance Adaptativo para uma ou mais extrusoras pode conter valores inválidos." msgid "Filament shrinkage will not be used because filament shrinkage for the used filaments does not match." msgstr "A contração de filamento não será usada porque a contração dos filamentos usados difere significativamente." @@ -11540,7 +12012,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11554,7 +12026,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12003,9 +12475,6 @@ msgstr "" "A geometria será decimada antes de detectar ângulos agudos. Este parâmetro indica o comprimento mínimo da divergência para a decimação.\n" "0 para desativar." -msgid "Select printers" -msgstr "Selecionar impressoras" - msgid "upward compatible machine" msgstr "uáquina compatível ascendente" @@ -12016,9 +12485,6 @@ msgstr "Condição" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Uma expressão booleana usando os valores de configuração de um perfil de impressora ativo. Se essa expressão for avaliada como true, esse perfil será considerado compatível com o perfil de impressora ativo." -msgid "Select profiles" -msgstr "Selecionar perfis" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Uma expressão booleana usando os valores de configuração de um perfil de impressão ativo. Se essa expressão for avaliada como true, esse perfil será considerado compatível com o perfil de impressão ativo." @@ -12286,6 +12752,42 @@ msgstr "Densidade da superfície superior" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Densidade da camada superior. Um valor de 100% cria uma camada superior totalmente sólida e lisa. Reduzir esse valor resulta em uma superfície superior texturizada, de acordo com o padrão de superfície superior escolhido. Um valor de 0% resultará na criação apenas das paredes da camada superior. Destinado a fins estéticos ou funcionais, não para corrigir problemas como extrusão excessiva." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Padrão de superfície inferior" @@ -12467,16 +12969,16 @@ msgstr "" "A taxa de fluxo final do objeto é este valor multiplicado pela taxa de fluxo do filamento." msgid "Enable pressure advance" -msgstr "Habilitar avanço de pressão" +msgstr "Habilitar pressure advance" msgid "Enable pressure advance, auto calibration result will be overwritten once enabled." -msgstr "Habilitar avanço de pressão, o resultado da calibração automática será sobrescrito uma vez habilitado." +msgstr "Habilitar pressure advance, o resultado da calibração automática será sobrescrito uma vez habilitado." msgid "Pressure advance (Klipper) AKA Linear advance factor (Marlin)." -msgstr "Avanço de pressão (Klipper) também conhecido como Fator de avanço linear (Marlin)" +msgstr "Pressure advance (Klipper) também conhecido como Fator de avanço linear (Marlin)" msgid "Enable adaptive pressure advance (beta)" -msgstr "Habilitar avanço de pressão adaptativo (beta)" +msgstr "Habilitar pressure advance adaptativo (beta)" #, no-c-format, no-boost-format msgid "" @@ -12489,13 +12991,13 @@ msgid "" msgstr "" "Com o aumento das velocidades de impressão (e, portanto, do fluxo volumétrico através do bico) e acelerações crescentes, observou-se que o valor efetivo de PA normalmente diminui. Isso significa que um único valor de PA nem sempre é 100% ideal para todos os recursos e um valor de compromisso é geralmente usado para não causar muita protuberância em partes com menor velocidade de fluxo e acelerações, mas também não causar lacunas em partes mais rápidas.\n" "\n" -"Este recurso visa abordar essa limitação modelando a resposta do sistema de extrusão da sua impressora dependendo da velocidade de fluxo volumétrico e aceleração em que está imprimindo. Internamente, ele gera um modelo ajustado que pode extrapolar o avanço de pressão necessário para qualquer velocidade de fluxo volumétrico e aceleração, que é então emitido para a impressora dependendo das condições de impressão atuais.\n" +"Este recurso visa abordar essa limitação modelando a resposta do sistema de extrusão da sua impressora dependendo da velocidade de fluxo volumétrico e aceleração em que está imprimindo. Internamente, ele gera um modelo ajustado que pode extrapolar o pressure advance necessário para qualquer velocidade de fluxo volumétrico e aceleração, que é então emitido para a impressora dependendo das condições de impressão atuais.\n" "\n" -"Quando habilitado, o valor de avanço de pressão acima é substituído. No entanto, um valor padrão razoável acima é fortemente recomendado para atuar como um fallback e para quando a ferramenta for trocada.\n" +"Quando habilitado, o valor do pressure advance acima é substituído. No entanto, um valor padrão razoável acima é fortemente recomendado para atuar como um fallback e para quando a ferramenta for trocada.\n" "\n" msgid "Adaptive pressure advance measurements (beta)" -msgstr "Medidas de avanço de pressão adaptativo (beta)" +msgstr "Medidas do pressure advance adaptativo (beta)" #, no-c-format, no-boost-format msgid "" @@ -12510,19 +13012,19 @@ msgid "" "2. Take note of the optimal PA value for each volumetric flow speed and acceleration. You can find the flow number by selecting flow from the color scheme drop down and move the horizontal slider over the PA pattern lines. The number should be visible at the bottom of the page. The ideal PA value should be decreasing the higher the volumetric flow is. If it is not, confirm that your extruder is functioning correctly. The slower and with less acceleration you print, the larger the range of acceptable PA values. If no difference is visible, use the PA value from the faster test\n" "3. Enter the triplets of PA values, Flow and Accelerations in the text box here and save your filament profile." msgstr "" -"Adicione conjuntos de valores de avanço de pressão (PA), as velocidades de fluxo volumétrico e acelerações em que foram medidos, separados por uma vírgula. Um conjunto de valores por linha. Por exemplo\n" +"Adicione conjuntos de valores do pressure advance (PA), as velocidades de fluxo volumétrico e acelerações em que foram medidos, separados por uma vírgula. Um conjunto de valores por linha. Por exemplo\n" "0,04,3,96,3000\n" "0,033,3,96,10000\n" "0,029,7,91,3000\n" "0,026,7,91,10000\n" "\n" "Como calibrar:\n" -"1. Execute o teste de avanço de pressão para pelo menos 3 velocidades por valor de aceleração. É recomendado que o teste seja executado para pelo menos a velocidade dos perímetros externos, a velocidade dos perímetros internos e a velocidade de impressão de recurso mais rápida em seu perfil (geralmente é o preenchimento esparso ou sólido). Em seguida, execute-os para as mesmas velocidades para as acelerações de impressão mais lentas e mais rápidas, e não mais rápido do que a aceleração máxima recomendada, conforme fornecido pelo modelador de entrada do Klipper\n" +"1. Execute o teste de pressure advance para pelo menos 3 velocidades por valor de aceleração. É recomendado que o teste seja executado para pelo menos a velocidade dos perímetros externos, a velocidade dos perímetros internos e a velocidade de impressão de recurso mais rápida em seu perfil (geralmente é o preenchimento esparso ou sólido). Em seguida, execute-os para as mesmas velocidades para as acelerações de impressão mais lentas e mais rápidas, e não mais rápido do que a aceleração máxima recomendada, conforme fornecido pelo modelador de entrada do Klipper\n" "2. Anote o valor de PA ideal para cada velocidade e aceleração de fluxo volumétrico. Você pode encontrar o número do fluxo selecionando fluxo no menu suspenso do esquema de cores e movendo o controle deslizante horizontal sobre as linhas do padrão de PA. O número deve estar visível na parte inferior da página. O valor de PA ideal deve diminuir quanto maior for o fluxo volumétrico. Se não estiver, confirme se sua extrusora está funcionando corretamente. Quanto mais lento e com menos aceleração você imprimir, maior será o intervalo de valores de PA aceitáveis. Se nenhuma diferença for visível, use o valor de PA do teste mais rápido\n" "3. Insira os tripletos de valores de PA, Fluxo e Acelerações na caixa de texto aqui e salve seu perfil de filamento." msgid "Enable adaptive pressure advance within features (beta)" -msgstr "" +msgstr "Habilitar pressure advance adaptativo nos recursos (beta)" msgid "" "Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n" @@ -12533,7 +13035,7 @@ msgid "" msgstr "" msgid "Static pressure advance for bridges" -msgstr "" +msgstr "Pressure advance estático para pontes" msgid "" "Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n" @@ -12541,6 +13043,10 @@ msgid "" "\n" "A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this." msgstr "" +"Valor de pressure advance (avanço de pressão) estático para pontes. Defina como 0 para aplicar o mesmo pressure advance que \n" +"paredes equivalentes (usando configurações adaptativas, se habilitadas).\n" +"\n" +"Um valor de PA mais baixo ao imprimir pontes ajuda a reduzir a ocorrência de leve subextrusão logo após as pontes. Isso é causado pela queda de pressão no bico durante a impressão no ar, e um PA mais baixo ajuda a compensar esse efeito." msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Largura de linha padrão se outras larguras de linha estiverem definidas como 0. Se expresso como %, será calculado sobre o diâmetro do bico." @@ -12608,12 +13114,18 @@ msgstr "Automático para purga" msgid "Auto For Match" msgstr "Automático para correspondência" +msgid "Nozzle Manual" +msgstr "Manual do Bico" + msgid "Flush temperature" msgstr "Temperatura de purga" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Temperatura ao purgar filamento. 0 indica o limite superior da faixa de temperatura recomendada para o bico." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Velocidade volumétrica de purga" @@ -12876,6 +13388,12 @@ msgstr "Filamento imprimível" msgid "The filament is printable in extruder." msgstr "O filamento é imprimível na extrusora." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Temperatura de amolecimento" @@ -12935,15 +13453,13 @@ msgstr "Densidade do preenchimento esparso" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Densidade do preenchimento esparso interno, 100% transforma todo o preenchimento esparso em preenchimento sólido e será usado o padrão de preenchimento sólido interno." -msgid "Align infill direction to model" -msgstr "Alinhar direção do preenchimento ao modelo" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"Alinha as direções do preenchimento, das pontes, do alisamento e do preenchimento de superfícies à orientação do modelo na mesa de impressão.\n" -"Quando ativado, as direções giram com o modelo para manter características ideais de resistência." msgid "Insert solid layers" msgstr "Inserir camadas sólidas" @@ -13287,11 +13803,11 @@ msgid "" "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." msgstr "" -"Tipo de ruído a ser usado para geração de textura difusa:\n" +"Tipos de ruído a serem usados para geração de textura difusa:\n" "Clássico: Ruído aleatório uniforme clássico;\n" "Perlin: Ruído Perlin, que dá uma textura mais consistente;\n" "Billow: Semelhante ao ruído Perlin, mas mais aglomerado;\n" -"Multifractal estriado: Ruído estriado com características pontiagudas e irregulares. Cria texturas semelhantes a mármore;\n" +"Multifractal Estriado: Ruído estriado com características pontiagudas e irregulares. Cria texturas semelhantes a mármore;\n" "Voronoi: Divide a superfície em células Voronoi e desloca cada uma delas por uma quantidade aleatória. Cria uma textura de retalhos;\n" "Ondulação: Padrão de ondulação uniforme que se propaga para a esquerda e para a direita do caminho original. Padrão repetitivo, com aparência de tecido." @@ -13356,7 +13872,7 @@ msgstr "" "O deslocamento é aplicado uma vez a cada número de camadas definido em Camadas entre deslocamento de ondulação, de modo que as camadas dentro do mesmo grupo sejam impressas de forma idêntica." msgid "Layers between ripple offset" -msgstr "Camadas entre o deslocamento de onda" +msgstr "Camadas entre o deslocamento de ondulação" msgid "" "Specifies how many consecutive layers share the same ripple phase before the offset is applied.\n" @@ -13475,6 +13991,15 @@ msgstr "Melhor posição de arranjo automático na faixa [0,1] em relação ao f msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Habilitar esta opção se a máquina tiver ventilador auxiliar de resfriamento de peças. Comando G-code: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13549,6 +14074,12 @@ msgstr "" "Esta opção está habilitada se a máquina suportar o controle da temperatura da câmara.\n" "Comando G-code: M141 S(0-255)" +msgid "Use cooling filter" +msgstr "Usar filtro de resfriamento" + +msgid "Enable this if printer support cooling filter" +msgstr "Ative essa opção se a impressora suportar filtro de resfriamento" + msgid "G-code flavor" msgstr "Tipo de G-code" @@ -14081,6 +14612,30 @@ msgstr "Velocidade mínima de movimento" msgid "Minimum travel speed (M205 T)" msgstr "Velocidade mínima de movimento (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Força máxima do eixo Y" + +msgid "The allowed maximum output force of Y axis" +msgstr "A força máxima de saída permitida do eixo Y" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Massa da mesa do eixo Y" + +msgid "The machine bed mass load of Y axis" +msgstr "A carga de massa da mesa do equipamento no eixo Y" + +msgid "g" +msgstr "G" + +msgid "The allowed max printed mass" +msgstr "Massa máxima de impressão permitida" + +msgid "The allowed max printed mass on a plate" +msgstr "A massa máxima de impressão permitida em uma placa" + msgid "Maximum acceleration for extruding" msgstr "Aceleração máxima para extrusão" @@ -14253,9 +14808,9 @@ msgstr "" "\n" "Um valor de 0 desativa o recurso.\n" "\n" -"Para uma impressora de acionamento direto de alta velocidade e alto fluxo (como a Bambu lab ou Voron), esse valor geralmente não é necessário. No entanto, pode fornecer alguns benefícios marginais em certos casos em que as velocidades das características variam muito. Por exemplo, quando há desacelerações agressivas devido a saliências. Nesses casos, um valor alto de cerca de 300-350 mm³/s² é recomendado, pois isso permite apenas suavização suficiente para ajudar o avanço de pressão a alcançar uma transição de fluxo mais suave.\n" +"Para uma impressora de acionamento direto de alta velocidade e alto fluxo (como a Bambu lab ou Voron), esse valor geralmente não é necessário. No entanto, pode fornecer alguns benefícios marginais em certos casos em que as velocidades das características variam muito. Por exemplo, quando há desacelerações agressivas devido a saliências. Nesses casos, um valor alto de cerca de 300-350 mm³/s² é recomendado, pois isso permite apenas suavização suficiente para ajudar o pressure advance a alcançar uma transição de fluxo mais suave.\n" "\n" -"Para impressoras mais lentas sem avanço de pressão, o valor deve ser definido muito mais baixo. Um valor de 10-15 mm³/s² é um bom ponto de partida para extrusoras de acionamento direto e 5-10 mm³/s² para estilo Bowden.\n" +"Para impressoras mais lentas sem pressure advance, o valor deve ser definido muito mais baixo. Um valor de 10-15 mm³/s² é um bom ponto de partida para extrusoras de acionamento direto e 5-10 mm³/s² para estilo Bowden.\n" "\n" "Este recurso é conhecido como Equalizador de Pressão no PrusaSlicer.\n" "\n" @@ -14652,7 +15207,10 @@ msgid "Direct Drive" msgstr "Acionamento Direto" msgid "Bowden" -msgstr "Tubo" +msgstr "Bowden" + +msgid "Hybrid" +msgstr "Híbrido" msgid "Enable filament dynamic map" msgstr "Habilitar mapa dinâmico de filamento" @@ -14689,6 +15247,12 @@ msgstr "Velocidade de desretração" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Velocidade para recarregar o filamento no bico. Zero significa mesma velocidade da retração." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Usar retração de firmware" @@ -14720,6 +15284,9 @@ msgstr "Alinhada" msgid "Aligned back" msgstr "Alinhada atrás" +msgid "Back" +msgstr "Atrás" + msgid "Random" msgstr "Aleatória" @@ -14999,6 +15566,12 @@ msgstr "Se o modo suave ou tradicional for selecionado, um vídeo em timelapse s msgid "Traditional" msgstr "Tradicional" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Variação de temperatura" @@ -15086,6 +15659,18 @@ msgstr "Preparar todas as extrusoras de impressão" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Se ativado, todos as extrusoras de impressão serão preparados na borda frontal da mesa de impressão no início da impressão." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Raio de fechamento de vãos de fatiamento" @@ -15464,7 +16049,7 @@ msgstr "" "Se habilitado, este parâmetro também define uma variável G-code chamada chamber_temperature, que pode ser usada para passar a temperatura desejada da câmara para sua macro de início de impressão ou uma macro de absorção de calor como esta: PRINT_START (outras variáveis) CHAMBER_TEMP=[chamber_temperature]. Isso pode ser útil se sua impressora não suportar comandos M141/M191 ou se você desejar lidar com a absorção de calor na macro de início de impressão se nenhum aquecedor de câmara ativo estiver instalado." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15513,6 +16098,45 @@ msgstr "Espessura da casca do topo" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "O número de camadas sólidas superiores é aumentado ao fatiar se a espessura calculada pelas camadas da casca do topo for menor do que este valor. Isso pode evitar que a casca seja muito fina quando a altura da camada é pequena. 0 significa que esta configuração está desativada e a espessura da casca do topo é determinada apenas pelo número de camadas da casca do topo." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Essa é a velocidade em que o deslocamento é feito." @@ -15557,12 +16181,30 @@ msgstr "Multiplicador de purga" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Os volumes de purga reais são iguais ao multiplicador de purga multiplicado pelos volumes de purga na tabela." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Volume de preparo" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Este é o volume de material para preparar a extrusora na torre." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "Esta é a largura das torres de preparo." @@ -15848,6 +16490,57 @@ msgstr "Largura mínima de parede" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Largura da parede que substituirá elementos finos (de acordo com o tamanho mínimo do elemento) do modelo. Se a Largura mínima da parede for mais fina do que a espessura do elemento, a parede será tão espesso quanto o próprio elemento. É expresso como uma porcentagem sobre o diâmetro do bico." +msgid "Hotend change time" +msgstr "Tempo de troca do hotend" + +msgid "Time to change hotend." +msgstr "Hora de trocar o hotend." + +msgid "Hotend change" +msgstr "Troca do Hotend" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "Ao trocar o hotend, é recomendado extrudar um certo comprimento de filamento do bico original. Isso ajuda a minimizar o oozing do bico." + +msgid "Extruder change" +msgstr "Troca da extrusora" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Para evitar vazamento, o bocal executará um movimento de deslocamento inverso por um determinado período após a conclusão da compactação. A configuração define o tempo de viagem." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Para evitar vazamento, a temperatura do bico será resfriada durante a compactação. Portanto, o tempo de impacto deve ser maior do que o tempo de recarga. 0 significa desativado." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "A velocidade volumétrica máxima para compactação antes da troca de extrusor, onde -1 significa usar a velocidade volumétrica máxima." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "Para evitar o gotejamento, a temperatura do bico será reduzida durante a compactação. Nota: somente um comando de resfriamento e ativação do ventilador são acionados, não sendo garantido o alcance da temperatura alvo. 0 significa desativado." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "A velocidade volumétrica máxima para compactação antes de uma troca de hotend, em que -1 significa usar a velocidade volumétrica máxima." + +msgid "length when change hotend" +msgstr "comprimento ao trocar o hotend" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "Quando este valor de retração for modificado, ele será usado como a quantidade de filament retraído dentro do hotend antes de trocar os hotends." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "O volume de material necessário para preparar o extrusor para uma troca do hotend na torre." + +msgid "Preheat temperature delta" +msgstr "Delta de temperatura de pré-aquecimento" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Delta de temperatura aplicado durante o pré-aquecimento antes da troca de ferramenta." + msgid "Detect narrow internal solid infills" msgstr "Detectar preenchimentos sólidos internos estreitos" @@ -16588,12 +17281,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Calibração não suportada" -msgid "Error desc" -msgstr "Descrição do erro" - -msgid "Extra info" -msgstr "Informação extra" - msgid "Flow Dynamics" msgstr "Dinâmica de Fluxo" @@ -16796,6 +17483,12 @@ msgstr "Por favor, insira o nome que você deseja salvar na impressora." msgid "The name cannot exceed 40 characters." msgstr "O nome não pode ter mais de 40 caracteres." +msgid "Nozzle ID" +msgstr "ID do Bico" + +msgid "Standard Flow" +msgstr "Fluxo Padrão" + msgid "Please find the best line on your plate" msgstr "Por favor, encontre a melhor linha em sua placa" @@ -16885,9 +17578,6 @@ msgstr "Informações de AMS e bico estão sincronizadas" msgid "Nozzle Flow" msgstr "Fluxo do Bico" -msgid "Nozzle Info" -msgstr "Informações de Bico" - msgid "Filament position" msgstr "Posição do filamento" @@ -16961,6 +17651,10 @@ msgstr "Sucesso ao obter o resultado anterior" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Atualizando os registros anteriores de Calibração de Dinâmica de Fluxo" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Nota: O número do hotend no %s está vinculado ao suporte. Quando o hotend for movido para um novo suporte, seu número será atualizado automaticamente." + msgid "Action" msgstr "Ação" @@ -18705,6 +19399,12 @@ msgstr "Impressão Falhou" msgid "Removed" msgstr "Removido" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Não me avise novamente" @@ -18738,12 +19438,25 @@ msgstr "Tutorial em vídeo" msgid "(Sync with printer)" msgstr "(Sinc. com impressora)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Vamos fatiar de acordo com este método de agrupamento:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Dica: Você pode arrastar os filamentos para reatribuí-los a diferentes bicos." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "O método de agrupamento de filamentos para a placa atual é determinado pela opção no botão de fatiamento da placa." @@ -18975,9 +19688,6 @@ msgstr "Esta ação não pode ser desfeita. Continuar?" msgid "Skipping objects." msgstr "Ignorando objetos." -msgid "Select Filament" -msgstr "Selecionar Filamento" - msgid "Null Color" msgstr "Cor Nula" @@ -19489,6 +20199,38 @@ msgstr "" "Evitar empenamento\n" "Você sabia que ao imprimir materiais propensos ao empenamento como ABS, aumentar adequadamente a temperatura da mesa aquecida pode reduzir a probabilidade de empenamento?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Renderiza sombras na placa em uma visualização realista." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "Aplica normais suaves à visualização realista.\n" +#~ "\n" +#~ "Requer a recarga manual da cena para fazer efeito (clique com o botão direito na visualização 3D → \"Recarregar Tudo\")." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Continue a sincronizar os filamentos" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Cancelar" + +#~ msgid "Align infill direction to model" +#~ msgstr "Alinhar direção do preenchimento ao modelo" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "Alinha as direções do preenchimento, das pontes, do alisamento e do preenchimento de superfícies à orientação do modelo na mesa de impressão.\n" +#~ "Quando ativado, as direções giram com o modelo para manter características ideais de resistência." + +#~ msgid "Print" +#~ msgstr "Imprimir" + #~ msgid "in" #~ msgstr "pol" @@ -19539,17 +20281,17 @@ msgstr "" #~ msgstr "O conteúdo da predefinição é muito grande para ser sincronizado com a nuvem (excede 1 MB). Reduza o tamanho da predefinição removendo configurações personalizadas ou use-o apenas localmente." #~ msgid "Enable adaptive pressure advance for overhangs (beta)" -#~ msgstr "Habilitar avanço de pressão adaptável para saliências (beta)" +#~ msgstr "Habilitar pressure advance adaptativo para saliências (beta)" #~ msgid "Pressure advance for bridges" -#~ msgstr "Avanço de pressão para pontes" +#~ msgstr "Pressure advance para pontes" #~ msgid "" #~ "Pressure advance value for bridges. Set to 0 to disable.\n" #~ "\n" #~ "A lower PA value when printing bridges helps reduce the appearance of slight under extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this." #~ msgstr "" -#~ "Valor de avanço de pressão para pontes. Defina como 0 para desabilitar.\n" +#~ "Valor do pressure advance para pontes. Defina como 0 para desabilitar.\n" #~ "\n" #~ "Um valor de PA mais baixo ao imprimir pontes ajuda a reduzir a aparência de leve subextrusão imediatamente após as pontes. Isso é causado pela queda de pressão no bico ao imprimir no ar e um PA mais baixo ajuda a neutralizar isso." @@ -19771,7 +20513,7 @@ msgstr "" #~ msgstr "" #~ "Habilite esta opção para desacelerar a impressão em áreas onde os perímetros podem ter se curvado para cima. Por exemplo, uma desaceleração adicional será aplicada ao imprimir saliências em cantos afiados, como a parte frontal do casco Benchy, reduzindo a curvatura que se acumula por várias camadas.\n" #~ "\n" -#~ "Geralmente, é recomendável ter esta opção ativada, a menos que o resfriamento da impressora seja potente o suficiente ou a velocidade de impressão lenta o suficiente para que a curvatura do perímetro não aconteça. Se estiver imprimindo com uma alta velocidade de perímetro externo, este parâmetro pode introduzir pequenos artefatos ao desacelerar devido à grande variação nas velocidades de impressão. Se você notar artefatos, certifique-se de que seu avanço de pressão esteja ajustado corretamente.\n" +#~ "Geralmente, é recomendável ter esta opção ativada, a menos que o resfriamento da impressora seja potente o suficiente ou a velocidade de impressão lenta o suficiente para que a curvatura do perímetro não aconteça. Se estiver imprimindo com uma alta velocidade de perímetro externo, este parâmetro pode introduzir pequenos artefatos ao desacelerar devido à grande variação nas velocidades de impressão. Se você notar artefatos, certifique-se de que seu pressure advance esteja ajustado corretamente.\n" #~ "\n" #~ "Observação: quando esta opção estiver habilitada, os perímetros de saliência são tratados como saliências, o que significa que a velocidade de saliência é aplicada mesmo se o perímetro de saliência for parte de uma ponte. Por exemplo, quando os perímetros estiverem 100% salientes, sem nenhuma parede apoiando-os por baixo, a velocidade de saliência de 100% será aplicada." @@ -20229,10 +20971,10 @@ msgstr "" #~ msgstr "Ok" #~ msgid "Pressure Advance Guide" -#~ msgstr "Guia de Avanço de Pressão" +#~ msgstr "Guia de Pressure Advance" #~ msgid "Adaptive Pressure Advance Guide" -#~ msgstr "Guia de Avanço de Pressão Adaptativo" +#~ msgstr "Guia de Pressure Advance Adaptativo" #~ msgid "Wiki Guide: Temperature Calibration" #~ msgstr "Guia Wiki: Calibração de Temperatura" @@ -20443,9 +21185,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Não é possível iniciar sem um cartão SD." -#~ msgid "Update" -#~ msgstr "Atualizar" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Sensibilidade da pausa é" diff --git a/localization/i18n/ru/OrcaSlicer_ru.po b/localization/i18n/ru/OrcaSlicer_ru.po index 86110c89ee..7bc6e42c44 100644 --- a/localization/i18n/ru/OrcaSlicer_ru.po +++ b/localization/i18n/ru/OrcaSlicer_ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: OrcaSlicer V2.5.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-02-25 13:38+0300\n" "Last-Translator: Felix14_v2\n" "Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg \n" @@ -41,6 +41,24 @@ msgstr "Печать TPU с помощью AMS не поддерживается msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS не поддерживает Bambu Lab PET-CF." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Перед печатью TPU выполните холодную протяжку, чтобы избежать засорения. Вы можете воспользоваться функцией холодной протяжки на принтере." @@ -48,11 +66,14 @@ msgid "Damp PVA will become flexible and get stuck inside AMS, please take care msgstr "Влажный PVA становится гибким и застревает внутри AMS, поэтому перед использованием его необходимо просушить." msgid "Damp PVA is flexible and may get stuck in extruder. Dry it before use." -msgstr "Влажный PVA слишком гибок и может застрять в подающем механизме. Перед печатью им необходима сушка." +msgstr "Влажный PVA становится гибким и может застрять в подающем механизме. Перед печатью им необходима сушка." msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "Шероховатая поверхность PLA Glow может ускорить износ системы AMS, особенно внутренних компонентов AMS Lite." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Стекло-/угленаполненные материалы твёрдые и хрупкие, легко ломаются и застревают в AMS, поэтому используйте их с осторожностью." @@ -62,11 +83,93 @@ msgstr "PPS-CF – это хрупкий материал, который мож msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF – это хрупкий материал, который может сломаться в изогнутом тефлоновом канале подачи." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + # подставляется tag_type и extruder_name #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s не подходит для печати через %s экструдер." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Высокий расход" + +# Подставляется в "%s экструдер"; используется везде совместно с "High flow" +# (Обычный режим/Высокий расход) +msgid "Standard" +msgstr "Обычный" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Неизвестно" + +msgid "Hardened Steel" +msgstr "Закалённая сталь" + +msgid "Stainless Steel" +msgstr "Нержавеющая сталь" + +msgid "Tungsten Carbide" +msgstr "Карбид вольфрама" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Предупреждение" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "Обновление" + msgid "Current AMS humidity" msgstr "Текущая влажность внутри AMS" @@ -97,6 +200,85 @@ msgstr "Версия:" msgid "Latest version" msgstr "Последняя версия" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Пусто" + +msgid "Error" +msgstr "Ошибка" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Обновить" + +msgid "Refreshing" +msgstr "Обновление" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "Отмена" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "Серийный номер" + +msgid "Version" +msgstr "Версия" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + msgid "Support Painting" msgstr "Рисование поддержек" @@ -107,7 +289,7 @@ msgid "On highlighted overhangs only" msgstr "Только на подсвеченных нависаниях" msgid "Erase all" -msgstr "" +msgstr "Сброс" msgid "Highlight overhangs" msgstr "Выделить зоны нависания" @@ -173,6 +355,12 @@ msgstr "Заливка" msgid "Gap Fill" msgstr "Заливка вкраплений" +msgid "Vertical" +msgstr "Вертикальная линия" + +msgid "Horizontal" +msgstr "Горизонтальная линия" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Ограничить область работы инструмента настройкой «%1%»" @@ -191,13 +379,13 @@ msgid "Support generated" msgstr "Поддержка сгенерирована" msgid "Entering Paint-on supports" -msgstr "" +msgstr "Запуск режима рисования поддержек" msgid "Leaving Paint-on supports" -msgstr "" +msgstr "Выход из режима рисования поддержек" msgid "Paint-on supports editing" -msgstr "" +msgstr "Рисование поддержек" msgid "Gizmo-Place on Face" msgstr "Гизмо: Поверхностью на стол" @@ -228,8 +416,9 @@ msgstr "Обнаружение границ" msgid "Triangles" msgstr "Треугольники" +# Оверюзинг, в т.ч. в значении "профили". Меняю на универсальное "Материалы" msgid "Filaments" -msgstr "Прутки" +msgstr "Материалы" msgid "Brush" msgstr "Кисть" @@ -255,8 +444,9 @@ msgstr "Применить" msgid "Reset" msgstr "Сброс" +# Пока только в двух местах в значении названия клавиши msgid "Enter" -msgstr "" +msgstr "Enter" msgid "Shortcut Key " msgstr "Горячая клавиша " @@ -267,12 +457,6 @@ msgstr "Треугольник" msgid "Height Range" msgstr "Диапазон высот" -msgid "Vertical" -msgstr "Вертикальная линия" - -msgid "Horizontal" -msgstr "Горизонтальная линия" - msgid "Remove painted color" msgstr "Удаление окрашенного участка" @@ -284,13 +468,13 @@ msgid "To:" msgstr "Заменить на:" msgid "Entering color painting" -msgstr "" +msgstr "Запуск режима покраски" msgid "Leaving color painting" -msgstr "" +msgstr "Выход из режима покраски" msgid "Color painting editing" -msgstr "" +msgstr "Покраска модели" msgid "Paint-on fuzzy skin" msgstr "Рисование нечёткой оболочки" @@ -311,13 +495,13 @@ msgid "Enable painted fuzzy skin for this object" msgstr "Включить нечёткую оболочку для модели" msgid "Entering Paint-on fuzzy skin" -msgstr "" +msgstr "Запуск режим рисования нечёткой оболочки" msgid "Leaving Paint-on fuzzy skin" -msgstr "" +msgstr "Выход из режима рисования нечёткой оболочки" msgid "Paint-on fuzzy skin editing" -msgstr "" +msgstr "Рисование нечёткой оболочки" msgid "Move" msgstr "Перемещение" @@ -337,8 +521,10 @@ msgstr "Инструмент вращения" msgid "Optimize orientation" msgstr "Оптимизация положения модели" +# Изменить размер +msgctxt "Verb" msgid "Scale" -msgstr "Масштаб" +msgstr "Масштабировать" msgid "Gizmo-Scale" msgstr "Инструмент изменения размера" @@ -348,7 +534,7 @@ msgstr "Ошибка: сначала закройте текущий инстр msgctxt "inches" msgid "in" -msgstr "" +msgstr "″" msgid "mm" msgstr "мм" @@ -360,10 +546,10 @@ msgid "Fixed step drag" msgstr "Сместить с шагом" msgid "Context Menu" -msgstr "" +msgstr "Контекстное меню" msgid "Toggle Auto-Drop" -msgstr "" +msgstr "Переключить притягивание к столу" msgid "Single sided scaling" msgstr "Масштабирование без привязки к центру" @@ -380,6 +566,9 @@ msgstr "Коэф. масштаба" msgid "Object operations" msgstr "Операции с моделями" +msgid "Scale" +msgstr "Масштаб" + msgid "Volume operations" msgstr "Булевы операции с телами" @@ -402,7 +591,7 @@ msgid "Reset rotation" msgstr "Сброс вращения" msgid "World" -msgstr "" +msgstr "Стол" msgid "Object" msgstr "Модель" @@ -411,13 +600,13 @@ msgid "Part" msgstr "Часть" msgid "Relative" -msgstr "" +msgstr "Прибавить" msgid "Coordinate system used for transform actions." -msgstr "" +msgstr "Опорная система координат для изменения положения." msgid "Absolute" -msgstr "" +msgstr "Поворот" msgid "Reset current rotation to the value when open the rotation tool." msgstr "Сбросить последние изменения ориентации" @@ -425,6 +614,10 @@ msgstr "Сбросить последние изменения ориентац msgid "Reset current rotation to real zeros." msgstr "Сбросить ориентацию до изначальной" +msgctxt "Noun" +msgid "Scale" +msgstr "Масштаб" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Размер" @@ -514,20 +707,21 @@ msgid "Cut position" msgstr "Положение сечения" msgid "Build Volume" -msgstr "Область построения" +msgstr "Габарит" msgid "Multiple" -msgstr "Множитель" +msgstr "Множественный паз" msgid "Count" -msgstr "" +msgstr "Количество" msgid "Gap" msgstr "Зазор" # В английском тут в кучу намешаны и "отступ", и "интервал". Используется в -# настройках авторасстановки моделей (в значении отступа) и в окне настроек +# настройках авторасстановки моделей (в значении отступа), в окне настроек # рэмминга (в значении интервала, но там процент, так что не прям критично) +# и в инструменте резки (интервал) msgid "Spacing" msgstr "Отступ" @@ -563,7 +757,7 @@ msgid "Drag" msgstr "Перетащить" msgid "Move cut line" -msgstr "" +msgstr "Переместить секущую плоскость" msgid "Draw cut line" msgstr "Разместить секущую плоскость" @@ -612,9 +806,6 @@ msgstr "Пропорция прорези в клипсе, связанная с msgid "Confirm connectors" msgstr "Готово" -msgid "Cancel" -msgstr "Отмена" - msgid "Flip cut plane" msgstr "Сменить направление" @@ -656,12 +847,12 @@ msgstr "Объединить в сборку" msgid "Reset cutting plane and remove connectors" msgstr "Сброс позиции секущей плоскости и удаление всех соединений" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Разрезать" -msgid "Warning" -msgstr "Предупреждение" - msgid "Invalid connectors detected" msgstr "обнаружены ошибочные соединения" @@ -694,14 +885,21 @@ msgstr "текущее положение секущей плоскости с msgid "Connector" msgstr "Соединение" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Разрез по плоскости" msgid "Non-manifold edges be caused by cut tool: do you want to fix now?" -msgstr "При разрезании образовались открытые рёбра: запустить исправление?" +msgstr "При разрезании образовались открытые рёбра: запустить восстановление?" msgid "Repairing model object" -msgstr "Починка модели" +msgstr "Восстановление модели" msgid "Cut by line" msgstr "Разрез по линии" @@ -710,13 +908,13 @@ msgid "Delete connector" msgstr "Удалить соединение" msgid "Entering Cut gizmo" -msgstr "" +msgstr "Запуск инструмента резки" msgid "Leaving Cut gizmo" -msgstr "" +msgstr "Закрытие инструмента резки" msgid "Cut gizmo editing" -msgstr "" +msgstr "Изменение разреза" msgid "Mesh name" msgstr "Название" @@ -740,9 +938,6 @@ msgstr "Упрощение модели" msgid "Simplification is currently only allowed when a single part is selected" msgstr "В настоящее время упрощение работает только при выборе одной модели" -msgid "Error" -msgstr "Ошибка" - msgid "Extra high" msgstr "Очень высокая" @@ -791,13 +986,13 @@ msgid "Remove selection" msgstr "Удалить выделенное" msgid "Entering seam painting" -msgstr "Вход в рисование шва" +msgstr "Запуск режима рисования шва" msgid "Leaving Seam painting" -msgstr "Выход из рисования шва" +msgstr "Выход из режима рисования шва" msgid "Paint-on seam editing" -msgstr "Редактирование рисования шва" +msgstr "Редактирование шва" #. TRN - Input label. Be short as possible #. Select look of letter shape @@ -814,7 +1009,7 @@ msgid "Angle" msgstr "Угол" msgid "Embedded depth" -msgstr "Глубинапроникновения" +msgstr "Глубина проникновения" msgid "Input text" msgstr "Введите текст" @@ -848,38 +1043,39 @@ msgstr "Перемещение текста" msgid "Set Mirror" msgstr "Задание отражения" +# Ранее было «Рельефный текст», но с "р" и "ф" выявился баг: https://github.com/OrcaSlicer/OrcaSlicer/pull/14612#issuecomment-4930055748 | баг будет проявляться при ручном вводе проблемных символов, но мы можем хотя бы обойти его в варианте по умолчанию. msgid "Embossed text" -msgstr "Рельефный текст" +msgstr "Объёмный текст" msgid "Enter emboss gizmo" -msgstr "Гизмо: Вход в рельефный текст" +msgstr "Гизмо: Вход в объёмный текст" msgid "Leave emboss gizmo" -msgstr "Гизмо: выход из рельефного текста" +msgstr "Гизмо: выход из объёмного текста" msgid "Embossing actions" -msgstr "Действие c рельефным текстом" +msgstr "Действие c объёмным текстом" msgid "Position on surface" -msgstr "" +msgstr "Разместить на поверхности" msgid "Emboss" -msgstr "Рельефный текст" +msgstr "Объёмный текст" msgid "NORMAL" -msgstr "" +msgstr "ОБЫЧНЫЙ" msgid "SMALL" -msgstr "" +msgstr "МЕЛКИЙ" msgid "ITALIC" -msgstr "" +msgstr "КУРСИВ" msgid "SWISS" -msgstr "" +msgstr "ГРОТЕСК" msgid "MODERN" -msgstr "" +msgstr "СОВРЕМЕННЫЙ" msgid "First font" msgstr "Первый шрифт" @@ -891,35 +1087,36 @@ msgid "Advanced" msgstr "Расширенные" msgid "Reset all options except the text and operation" -msgstr "" +msgstr "Сбросить настройки текста" msgid "The text cannot be written using the selected font. Please try choosing a different font." msgstr "Невозможно создать текст с выбранным шрифтом, попробуйте указать другой." # Высвечивается не только с пробелами msgid "Embossed text cannot contain only white spaces." -msgstr "Рельефный текст не может быть пустым." +msgstr "Объёмный текст не может быть пустым." msgid "Text contains character glyph (represented by '?') unknown by font." -msgstr "Текст содержит символ (заменён на \"?\"), которого нет в шрифте." +msgstr "Текст содержит символ (заменён на «?»), которого нет в шрифте." msgid "Text input doesn't show font skew." -msgstr "Визуализация наклона шрифта в окне ввода текста не поддерживается." +msgstr "Изменения наклона шрифта не отражаются в поле ввода." msgid "Text input doesn't show font boldness." -msgstr "Визуализация толщины шрифта в окне ввода текста не поддерживается." +msgstr "Изменения толщины шрифта не отражаются в поле ввода." msgid "Text input doesn't show gap between lines." -msgstr "Визуализация межстрочного интервала в окне ввода текста не поддерживается." +msgstr "Изменения межстрочного интервала не отражаются в поле ввода." msgid "Too tall, diminished font height inside text input." -msgstr "Слишком высокий. Уменьшите высоту шрифта в окне ввода текста." +msgstr "Шрифт слишком велик, текст в поле ввода был уменьшен." msgid "Too small, enlarged font height inside text input." -msgstr "Слишком маленький. Увеличьте высоту шрифта в окне ввода текста." +msgstr "Шрифт слишком мал, текст в поле ввода был увеличен." +# Из-за бага в коде это предупреждение никогда не выводится (на момент 2.5.0-dev) msgid "Text doesn't show current horizontal alignment." -msgstr "Текст не отображает текущее горизонтальное выравнивание." +msgstr "Изменения выравнивания не отражаются в поле ввода." msgid "Revert font changes." msgstr "Сброс настроек шрифта" @@ -929,7 +1126,7 @@ msgid "Font \"%1%\" can't be selected." msgstr "Невозможно выбрать шрифт «%1%»." msgid "Operation" -msgstr "Операция" +msgstr "Операция:" #. TRN EmbossOperation #. ORCA @@ -960,7 +1157,7 @@ msgstr "Изменить тип текста" #, boost-format msgid "Rename style (%1%) for embossing text" -msgstr "Переименование стиля (%1%) рельефного текста" +msgstr "Переименование стиля (%1%) объёмного текста" msgid "Name can't be empty." msgstr "Имя не может быть пустым." @@ -1334,7 +1531,7 @@ msgstr "Неизвестное имя файла" #, boost-format msgid "SVG file path is \"%1%\"" -msgstr "Путь к файлу SVG \"%1%\"" +msgstr "Путь к файлу SVG «%1%»" msgid "Reload SVG file from disk." msgstr "Перезагрузить SVG файл с диска." @@ -1432,7 +1629,7 @@ msgstr "Парсер NanoSVG не может прочитать файл (%1%)." #, boost-format msgid "SVG file does NOT contain a single path to be embossed (%1%)." -msgstr "Файл SVG не содержит ни одного контура для рельефного текста (%1%)." +msgstr "Файл SVG не содержит ни одного контура для объёмного текста (%1%)." # ????? msgid "No feature" @@ -1475,10 +1672,10 @@ msgid "Restart selection" msgstr "Выбрать заново" msgid "Esc" -msgstr "" +msgstr "Esc" msgid "Cancel a feature until exit" -msgstr "Отменить выбор до выхода" +msgstr "Отменить выбор/выйти" msgid "Measure" msgstr "Измерения" @@ -1576,10 +1773,10 @@ msgid "Flip by Face 2" msgstr "Перевернуть грань 2" msgid "Entering Measure gizmo" -msgstr "" +msgstr "Запуск режима измерения" msgid "Leaving Measure gizmo" -msgstr "" +msgstr "Выход из режима измерения" # при выборе на столе msgid "Assemble" @@ -1614,15 +1811,18 @@ msgid "" "because they are restricted to the bed \n" "and only parts can be lifted." msgstr "" +"Рекомендуется объединить модели в сборку\n" +"для получения возможности поднимать их\n" +"над столом." msgid "Face and face assembly" msgstr "Сборка по граням" msgid "Entering Assembly gizmo" -msgstr "" +msgstr "Запуск режима сборки" msgid "Leaving Assembly gizmo" -msgstr "" +msgstr "Выход из режима сборки" msgid "Ctrl+" msgstr "Ctrl+" @@ -1754,15 +1954,15 @@ msgid "" msgstr "" "Начиная с версии 2.4.0, OrcaSlicer синхронизирует пользовательские профили через Orca Cloud вместо Bambu Cloud.\n" "\n" -"Чтобы перенести существующие профили, войдите в Orca Cloud, и они будут перенесены автоматически. Чтобы узнать больше о том, как OrcaSlicer хранит и синхронизирует ваши профили, или перенести профили вручную, посетите нашу вики.\n" +"Для автоматического переноса существующих профилей войдите в Orca Cloud. Посетите нашу Вики, чтобы узнать подробнее о ручном переносе, хранении и синхронизации профилей.\n" "\n" -"Если вы не использовали Bambu Cloud для синхронизации профилей, это изменение вас не затрагивает, и вы можете спокойно проигнорировать это сообщение." +"Можно спокойно игнорировать это сообщение, если вы ранее не использовали Bambu Cloud для синхронизации." msgid "Profile syncing change" -msgstr "" +msgstr "Изменения в синхронизации профилей" msgid "Learn more" -msgstr "" +msgstr "Подробнее" msgid "Reloading network plug-in..." msgstr "Перезагрузка сетевого плагина..." @@ -1788,7 +1988,7 @@ msgid "" "Click Yes to install it now." msgstr "" "Для работы некоторых функций Orca Slicer требуется Microsoft WebView2 Runtime.\n" -"Нажмите Да, чтобы установить." +"Нажмите «Да», чтобы установить." msgid "WebView2 Runtime" msgstr "WebView2 Runtime" @@ -1798,6 +1998,9 @@ msgid "" "Some features, including the setup wizard, may appear blank until it is installed.\n" "Please install it manually from https://developer.microsoft.com/microsoft-edge/webview2/ and restart Orca Slicer." msgstr "" +"Не удалось установить среду выполнения WebView2.\n" +"Некоторые страницы (такие как мастер настройки) будут недоступны до момента установки.\n" +"Необходимо выполнить установку в ручном режиме с https://developer.microsoft.com/microsoft-edge/webview2 и перезапустить OrcaSlicer." #, c-format, boost-format msgid "Resources path does not exist or is not a directory: %s" @@ -1828,16 +2031,16 @@ msgid "Info" msgstr "Информация" msgid "Loading printer & filament profiles" -msgstr "" +msgstr "Загрузка профилей принтеров и материалов" msgid "Creating main window" -msgstr "" +msgstr "Запуск окна" msgid "Loading current preset" -msgstr "" +msgstr "Загрузка текущего профиля" msgid "Showing main window" -msgstr "" +msgstr "Активация окна" msgid "" "The OrcaSlicer configuration file may be corrupted and cannot be parsed.\n" @@ -1888,13 +2091,14 @@ msgid "User logged out" msgstr "Пользователь вышел из системы" msgid "You are currently in Stealth Mode. To log into the Cloud, you need to disable Stealth Mode first." -msgstr "" +msgstr "Активен режим приватности. Отключите его для авторизации в облаке." msgid "Stealth Mode" -msgstr "Режим конфиденциальности (отключение телеметрии Bambulab)" +msgstr "Режим приватности" +# Не совсем прямой перевод, но лучше доносит то, чего пользователь лишается. msgid "Quit Stealth Mode" -msgstr "" +msgstr "Покинуть приватность" msgid "new or open project file is not allowed during the slicing process!" msgstr "Создание или открытие файла проекта невозможно во время нарезки." @@ -1906,45 +2110,58 @@ msgid "The version of Orca Slicer is too low and needs to be updated to the late msgstr "Слишком старая версия Orca Slicer. Для корректной работы обновите программу до последней версии." msgid "Cloud sync conflict:" -msgstr "" +msgstr "Конфликт синхронизации с облаком:" #, c-format, boost-format msgid "Cloud sync conflict for preset \"%s\":" -msgstr "" +msgstr "Конфликт синхронизации профиля «%s» с облаком:" msgid "" "This preset has a newer version in OrcaCloud.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"профиль имеет обновлённую версию в OrcaCloud.\n" +"«Загрузить из облака» отменит локальные изменения в пользу облачных. «Выгрузить в облако» выгрузит локальные изменения." msgid "" "A preset with this name already exists in OrcaCloud.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"профиль с таким именем уже существует в OrcaCloud.\n" +"«Загрузить из облака» заменит локальнный профиль облачным. «Выгрузить в облако» выгрузит локальный профиль в облако." msgid "" "A preset with the same name was previously deleted from the cloud.\n" "Delete will delete your local preset. Force push overwrites it with your local preset." msgstr "" +"профиль с таким именем был удалён из OrcaCloud.\n" +"«Удалить» сделает то же самое локально. «Выгрузить в облако» выгрузит локальный профиль в облако." msgid "" "There was an unexpected or unidentified preset conflict.\n" "Pull downloads the cloud copy. Force push overwrites it with your local preset." msgstr "" +"произошёл непредвиденный конфликт профилей.\n" +"«Загрузить из облака» сохранит профиль из облака. «Выгрузить в облако» сохранит локальный профиль." +# Не известно, один профиль меняется, или несколько. msgid "" "Force push will overwrite the cloud copy with your local preset changes.\n" "Do you want to continue?" msgstr "" +"«Выгрузить в облако» перезапишет сведения в облаке вашими локальными изменениями.\n" +"Вы действительно хотите продолжить?" #, c-format, boost-format msgid "" "Force push will overwrite the cloud copy of preset \"%s\" with your local changes.\n" "Do you want to continue?" msgstr "" +"«Выгрузить в облако» перезапишет профиль «%s» в облаке вашим локальным профилем.\n" +"Вы действительно хотите продолжить?" msgid "Resolve cloud sync conflict" -msgstr "" +msgstr "Решение проблем синхронизации" msgid "Retrieving printer information, please try again later." msgstr "Получение информации о принтере, попробуйте позднее." @@ -1987,14 +2204,14 @@ msgstr "Обновление политики конфиденциальност #, c-format, boost-format msgid "your Orca Cloud profile (user ID: \"%s\")" -msgstr "" +msgstr "профиль Orca Cloud (идентификатор: «%s»)" msgid "your default profile" -msgstr "" +msgstr "профиль по умолчанию" #, c-format, boost-format msgid "a user profile (folder: \"%s\")" -msgstr "" +msgstr "профиль пользователя (папка: «%s»)" #, c-format, boost-format msgid "" @@ -2002,48 +2219,56 @@ msgid "" "Do you want to migrate them to your OrcaCloud profile?\n" "This will copy your presets so they are available under your new account." msgstr "" +"Обнаружены пользовательские профили в %s.\n" +"Перенести их в папку пользователя, привязанного к OrcaSloud?\n" +"Файлы будут скопированы в папку нового пользователя и станут доступны для синхронизации." msgid "Migrate User Presets" -msgstr "" +msgstr "Перенести" #, c-format, boost-format msgid "" "Failed to migrate user presets:\n" "%s" msgstr "" +"Не удалось перенести профили:\n" +"%s" msgid "The number of user presets cached in the cloud has exceeded the upper limit, newly created user presets can only be used locally." -msgstr "Количество пользовательских профилей, кэшированных в облаке, превысило установленный лимит. Новые пользовательские профили можно будет использовать только локально." +msgstr "Количество пользовательских профилей в облаке превысило допустимый предел. Новые пользовательские профили можно будет сохранять только локально." msgid "Sync user presets" -msgstr "Синхронизировать пользовательские профили" +msgstr "Синхронизировать профили" #, c-format, boost-format msgid "The preset \"%s\" is too large to sync to the cloud (exceeds 1MB). Please reduce the preset size by removing custom configurations or use it locally only." -msgstr "" +msgstr "Размер файла профиля «%s» слишком велик для синхронизации (превышает 1 МБ). Сократите пользовательское содержимое или используйте профиль локально." #, c-format, boost-format msgid "%s updated from %s to %s" -msgstr "" +msgstr "%s обновлён с %s до %s" #, c-format, boost-format msgid "%s has been downloaded." -msgstr "" +msgstr "%s загружен." #, c-format, boost-format msgid "Bundle %s is no longer available." -msgstr "" +msgstr "Пакет %s больше недоступен." #, c-format, boost-format msgid "Bundle %s access is unauthorized." -msgstr "" +msgstr "Доступ к пакету %s не авторизован." msgid "Loading user preset" msgstr "Загрузка пользовательского профиля" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." -msgstr "" +msgstr "%s был удалён." msgid "Switching application language" msgstr "Изменение языка приложения" @@ -2054,6 +2279,18 @@ msgstr "Выбор языка" msgid "Language" msgstr "Язык" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2230,7 +2467,7 @@ msgid "OrcaSliced Combo" msgstr "Нарезанная Orca" msgid "Orca Badge" -msgstr "" +msgstr "Значок Orca" msgid "Orca Tolerance Test" msgstr "Тест точности Orca" @@ -2258,7 +2495,7 @@ msgid "" "Yes - Change these settings automatically\n" "No - Do not change these settings for me" msgstr "" -"На верхней поверхности модели присутствует рельефный текст. Для достижения оптимального результата рекомендуется установить «Порог одного периметра» (min_width_top_surface) равным 0, чтобы избежать проблем в работе настройки «Только один периметр на верхней поверхности».\n" +"На верхней поверхности модели присутствует объёмный текст. Для достижения оптимального результата рекомендуется установить «Порог верхней поверхности» (min_width_top_surface) равным 0, чтобы избежать проблем в работе настройки «Только один периметр на верхней поверхности».\n" "\n" "Да – применить рекомендуемые настройки\n" "Нет – ничего не менять" @@ -2306,10 +2543,10 @@ msgid "Printable" msgstr "Для печати" msgid "Auto Drop" -msgstr "" +msgstr "Притягивать к столу" msgid "Automatically drops the selected object to the build plate." -msgstr "" +msgstr "Автоматически притягивать модель к поверхности стола при её поднятии." msgid "Fix Model" msgstr "Восстановить модель" @@ -2596,7 +2833,7 @@ msgid "Set Filament for selected items" msgstr "Задать материал для выбранных элементов" msgid "Automatically snaps the selected object to the build plate." -msgstr "" +msgstr "Автоматически притягивать выбранную модель к поверхности стола." msgid "Unlock" msgstr "Разблокировать" @@ -2661,6 +2898,45 @@ msgstr "Перекрасить модель" msgid "Click the icon to shift this object to the bed" msgstr "Вытолкнуть на стол" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Загрузка файла" @@ -2670,6 +2946,9 @@ msgstr "Ошибка!" msgid "Failed to get the model data in the current file." msgstr "Не удалось получить данные модели из текущего файла." +msgid "Add primitive" +msgstr "" + # Базовый примитив – опасно оставлять узкоспециализированный перевод (чисто # для фигур), т.к. Generic уже сейчас используется в названии начала профилей. # Если им добавят локализацию, получится неуместно. @@ -2689,6 +2968,12 @@ msgstr "" msgid "Remove paint-on fuzzy skin" msgstr "Удалить покраску нечеткой оболочки" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Удаление диапазона высот слоёв" + msgid "Delete connector from object which is a part of cut" msgstr "Удаление соединения из модели, которое является частью разреза" @@ -2718,12 +3003,24 @@ msgstr "Удалить все соединения" msgid "Deleting the last solid part is not allowed." msgstr "Удаление последней твердотельной части не допускается." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Заданная модель состоит только из одной части и не может быть разделена." +msgid "Split to parts" +msgstr "Разделить на части" + msgid "Assembly" msgstr "Сборка" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Информация о вырезанных соединениях" @@ -2754,6 +3051,9 @@ msgstr "Диапазон высот слоёв" msgid "Settings for height range" msgstr "Настройки для диапазона высот слоёв" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Слой" @@ -2775,6 +3075,9 @@ msgstr "Тип:" msgid "Choose part type" msgstr "Выберите тип элемента" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Введите новое имя" @@ -2807,6 +3110,9 @@ msgstr "«%s» после сглаживания будет иметь боле msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "Сетка модели «%s» содержит ошибки. Выполните её восстановление." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Доп. профиль настроек" @@ -2816,9 +3122,6 @@ msgstr "Удалить параметр" msgid "to" msgstr "до" -msgid "Remove height range" -msgstr "Удаление диапазона высот слоёв" - msgid "Add height range" msgstr "Добавление диапазона высот слоёв" @@ -2874,7 +3177,7 @@ msgid "Brim" msgstr "Кайма" msgid "Object/Part Settings" -msgstr "" +msgstr "Сводка настроек моделей" msgid "Reset parameter" msgstr "Сбросить" @@ -3028,6 +3331,9 @@ msgstr "Выберите слот AMS, затем нажмите кнопку « msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Для выполнения этого действия требуется указать тип материала. Пожалуйста, дополните информацию об этом материале." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Будьте осторожны, изменение охлаждения в процессе печати может повлиять на её качество." @@ -3037,8 +3343,9 @@ msgstr "Изменить в любом случае" msgid "Off" msgstr "Выкл" +# Очередной оверюзинг строки в нескольких местах; невозможно перевести универсально. UPD: а точно ли оверюзинг? Поиск по коду выдаёт только одно место. Поэтому согласовываю с чувствительностью фильтрации внутренних мостов. msgid "Filter" -msgstr "Фильтровать" +msgstr "Низкая" msgid "Enabling filtration redirects the right fan to filter gas, which may reduce cooling performance." msgstr "Включение фильтрации направляет поток воздуха правого вентилятора через канал с фильтром, что может снизить эффективность охлаждения." @@ -3156,6 +3463,24 @@ msgstr "Подтверждение экструзии" msgid "Check filament location" msgstr "Проверка расположения прутка" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Температура не должна превышать " @@ -3195,18 +3520,75 @@ msgid "Filter nonSelected" msgstr "" msgid "Simple settings" -msgstr "" +msgstr "Простые настройки" msgid "Advanced settings" msgstr "Расширенные настройки" msgid "Expert settings" -msgstr "" +msgstr "Продвинутые настройки" msgid "Developer mode" msgstr "Режим разработчика" +# Подсказка переключателя настроек при включённом режиме разработчика msgid "Launch troubleshoot center" +msgstr "Запустить экран отладки" + +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Подтвердить" + +msgid "Extruder" +msgstr "Экструдер" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "Информация о сопле" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Игнорировать" + +msgid "Done." msgstr "" msgid "" @@ -3405,12 +3787,12 @@ msgid "Bad input data for EmbossCreateObjectJob." msgstr "Некорректный ввод для EmbossCreateObjectJob." msgid "Add Emboss text object" -msgstr "Добавление рельефного текста" +msgstr "Добавление объёмного текста" msgid "Bad input data for EmbossUpdateJob." msgstr "Некорректный ввод для EmbossUpdateJob." -# Вылазит при попытке ввода в поле рельефного текста любых символов, которых +# Вылазит при попытке ввода в поле объёмного текста любых символов, которых # нет в шрифте. Например, разные вариации пробелов модифицированной ширины, # составные смайлы или другие необычные символы юникода msgid "Created text volume is empty. Change text or font." @@ -3428,7 +3810,7 @@ msgid "Emboss attribute change" msgstr "Изменение свойств рельефа" msgid "Add Emboss text Volume" -msgstr "Добавление объёма рельефного текста" +msgstr "Добавление объёма объёмного текста" msgid "Font doesn't have any shape for given text." msgstr "В шрифте отсутствуют данные для создания формы введённого текста." @@ -3439,7 +3821,7 @@ msgid "There is no valid surface for text projection." msgstr "Невозможно спроецировать текст." msgid "An unexpected error occurred" -msgstr "" +msgstr "Произошла непредвиденная ошибка" msgid "Thermal Preconditioning for first layer optimization" msgstr "Преднагрев для оптимизации первого слоя" @@ -3518,30 +3900,25 @@ msgid "Libraries" msgstr "Библиотеки" msgid "This software uses open source components whose copyright and other proprietary rights belong to their respective owners" -msgstr "В данном программном обеспечении используются компоненты с открытым исходным кодом, авторские и иные права на которые принадлежат их соответствующим владельцам" +msgstr "В данном ПО используются компоненты с открытым исходным кодом, авторские и иные права на которые принадлежат их соответствующим владельцам" #, c-format, boost-format msgid "About %s" msgstr "О программе %s" +# Не знаю, как тут лучше красиво сформулировать по-русски, может потом кто-то исправит (или я сам сюда вернусь). Текст почти лирический, попытался это передать. msgid "Open-source slicing stands on a tradition of collaboration and attribution. Slic3r, created by Alessandro Ranellucci and the RepRap community, laid the foundation. PrusaSlicer by Prusa Research built on that work, Bambu Studio forked from PrusaSlicer, and SuperSlicer extended it with community-driven enhancements. Each project carried the work of its predecessors forward, crediting those who came before." -msgstr "" +msgstr "Разработчики и сообщество OrcaSlicer придерживаются идей открытости, совместной работы и взаимоуважения. Основоположником стал Slic3r, созданный в 2011 году Alessandro Ranellucci и сообществом RepRap. Компания Prusa Research основала на нём PrusaSlicer, от которого позднее ответвились Bambu Studio и SuperSlicer, вобравший в себя множество улучшений от сообщества. Каждый из них продолжал дело своих предшественников, отдавая должное тем, кто нёс его сквозь время." msgid "OrcaSlicer began in that same spirit, drawing from PrusaSlicer, BambuStudio, SuperSlicer, and CuraSlicer. But it has since grown far beyond its origins — introducing advanced calibration tools, precise wall and seam control and hundreds of other features." -msgstr "" +msgstr "OrcaSlicer начинал свой путь с тем же замыслом, опираясь на PrusaSlicer, Bambu Studio, SuperSlicer и Cura. Но с тех пор проект развился далеко за пределы своих истоков, привнеся в сферу печати расширенные инструменты калибровок, обработки швов, поверхностей и сотни других функций." msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." -msgstr "" - -msgid "Version" -msgstr "Версия" +msgstr "В наши дни OrcaSlicer – самый прогрессивный и распространённый в сообществе слайсер с открытым исходным кодом. Благодаря множеству инноваций он становится основой других слайсеров и движущей силой всей индустрии 3D-печати." msgid "AMS Materials Setting" msgstr "Настройка материалов AMS" -msgid "Confirm" -msgstr "Подтвердить" - msgid "Close" msgstr "Закрыть" @@ -3562,12 +3939,12 @@ msgstr "мин." msgid "The input value should be greater than %1% and less than %2%" msgstr "Введённое значение должно быть больше %1%, но меньше %2%" -msgid "SN" -msgstr "Серийный номер" - msgid "Factors of Flow Dynamics Calibration" msgstr "Коэф. калиб. динам. потока" +msgid "Wiki Guide" +msgstr "Руководство" + msgid "PA Profile" msgstr "Профиль PA" @@ -3657,9 +4034,9 @@ msgstr "Калибровка завершена. Теперь найдите н msgid "Save" msgstr "Сохранить" -# Используется в нескольких местах: в 2 местах в значении расположения (шва и камеры), в одном – на кнопке "назад" (калибровка бамбу) +msgctxt "Navigation" msgid "Back" -msgstr "Сзади" +msgstr "Назад" msgid "Example" msgstr "Пример" @@ -3741,6 +4118,19 @@ msgstr "Правый экструдер" msgid "Nozzle" msgstr "Экструдер" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "Выбрать филамент" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Примечание: тип филамента (%s) не совпадает с типом филамента (%s) в файле нарезки. Если вы хотите использовать этот слот, установите %s вместо %s и измените информацию о слоте на странице «Устройство»." @@ -3915,7 +4305,7 @@ msgid "The network plug-in was installed but could not be loaded. Please restart msgstr "Сетевой плагин установлен, для его загрузки требуется перезапуск приложения." msgid "Restart Required" -msgstr "Требуется перезапуск" +msgstr "Требуется перезапуск." msgid "Please home all axes (click " msgstr "Пожалуйста, припаркуйте все оси в начало координат (нажав " @@ -4122,7 +4512,7 @@ msgstr "Текущая температура внутри термокамер #, c-format, boost-format msgid "The minimal chamber temperature (%d℃) is higher than the target chamber temperature (%d℃). The minimal value is the threshold at which printing starts while the chamber keeps heating toward the target, so it should not exceed it. It will be clamped to the target." -msgstr "" +msgstr "Минимальная температура внутри термокамеры (%d℃) превышает целевую (%d℃). Печать начинается по достижении минимальной температуры, поэтому она не должна быть больше целевой. Значение будет уменьшено." msgid "" "Layer height too small\n" @@ -4451,9 +4841,6 @@ msgstr "Измерение поверхности" msgid "Calibrating the detection position of nozzle clumping" msgstr "Калибровка положения обнаружения налипаний на сопло" -msgid "Unknown" -msgstr "Неизвестно" - msgid "Update successful." msgstr "Обновление успешно выполнено." @@ -4651,6 +5038,7 @@ msgstr "Настройки принтера" msgid "parameter name" msgstr "имя параметра" +# Используется в 12 местах, согласовать не получится msgid "layers" msgstr "слой(-я)" @@ -4732,7 +5120,7 @@ msgid "Acceleration" msgstr "Ускорение" msgid "Jerk" -msgstr "Jerk" +msgstr "Рывки" msgid "Fan Speed" msgstr "Охлаждение" @@ -4996,9 +5384,6 @@ msgstr "Оптимизировать" msgid "Regroup filament" msgstr "Изменить" -msgid "Wiki Guide" -msgstr "Руководство" - msgid "up to" msgstr "до" @@ -5032,7 +5417,7 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Скорость вентилятора (%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "Температура (°C)" msgid "Volumetric flow rate (mm³/s)" @@ -5050,9 +5435,6 @@ msgstr "Смена прутка" msgid "Options" msgstr "Параметры" -msgid "Extruder" -msgstr "Экструдер" - msgid "Cost" msgstr "Стоимость" @@ -5065,6 +5447,7 @@ msgstr "Смена инструмента" msgid "Color change" msgstr "Смена цвета" +msgctxt "Noun" msgid "Print" msgstr "Печать" @@ -5149,7 +5532,7 @@ msgid "Sequence" msgstr "Последовательность" msgid "Object selection" -msgstr "" +msgstr "Выбрать объект" msgid "number keys" msgstr "(цифры)" @@ -5213,13 +5596,13 @@ msgid "Arrange options" msgstr "Параметры расстановки" msgid "0 means auto spacing." -msgstr "0 - автоматический отступ." +msgstr "0 – автоматический отступ." msgid "Auto rotate for arrangement" msgstr "Разрешить вращение при расстановке" msgid "Allow multiple materials on same plate" -msgstr "Разрешить использование нескольких материалов на одном столе" +msgstr "Игнорировать разницу в материале" msgid "Avoid extrusion calibration region" msgstr "Избегать зону калибровки экструзии" @@ -5227,11 +5610,15 @@ msgstr "Избегать зону калибровки экструзии" msgid "Align to Y axis" msgstr "Выравнивать по оси Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Сзади" + +msgctxt "Camera View" msgid "Left" msgstr "Слева" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Справа" @@ -5256,9 +5643,6 @@ msgstr "Расставить модели на активном столе" msgid "Split to objects" msgstr "Разделить на модели" -msgid "Split to parts" -msgstr "Разделить на части" - msgid "Assembly View" msgstr "Сборочный вид" @@ -5315,10 +5699,10 @@ msgid "Outline" msgstr "Обводка выбранного" msgid "Wireframe" -msgstr "" +msgstr "Сетка модели" msgid "Realistic View" -msgstr "" +msgstr "Продвинутая графика" msgid "Perspective" msgstr "Перспектива" @@ -5589,6 +5973,11 @@ msgstr "Распечатать стол" msgid "Export G-code file" msgstr "Экспорт в G-код" +# Запустить печать/Отправить на печать +msgctxt "Verb" +msgid "Print" +msgstr "Печать" + msgid "Export plate sliced file" msgstr "Экспорт стола в файл проекта" @@ -5619,10 +6008,10 @@ msgid "Setup Wizard" msgstr "Мастер настройки" msgid "Show Configuration Folder" -msgstr "Показать конфигурационную папку" +msgstr "Открыть папку слайсера" msgid "Troubleshoot Center" -msgstr "" +msgstr "Экран отладки" msgid "Open Network Test" msgstr "Проверка сети" @@ -5764,15 +6153,6 @@ msgstr "Экспортировать текущую конфигурацию в msgid "Export" msgstr "Экспорт" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Выход" @@ -5855,10 +6235,10 @@ msgid "Show Gridlines on plate" msgstr "Показать разметку стола" msgid "Reset Window Layout" -msgstr "Сбросить настройки окон" +msgstr "Сбросить макет интерфейса" msgid "Reset to default window layout" -msgstr "Восстановить расположение окон по умолчанию" +msgstr "Восстановить стандартное расположение элементов интерфейса" msgid "Show &Labels" msgstr "Показать &имена файлов" @@ -5879,16 +6259,25 @@ msgid "Show outline around selected object in 3D scene." msgstr "Отображение контура вокруг выбранных моделей в окне подготовки." msgid "Preferences" -msgstr "Параметры" +msgstr "Настройки" msgid "View" msgstr "Вид" msgid "Preset Bundle" -msgstr "" +msgstr "Пакет профилей" + +msgid "Sync Presets" +msgstr "Синхронизация" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "Загрузить и применить новейшие профили из OrcaCloud" + +msgid "You must be logged in to sync presets from cloud." +msgstr "Для синхронизации с облаком необходима авторизация." msgid "Syncing presets from cloud…" -msgstr "" +msgstr "Синхронизация профилей с облаком…" msgid "Help" msgstr "Помощь" @@ -5918,20 +6307,21 @@ msgid "Cornering calibration" msgstr "Калибровка прохождения углов" msgid "Input Shaping Frequency" -msgstr "Частота Input Shaping" +msgstr "Частота шейпера" +# Коэффициент из формулы, использующейся в шейпинге. Подробнее тут: wikipedia.org/wiki/Затухающие_колебания msgid "Input Shaping Damping/zeta factor" -msgstr "Затухание Input Shaping/Коэффициент затухания (ζ)" +msgstr "Коэффициент затухания (ζ)" -# Тест шейпера +# подставляется после "Тест частоты" и "Тест затухания" msgid "Input Shaping" -msgstr "Input Shaping" +msgstr "Подбор параметров шейпера" msgid "VFA" msgstr "Тест ряби (VFA)" msgid "Calibration Guide" -msgstr "" +msgstr "Руководство по калибровкам" msgid "&Open G-code" msgstr "&Открыть файл G-кода" @@ -6007,6 +6397,9 @@ msgstr "Результат экспорта" msgid "Select profile to load:" msgstr "Выберите профиль для загрузки:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6171,9 +6564,6 @@ msgstr "Скачать выбранные файлы с принтера." msgid "Batch manage files." msgstr "Пакетное управление файлами." -msgid "Refresh" -msgstr "Обновить" - msgid "Reload file list from printer." msgstr "Перезагрузка списка файлов с принтера." @@ -6365,8 +6755,9 @@ msgstr "Мой принтер" msgid "Other Device" msgstr "Другое устройство" +# Ранее – "В сети". Вернуть как было после миграции на более функциональную систему локализации, которая умеет разделять строки в зависимости от их расположения. Сейчас статус "в сети" конфликтует с вкладкой настроек "Сеть" (тоже Online). msgid "Online" -msgstr "В сети" +msgstr "Онлайн" msgid "Input access code" msgstr "Введите код доступа" @@ -6377,8 +6768,9 @@ msgstr "Не удаётся найти свои принтеры?" msgid "Log out successful." msgstr "Выход выполнен успешно." +# Вернуть "Не в сети" в будущем, причину см. в строке "Online" msgid "Offline" -msgstr "Не в сети" +msgstr "Офлайн" msgid "Busy" msgstr "Занят" @@ -6487,6 +6879,9 @@ msgstr "Настройки печати" msgid "Safety Options" msgstr "Настройки защиты" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Свет" @@ -6520,6 +6915,12 @@ msgstr "Во время паузы смена материала поддерж msgid "Current extruder is busy changing filament." msgstr "В экструдере производится смена материала." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Слот уже занят." @@ -6570,11 +6971,6 @@ msgstr "Применимо только во время печати" msgid "Silent" msgstr "Тихий" -# Подставляется в "%s экструдер"; используется везде совместно с "High flow" -# (Обычный режим/Высокий расход) -msgid "Standard" -msgstr "Обычный" - msgid "Sport" msgstr "Спортивный" @@ -6608,6 +7004,12 @@ msgstr "Добавить фото" msgid "Delete Photo" msgstr "Удалить фото" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Отправить" @@ -6793,6 +7195,9 @@ msgstr "Как использовать режим «Только LAN»" msgid "Don't show this dialog again" msgstr "Не показывать снова" +msgid "Please refer to Wiki before use->" +msgstr "Перед использованием обратитесь к руководству →" + msgid "3D Mouse disconnected." msgstr "3D-мышь отключена." @@ -6892,22 +7297,22 @@ msgid "Model file downloaded." msgstr "Файл модели скачан." msgid "Pull" -msgstr "" +msgstr "Загрузить из облака" msgid "Force push" -msgstr "" +msgstr "Выгрузить в облако" msgid "Shared profiles may be available for this printer." -msgstr "" +msgstr "Для этого принтера могут быть доступны профили от сообщества." msgid "Browse shared profiles" -msgstr "" +msgstr "Найти профили сообщества" msgid "Serious warning:" msgstr "Серьёзное предупреждение:" msgid " (Repair)" -msgstr " (Починить)" +msgstr " (Восстановить)" msgid " Click here to install it." msgstr " Нажмите здесь, чтобы установить." @@ -7047,27 +7452,18 @@ msgstr "Расход" msgid "Please change the nozzle settings on the printer." msgstr "Пожалуйста, измените настройки сопла на принтере." -msgid "Hardened Steel" -msgstr "Закалённая сталь" - -msgid "Stainless Steel" -msgstr "Нержавеющая сталь" - -msgid "Tungsten Carbide" -msgstr "Карбид вольфрама" - msgid "Brass" msgstr "Латунь" msgid "High flow" msgstr "Высокий расход" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Ссылка на руководство по этому принтеру отсутствует." -msgid "Refreshing" -msgstr "Обновление" - msgid "Unavailable while heating maintenance function is on." msgstr "Недоступно, пока включена функция поддержания нагрева." @@ -7091,7 +7487,7 @@ msgid "Compare presets" msgstr "Сравнить профили" msgid "View all object's settings" -msgstr "Просмотр всех настроек модели" +msgstr "Сводка настроек моделей" msgid "Material settings" msgstr "Настройки материала" @@ -7198,6 +7594,16 @@ msgstr "Переключение диаметра" msgid "Configuration incompatible" msgstr "Несовместимый профиль" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +# "Подсказки" не влезают +msgid "Tips" +msgstr "Советы" + msgid "Sync printer information" msgstr "Информация о синхронизации с принтером" @@ -7226,6 +7632,9 @@ msgstr "Изменить профиль" msgid "Project Filaments" msgstr "Материалы проекта" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Объём прочистки" @@ -7446,10 +7855,6 @@ msgstr "Подключённый принтер – %s. Для печати он msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Синхронизировать информацию о принтере и переключить профиль?" -# "Подсказки" не влезают -msgid "Tips" -msgstr "Советы" - msgid "The file does not contain any geometry data." msgstr "Файл не содержит никаких геометрических данных." @@ -7505,14 +7910,26 @@ msgstr "" "Это действие приведёт к удалению информации о разрезе.\n" "Целостность модели после этого не гарантируется." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Невозможно разделить выбранную модель." -msgid "Disable Auto-Drop to preserve Z positioning?\n" +msgid "Split to Objects" msgstr "" +msgid "Disable Auto-Drop to preserve Z positioning?\n" +msgstr "Отключить притягивание компонентов к столу для сохранения высоты?\n" + msgid "Object with floating parts was detected" -msgstr "" +msgstr "Обнаружен объект с парящими элементами" msgid "Another export job is running." msgstr "Уже идёт другой процесс экспорта." @@ -7533,6 +7950,9 @@ msgstr "Выбор нового файла" msgid "File for the replacement wasn't selected" msgstr "Файл для замены не выбран" +msgid "Replace with 3D file" +msgstr "" + # В заголовке окна выбора папки и ошибки "папка не найдена" msgid "Select folder to replace from" msgstr "Выбор папки для замены моделей" @@ -7580,6 +8000,9 @@ msgstr "Не удалось перезагрузить:" msgid "Error during reload" msgstr "Ошибка во время перезагрузки" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Предупреждение о нарезке моделей:" @@ -7725,7 +8148,7 @@ msgid "All objects will be removed, continue?" msgstr "Все модели будут удалены, продолжить?" msgid "The current project has unsaved changes. Would you like to save before continuing?" -msgstr "В текущем проекте имеются несохранённые изменения. Сохранить их перед продолжением?" +msgstr "В текущем проекте имеются несохранённые изменения. Сохранить их и продолжить?" msgid "Number of copies:" msgstr "Количество копий:" @@ -7892,7 +8315,7 @@ msgid "Plate %d: %s is not suggested for use printing filament %s (%s). If you s msgstr "Покрытие %d-го стола (%s) не рекомендуется использовать для печати %s-м материалом (%s). Установите положительную температуру для этого покрытия в настройках материала, чтобы продолжить нарезку." msgid "Currently, the object configuration form cannot be used with a multiple-extruder printer." -msgstr "В настоящее время форма настройки объекта не может использоваться с многоэкструдерным принтером." +msgstr "Сводка настроек моделей пока не поддерживает многоэкструдерные принтеры." msgid "Not available" msgstr "Недоступно" @@ -7965,12 +8388,12 @@ msgid "" "\n" "Continue with enabling this feature?" msgstr "" -"Использование материалов со значительно отличающимися температурами может вызвать:\n" +"Печать материалами со значительно отличающимися температурами может вызвать:\n" "• засорение сопла;\n" "• повреждение сопла;\n" "• проблемы с адгезией.\n" -"\n" -"Включить эту функцию и продолжить?" +"Включить эту функцию и продолжить?\n" +" " # Сканирование IP принтеров в сети и поиск файла сертификата в файловом # менеджере @@ -8025,8 +8448,9 @@ msgstr "Не удалось перезагрузить сетевой плаги msgid "Reload Failed" msgstr "Перезапуск не удался" +# Строки дублируются, используем универсальное msgid "Associate" -msgstr "Ассоциация" +msgstr "Открытие" msgid "with OrcaSlicer so that Orca can open models from" msgstr "с OrcaSlicer, чтобы она могла открывать модели сразу с" @@ -8080,7 +8504,7 @@ msgid "Show the splash screen during startup." msgstr "Показывать окно приветствия при запуске программы." msgid "Use window buttons on left side" -msgstr "" +msgstr "Кнопки управления окном слева" msgid "(Requires restart)" msgstr "(требуется перезапуск)" @@ -8133,10 +8557,10 @@ msgid "Show options when importing STEP file" msgstr "Показывать настройки импорта STEP" msgid "If enabled, a parameter settings dialog will appear during STEP file import." -msgstr "Если включено, во время импорта STEP файла появится диалоговое окно настроек параметров импорта." +msgstr "Отображать диалоговое окно с настройками импорта при открытии файлов STEP." msgid "STEP importing: linear deflection" -msgstr "" +msgstr "Линейное отклонение при импорте STEP" msgid "" "Linear deflection used when meshing imported STEP files.\n" @@ -8144,9 +8568,15 @@ msgid "" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: 0.003 mm." msgstr "" +"Линейное отклонение при создании сетки импортируемых файлов STEP.\n" +"Чем меньше, тем выше точность поверхности и время обработки.\n" +"\n" +"Используется в качестве стандартного значения для диалога импорта (или для тихого импорта без отображения настроек).\n" +"\n" +"Значение по умолчанию: 0.003 мм." msgid "STEP importing: angle deflection" -msgstr "" +msgstr "Угловое отклонение при импорте STEP" msgid "" "Angle deflection used when meshing imported STEP files.\n" @@ -8154,15 +8584,25 @@ msgid "" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: 0.5." msgstr "" +"Угловое отклонение при создании сетки импортируемых файлов STEP.\n" +"Чем меньше, тем выше точность поверхности и время обработки.\n" +"\n" +"Используется в качестве стандартного значения для диалога импорта (или для тихого импорта без отображения настроек).\n" +"\n" +"Значение по умолчанию: 0.5°." msgid "STEP importing: Split into multiple objects" -msgstr "" +msgstr "Разделять отдельные тела на части" msgid "" "If enabled, compound and compsolid shapes in imported STEP files are split into multiple objects.\n" "Used as the default in the import dialog, or directly when the import dialog is disabled.\n" "Default: disabled." msgstr "" +"При импорте STEP автоматически разделять на части модели, состоящие из нескольких отдельных тел.\n" +"Используется в качестве стандартного значения для диалога импорта (или для тихого импорта без отображения настроек).\n" +"\n" +"По умолчанию: отключено." msgid "Quality level for Draco export" msgstr "Качество при экспорте в DRC" @@ -8180,10 +8620,10 @@ msgstr "" "0 – сжатие без потерь (представление с максимальной точностью)." msgid "Store full source file paths in projects" -msgstr "" +msgstr "Абсолютные пути файлов проекта" msgid "If enabled, saved projects store the absolute path to imported source files (STEP/STL/...), so \"Reload from disk\" still works when the source file is kept in a different folder than the project. If disabled, only the filename is stored, which keeps projects portable and avoids embedding absolute paths." -msgstr "" +msgstr "Сохранять абсолютные пути к внешним файлам, используемым внутри проекта (STEP, STL, SVG и т.д.), чтобы обеспечить возможность перезагрузки файлов с диска. По умолчанию хранится относительный путь для обеспечения портативности проектов." msgid "Preset" msgstr "Профиль" @@ -8216,10 +8656,10 @@ msgid "Optimizes filament area maximum height by chosen filament count." msgstr "Ограничить высоту секции с материалами проекта. При превышении лимита будет отображаться полоса прокрутки." msgid "Show shared profiles notification" -msgstr "" +msgstr "Уведомление о профилях сообщества" msgid "Show a notification with a link to browse shared profiles when the selected printer is changed." -msgstr "" +msgstr "Уведомлять о потенциальной доступности профилей от сообщества при смене профиля принтера." msgid "Features" msgstr "Возможности" @@ -8309,19 +8749,19 @@ msgid "Left Mouse Drag" msgstr "Перетаскивание левой кнопкой мыши" msgid "Set the action that dragging the left mouse button should perform." -msgstr "" +msgstr "Действие при перемещении курсора с зажатой левой кнопкой мыши." msgid "Middle Mouse Drag" msgstr "Перетаскивание колёсиком мыши" msgid "Set the action that dragging the middle mouse button should perform." -msgstr "" +msgstr "Действие при перемещении курсора с зажатой средней кнопкой мыши." msgid "Right Mouse Drag" msgstr "Перетаскивание правой кнопкой мыши" msgid "Set the action that dragging the right mouse button should perform." -msgstr "" +msgstr "Действие при перемещении курсора с зажатой правой кнопкой мыши." msgid "Clear my choice on..." msgstr "Сброс выбора по умолчанию" @@ -8350,40 +8790,40 @@ msgid "Clear my choice for synchronizing printer preset after loading the file." msgstr "Отменить выбор для синхронизации профиля принтера при открытии файла." msgid "Graphics" -msgstr "" - -msgid "Phong shading" -msgstr "" - -msgid "Uses Phong shading inside realistic view." -msgstr "" - -msgid "SSAO ambient occlusion" -msgstr "" - -msgid "Applies SSAO in realistic view." -msgstr "" - -msgid "Shadows" -msgstr "" - -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" +msgstr "Графика" msgid "Smooth normals" -msgstr "" +msgstr "Сглаживание бликов" msgid "" -"Applies smooth normals to the realistic view.\n" +"Applies smooth normals to the model.\n" "\n" "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." msgstr "" +msgid "Phong shading" +msgstr "Затенение по Фонгу" + +msgid "Uses Phong shading inside realistic view." +msgstr "Использовать затенение по Фонгу в режиме продвинутой графики." + +msgid "SSAO ambient occlusion" +msgstr "Фоновое затенение" + +msgid "Applies SSAO in realistic view." +msgstr "Применять фоновое затенение в пространстве экрана в режиме продвинутой графики." + +msgid "Shadows" +msgstr "Тени" + +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." +msgstr "" + msgid "Anti-aliasing" -msgstr "Anti-aliasing" +msgstr "Сглаживание" msgid "MSAA Multiplier" -msgstr "" +msgstr "Уровень MSAA" msgid "" "Set the Multi-Sample Anti-Aliasing level.\n" @@ -8393,56 +8833,71 @@ msgid "" "\n" "Requires application restart." msgstr "" +"Уровень сглаживания с множественной выборкой.Более высокие значения повышают качество отрисовки краёв объектов ценой экспоненциального роста вычислительной нагрузки.\n" +"Более низкие значения снижают нагрузку ценой падения качества отрисовки краёв.\n" +"При полном отключении рекомендуется использовать быстрое сглаживание FXAA.\n" +"\n" +"Примечание: для применения изменений требуется перезапуск." msgid "Disabled" msgstr "Отключено" msgid "FXAA post-processing" -msgstr "" +msgstr "Сглаживание FXAA" +# Довольно технично, проходы рендеринга лучше опустить msgid "" "Applies Fast Approximate Anti-Aliasing as a screen-space pass.\n" "Useful for disabling or reducing the MSAA setting to improve performance.\n" "\n" "Takes effect immediately." msgstr "" +"Применять быстрое приблизительное сглаживание.\n" +"Может улучшить изображение при отключении или низких значениях уровня MSAA.\n" +"\n" +"Применяется незамедлительно." msgid "FPS" msgstr "FPS" msgid "FPS cap" -msgstr "" +msgstr "Ограничение частоты кадров" msgid "(0 = unlimited)" -msgstr "" +msgstr "(0 – не ограничено)" msgid "" "Limits viewport frame rate to reduce GPU load and power usage.\n" "Set to 0 for unlimited frame rate." msgstr "" +"Ограничить частоту отрисовки рабочего пространства для снижения энергопотребления и нагрузки на ГП.\n" +"0 – не ограничивать частоту кадров." msgid "Show FPS overlay" -msgstr "" +msgstr "Отображать частоту кадров" msgid "Displays current viewport FPS in the top-right corner." -msgstr "" +msgstr "Выводить частоту кадров рабочего пространства в правом верхнем углу." msgid "Login region" msgstr "Регион входа" msgid "Stealth mode" -msgstr "Режим конфиденциальности (отключение телеметрии Bambu Lab)" +msgstr "Режим приватности" msgid "" "This disables all cloud features, including Orca Cloud profile syncing. Users who prefer to work entirely offline can enable this option.\n" "Note: When Stealth Mode is enabled, your user profiles will not be backed up to Orca Cloud." msgstr "" +"Отключить все облачные функции, включая синзронизацию профилей с облаком Orca Cloud. Пригодится пользователям, отдающим предпочтение приватной работе без связи с интернетом.\n" +"\n" +"Внимание: резервирование профилей в Orca Cloud будет недоступно." msgid "Hide login side panel" -msgstr "" +msgstr "Скрыть панель входа" msgid "Hide the login side panel on the home page." -msgstr "" +msgstr "Скрыть панель авторизации на главной странице." msgid "Network test" msgstr "Тестирование сети" @@ -8451,13 +8906,13 @@ msgid "Test" msgstr "Тест" msgid "Cloud Providers" -msgstr "" +msgstr "Поставщики услуг" msgid "Enable Bambu Cloud" -msgstr "" +msgstr "Облако Bambu Cloud" msgid "Allow logging into Bambu Cloud alongside Orca Cloud. When enabled, a Bambu login section appears on the homepage." -msgstr "" +msgstr "Разрешить вход в Bambu Cloud совместно с Orca Cloud. При включении на главной странице будет отображаться форма входа в учётную запись Bambu." msgid "Update & sync" msgstr "Обновление и синхронизация" @@ -8490,10 +8945,10 @@ msgid "Store authentication tokens in an encrypted file instead of the system ke msgstr "Сохранять токены аутентификации в зашифрованном файле вместо использования системной связки ключей (требуется перезапуск)." msgid "Bambu network plug-in" -msgstr "" +msgstr "Сетевой плагин Bambu" msgid "Enable Bambu network plug-in" -msgstr "" +msgstr "Включить сетевой плагин Bambu" msgid "Network plug-in version" msgstr "Версия сетевого плагина" @@ -8505,10 +8960,10 @@ msgid "Associate files to OrcaSlicer" msgstr "Открытие файлов по умолчанию" msgid "File associations for the Microsoft Store version are managed by Windows Settings." -msgstr "" +msgstr "Ассоциации файлов с версией для Microsoft Store управляются через настройки Windows." msgid "Open Windows Default Apps Settings" -msgstr "" +msgstr "Перейти в настройки" msgid "Associate 3MF files to OrcaSlicer" msgstr "Открывать файлы 3MF в OrcaSlicer" @@ -8544,21 +8999,27 @@ msgid "Skip AMS blacklist check" msgstr "Пропуск проверки материалов в AMS из файла чёрного списка" msgid "Show unsupported presets" -msgstr "" +msgstr "Показывать несовместимые профили" msgid "Show incompatible/unsupported presets in the printer and filament dropdown lists. These presets cannot be selected." msgstr "" +"Отображать в списке выбора профили материалов, несовместимые с текущим принтером.\n" +"\n" +"Примечание: профили остаются недоступными для выбора." msgid "Experimental Features" -msgstr "" +msgstr "Экспериментальные настройки" msgid "Keep painted feature after mesh change" -msgstr "" +msgstr "Восстанавливать нарисованное после изменения сетки" msgid "" "Attempt to keep painted features (color/seam/support/fuzzy etc.) after changing the object mesh (such as cut/reload from disk/simplify/fix etc.)\n" "Highly experimental! Slow and may create artifact." msgstr "" +"Пытаться восстановить нарисованные элементы (швы, поддержки, раскраску цветов и т.п.) после изменения сетки модели (в результате перезагрузки модели, её упрощения, восстановления, разделения и т.д.).\n" +"\n" +"Внимание: функция экспериментальна! Возможны падение производительности и артефакты работы." msgid "Allow Abnormal Storage" msgstr "Игнорировать неисправность хранилища" @@ -8651,6 +9112,9 @@ msgstr "Несовместимые профили" msgid "My Printer" msgstr "Мой принтер" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Остаток материалов" @@ -8669,6 +9133,9 @@ msgstr "Добавить/удалить профиль" msgid "Edit preset" msgstr "Изменить профиль" +msgid "Change extruder color" +msgstr "" + # Название группы материала в выпадающем списке, если включена группировка # кастомных профилей и в профиле не задан производитель и/или тип. msgid "Unspecified" @@ -8678,7 +9145,7 @@ msgid "Project-inside presets" msgstr "Профили внутри проекта" msgid "Bundle presets" -msgstr "" +msgstr "Профили в пакете" # На удивление, используется лишь единожды в группе профилей "Системные" в # ComboBox (судя по коду) @@ -8703,9 +9170,6 @@ msgstr "Выбрать принтеры" msgid "Create printer" msgstr "Создать принтер" -msgid "Empty" -msgstr "Пусто" - msgid "Incompatible" msgstr "Несовместимы" @@ -8937,12 +9401,42 @@ msgstr "отправка завершена" msgid "Error code" msgstr "Код ошибки" -msgid "High Flow" -msgstr "Высокий расход" +msgid "Error desc" +msgstr "Описание ошибки" + +msgid "Extra info" +msgstr "Доп. информация" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "Настройка потока сопла %s(%s) не совпадает с файлом нарезки (%s). Убедитесь, что установленное сопло соответствует настройкам принтера, затем выберите соответствующий профиль принтера при нарезке." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -9005,8 +9499,38 @@ msgstr "Будет затрачено на %d г материала и на %d msgid "nozzle" msgstr "сопло" -msgid "both extruders" -msgstr "обоих экструдерах" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "Настройка потока сопла %s(%s) не совпадает с файлом нарезки (%s). Убедитесь, что установленное сопло соответствует настройкам принтера, затем выберите соответствующий профиль принтера при нарезке." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "Совет: после замены сопла в принтере необходимо обновить его настройки («Принтер» → «Части принтера»)." @@ -9019,10 +9543,17 @@ msgstr "Диаметр %s (%.1f мм) текущего принтера не с msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Текущий диаметр сопла (%.1f мм) не совпадает с файлом нарезки (%.1f мм). Убедитесь, что установленное сопло соответствует настройкам принтера, и выберите соответствующий профиль принтера при нарезке." +msgid "both extruders" +msgstr "обоих экструдерах" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Требования к твёрдости у выбранного материала (%s) превышают возможности %s(%s). Проверьте настройки профиля принтера или материала и попробуйте ещё раз." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[%s] требует прогретой среды для печати: необходимо закрыть дверцу." @@ -9137,10 +9668,7 @@ msgid "The current firmware supports a maximum of 16 materials. You can either r msgstr "Текущая прошивка поддерживает не более 16 материалов. Попробуйте уменьшить их количество в настройках печати или обновить прошивку. Если обновление не помогло – ожидайте обновлений с расширением поддержки." msgid "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." -msgstr "" - -msgid "Please refer to Wiki before use->" -msgstr "Перед использованием обратитесь к руководству →" +msgstr "Тип материала на внешней катушке неизвестен или не соответствует материалу в файле печати. Убедитесь, что установлена внешняя катушка с требуемым материалом." msgid "Current firmware does not support file transfer to internal storage." msgstr "Прошивка принтера не поддерживает удалённую запись файлов в хранилище." @@ -9189,7 +9717,7 @@ msgid "File upload timed out. Please check if the firmware version supports this msgstr "Превышено время ожидания отправки файла. Убедитесь, что прошивка поддерживает эту функцию, и что принтер работает нормально." msgid "Sending failed, please try again!" -msgstr "" +msgstr "Ошибка отправки; попробуйте ещё раз." msgid "Slice complete" msgstr "Нарезка завершена." @@ -9260,7 +9788,7 @@ msgid "Terms and Conditions" msgstr "Условия использования" msgid "Thank you for purchasing a Bambu Lab device. Before using your Bambu Lab device, please read the terms and conditions. By clicking to agree to use your Bambu Lab device, you agree to abide by the Privacy Policy and Terms of Use (collectively, the \"Terms\"). If you do not comply with or agree to the Bambu Lab Privacy Policy, please do not use Bambu Lab equipment and services." -msgstr "Благодарим вас за покупку устройства Bambu Lab. Перед использованием устройства Bambu Lab ознакомьтесь с правилами и условиями. Нажимая на кнопку «Согласие на использование устройства Bambu Lab», вы соглашаетесь соблюдать Политику конфиденциальности и Условия использования (далее - «Условия»). Если вы не соблюдаете или не согласны с Политикой конфиденциальности Bambu Lab, пожалуйста, не пользуйтесь оборудованием и услугами Bambu Lab." +msgstr "Благодарим вас за покупку устройства Bambu Lab. Перед использованием устройства Bambu Lab ознакомьтесь с правилами и условиями. Нажимая на кнопку «Согласие на использование устройства Bambu Lab», вы соглашаетесь соблюдать Политику конфиденциальности и Условия использования (далее – «Условия»). Если вы не соблюдаете или не согласны с Политикой конфиденциальности Bambu Lab, пожалуйста, не пользуйтесь оборудованием и услугами Bambu Lab." msgid "and" msgstr "и" @@ -9314,11 +9842,14 @@ msgid "Synchronization of different extruder drives or nozzle volume types is no msgstr "" msgid "Synchronize the modification of parameters to the corresponding parameters of another extruder." -msgstr "" +msgstr "Перенести изменения в настройки другого экструдера." msgid "Click to reset all settings to the last saved preset." msgstr "Сбросить все изменения" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Для сглаженного таймлапса требуется черновая башня, без неё на модели могут возникнуть дефекты. Вы действительно хотите отключить черновую башню?" @@ -9382,7 +9913,7 @@ msgstr "" "• Растворимый материал для всей поддержки" msgid "Enabling this option will modify the model's shape. If your print requires precise dimensions or is part of an assembly, it's important to double-check whether this change in geometry impacts the functionality of your print." -msgstr "Включение этой опции приведёт к изменению формы модели. Если ваша печать требует точных размеров или является частью сборки, важно перепроверить, не повлияет ли изменение геометрии на функциональность напечатанного." +msgstr "Включение этой настройки приведёт к изменению формы модели. Если модель требует соблюдения точности размеров или является частью сборки, убедитесь, что изменение геометрии не повлияет на функциональность напечатанного." msgid "Are you sure you want to enable this option?" msgstr "Вы действительно хотите включить эту опцию?" @@ -9408,9 +9939,6 @@ msgstr "Автоматически подстроиться под заданн msgid "Adjust" msgstr "Подстроиться" -msgid "Ignore" -msgstr "Игнорировать" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "[Экспериментальная функция] Втягивание и обрезка прутка на большем расстоянии во время его замены для минимизации очистки. Хотя это значительно сокращает величину очистки, это может повысить риск возникновения затора или вызвать другие проблемы при печати." @@ -9497,7 +10025,7 @@ msgid "Precision" msgstr "Точность" msgid "Z contouring" -msgstr "" +msgstr "Сглаживание" msgid "Wall generator" msgstr "Генератор периметров" @@ -9566,8 +10094,9 @@ msgstr "Специальные режимы" msgid "G-code output" msgstr "Выходной G-код" +# G-код смены типа линии msgid "Change extrusion role G-code" -msgstr "G-код перехода к другому типу линии" +msgstr "G-код при смене типа линии" msgid "Post-processing Scripts" msgstr "Скрипты постобработки" @@ -9604,8 +10133,9 @@ msgstr "Замещение настроек" msgid "Basic information" msgstr "Основные" +# Тут указывается именно допустимый диапазон, который проверяется при печати несколькими материалами. Если у хотя бы одного материала температура из "температуры печати" выходит за этот диапазон, слайсер выдаёт ошибку. msgid "Recommended nozzle temperature" -msgstr "Рекомендуемая температура сопла" +msgstr "Допустимая температура сопла" msgid "Recommended nozzle temperature range of this filament. 0 means not set" msgstr "Рекомендуемый диапазон температур прогрева этого материала при печати. 0 – не задано." @@ -9620,13 +10150,13 @@ msgid "Chamber temperature" msgstr "Температура термокамеры" msgid "Target chamber temperature, and the minimal chamber temperature at which printing should start" -msgstr "" +msgstr "Целевая (основная) и минимальная температура термокамеры, с которой начинается печать" msgid "Target" -msgstr "" +msgstr "Целевая" msgid "Minimal" -msgstr "" +msgstr "Минимальная" msgid "Print temperature" msgstr "Температура печати" @@ -9665,13 +10195,14 @@ msgstr "Температура стола с текстурным покрыти msgid "Volumetric speed limitation" msgstr "Ограничение объёмного расхода" +# Адаптировал к новой настройке обдува на первом слое msgid "Cooling for specific layer" -msgstr "Обдув определённого слоя" +msgstr "Охлаждение начала печати" msgid "Part cooling fan" msgstr "Вентилятор обдува модели" -# Порог усиления обдува +# Порог усиления обдува, Усиливать обдув при... msgid "Min fan speed threshold" msgstr "Минимальный обдув слоя" @@ -9811,7 +10342,7 @@ msgid "Normal" msgstr "Обычный" msgid "Resonance Compensation" -msgstr "" +msgstr "Борьба с вертикальными артефактами" msgid "Resonance Avoidance Speed" msgstr "Диапазон избегаемых скоростей" @@ -9820,13 +10351,13 @@ msgid "Frequency" msgstr "Частота по" msgid "The frequency of the anti-vibration signal will correspond to the natural frequency of the frame." -msgstr "" +msgstr "Частота управляющего сигнала, противодействующего колебаниям механики принтера." msgid "Damping" -msgstr "" +msgstr "Коэффициент затухания" msgid "Damping ratio for the input shaping filter." -msgstr "" +msgstr "Используется для обработки шейпером колебаний с учётом снижающейся амплитуды." msgid "Speed limitation" msgstr "Максимальные скорости перемещения" @@ -9881,6 +10412,10 @@ msgid "" "\n" "Shall I set it to 100% in order to enable Firmware Retraction?" msgstr "" +"При использовании «отката на уровне прошивки» невозможно разделить откат на первичный и вторичный.\n" +"\n" +"Установить первичный откат на 100% для совместимости с функцией отката из прошивки?\n" +"Отказ приведёт к отключению последней." msgid "Firmware Retraction" msgstr "Откат из прошивки" @@ -9938,58 +10473,74 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Вы действительно хотите %1% выбранный профиль?" +msgid "Select printers" +msgstr "Профили принтеров" + +msgid "Select profiles" +msgstr "Профили настроек" + #, c-format, boost-format msgid "" " - %s:\n" " %s first layer %d %s, other layers %d %s\n" " %s max delta %d %s, current delta %d %s\n" msgstr "" +" - %s:\n" +" %s Первый слой – %d %s, основная – %d %s\n" +" %s допустимый перепад – %d %s, текущий – %d %s\n" msgid "Some first-layer and other-layer temperature pairs exceed safety limits.\n" -msgstr "" +msgstr "Некоторые пары температур превышают допустимый перепад.\n" msgid "" "\n" "Invalid pairs:\n" msgstr "" +"\n" +"Недопустимые пары:\n" msgid "" "\n" "You can go back to edit values, or continue if this is intentional." msgstr "" +"\n" +"Можно вернуться и изменить значения, либо проигнорировать предупреждение, если действие намеренно." msgid "" "\n" "\n" "Continue anyway?" msgstr "" +"\n" +"\n" +"Игнорировать предупреждение?" msgid "Temperature Safety Check" -msgstr "" +msgstr "Опасный перепад температур" msgid "Continue" msgstr "Продолжить" msgid "Don't warn again for this preset" -msgstr "" +msgstr "Больше не спрашивать для этого профиля" #, c-format, boost-format msgid "%s: %s" msgstr "" msgid "No modifications need to be copied." -msgstr "" +msgstr "Перенос изменений не требуется." msgid "Copy paramters" -msgstr "" +msgstr "Копировать настройки" #, c-format, boost-format msgid "Modify paramters of %s" -msgstr "" +msgstr "Изменить настройки %s" #, c-format, boost-format msgid "Do you want to modify the following parameters of the %s to that of the %s?" -msgstr "" +msgstr "Вы действительно хотите заменить следующие настройки %s настройками %s?" msgid "Click to reset current value and attach to the global value." msgstr "Сбросить значение до сохранённого" @@ -10021,8 +10572,9 @@ msgstr "Не сохранять" msgid "Discard" msgstr "Не сохранять" +# Используется для подстановки в new_profile в неопределённых случаях, когда профиль... не имеет названия? msgid "the new profile" -msgstr "" +msgstr "новый профиль" #, boost-format msgid "" @@ -10030,7 +10582,7 @@ msgid "" "\"%1%\"\n" "discarding any changes made in\n" "\"%2%\"." -msgstr "" +msgstr "Отменить изменения в «%2%» и переключиться на «%1%»." #, boost-format msgid "" @@ -10038,14 +10590,14 @@ msgid "" "\"%1%\"\n" "will be transferred to\n" "\"%2%\"." -msgstr "" +msgstr "Перенести все несохранённые изменения из «%1%» в «%2%»." #, boost-format msgid "" "All \"New Value\" settings are saved in\n" "\"%1%\"\n" "and \"%2%\" will open without any changes." -msgstr "" +msgstr "Сохранить изменения в «%1%» и переключиться на «%2%»." msgid "Click the right mouse button to display the full text." msgstr "Нажмите правой кнопкой мыши, чтобы отобразить полный текст." @@ -10071,7 +10623,7 @@ msgid "" "\"%1%\"." msgstr "" "Сохранить выбранные параметры в профиль \n" -"\"%1%\"." +"«%1%»." #, boost-format msgid "" @@ -10079,23 +10631,23 @@ msgid "" "\"%1%\"." msgstr "" "Перенести выбранные параметры во вновь выбранный профиль \n" -"\"%1%\"." +"«%1%»." #, boost-format msgid "Preset \"%1%\" contains the following unsaved changes:" -msgstr "Профиль \"%1%\" имеет следующие несохранённые изменения:" +msgstr "Профиль «%1%» имеет следующие несохранённые изменения:" #, boost-format msgid "Preset \"%1%\" is not compatible with the new printer profile and it contains the following unsaved changes:" -msgstr "Профиль \"%1%\" несовместим с новым профилем принтера, и имеет следующие несохранённые изменения:" +msgstr "Профиль «%1%» несовместим с новым профилем принтера, и имеет следующие несохранённые изменения:" #, boost-format msgid "Preset \"%1%\" is not compatible with the new process profile and it contains the following unsaved changes:" -msgstr "Профиль \"%1%\" несовместим с новым профилем настроек и имеет следующие несохранённые изменения:" +msgstr "Профиль «%1%» несовместим с новым профилем настроек и имеет следующие несохранённые изменения:" #, boost-format msgid "You have changed some settings of preset \"%1%\"." -msgstr "Изменены параметры профиля \"%1%\"." +msgstr "Изменены параметры профиля «%1%»." msgid "" "\n" @@ -10161,6 +10713,12 @@ msgstr "Перенести значения из левого профиля" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "При включении активируется режим выбора значений из левого профиля для переноса в правый." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Добавить файл" @@ -10425,12 +10983,8 @@ msgstr "Информация о сопле успешно синхронизир msgid "Successfully synchronized nozzle and AMS number information." msgstr "Информация о сопле и количестве AMS успешно синхронизирована." -msgid "Continue to sync filaments" -msgstr "Продолжить синхронизацию филаментов" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Отмена" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Цвет материала успешно синхронизирован с принтером." @@ -10503,10 +11057,10 @@ msgid "Please choose the filament colour" msgstr "Изменение цвета" msgid "Native Wayland liveview requires the GStreamer GTK video sink. Please install the gtksink plugin for GStreamer, then restart OrcaSlicer." -msgstr "" +msgstr "Для нативного отображения трансляции в Wayland требуется gtksink (плагин для GStreamer). Установите необходимый пакет плагинов и перезапустите OrcaSlicer." msgid "Failed to initialize the native Wayland GStreamer video sink. Please check your GStreamer GTK plugin installation." -msgstr "" +msgstr "Не удалось запустить нативную трансляцию GSteramer через Wayland. Проверьте наличие установленного пакета плагинов GStreamer." msgid "Windows Media Player is required for this task! Do you want to enable 'Windows Media Player' for your operation system?" msgstr "Для этой задачи требуется Windows Media Player! Хотите включить его в своей ОС?" @@ -10536,6 +11090,9 @@ msgid "Login" msgstr "Войти" msgid "Login failed. Please try again." +msgstr "Ошибка входа. Попробуйте ещё раз." + +msgid "parse json failed" msgstr "" msgid "[Action Required] " @@ -10581,7 +11138,7 @@ msgid "Rotate View" msgstr "Вращение камеры" msgid "Middle mouse button" -msgstr "" +msgstr "Средняя кнопка мыши" msgid "Zoom View" msgstr "Масштабирование вида" @@ -10709,13 +11266,14 @@ msgstr "Приблизить" msgid "Zoom out" msgstr "Отдалить" +# Ошибка в оригинале – переключить печать частей невозможно, функция работает только для всей сборки msgid "Toggle printable for object/part" -msgstr "" +msgstr "Переключить печать модели" msgid "Switch between Prepare/Preview" msgstr "Переключение между подготовкой и просмотром нарезки" -# ??? Plater – это название библиотеки. +# Plater – это название библиотеки. Используется в меню горячих клавиш в качестве заголовка сочетаний клавиш, которые работают внутри пространства Plater. Как минимум на Windows не отображается. msgid "Plater" msgstr "" @@ -10796,21 +11354,22 @@ msgstr "Доступен новый сетевой плагин (%s). Хотит msgid "New version of Orca Slicer" msgstr "Доступна новая версия Orca Slicer" +# Функционально идентична строке-синониму msgid "Check on Microsoft Store" -msgstr "" +msgstr "Открыть в Microsoft Store" msgid "Check on GitHub" -msgstr "Открыть на GitHub" +msgstr "Открыть GitHub" msgid "Open Microsoft Store" -msgstr "" +msgstr "Открыть в Microsoft Store" msgid "Skip this Version" msgstr "Пропустить эту версию" #, c-format, boost-format msgid "New version available: %s. Please update OrcaSlicer from the Microsoft Store." -msgstr "" +msgstr "Доступна новая версия: %s. Рекомендуется обновить OrcaSlicer из магазина приложений." msgid "Confirm and Update Nozzle" msgstr "Подтвердить и обновить сопло" @@ -10845,6 +11404,9 @@ msgstr "Имя принтера" msgid "Where to find your printer's IP and Access Code?" msgstr "Где найти IP-адрес и код доступа к вашему принтеру?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Подключить" @@ -10910,6 +11472,9 @@ msgstr "Модуль обрезки" msgid "Auto Fire Extinguishing System" msgstr "Автоматическая система пожаротушения" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10928,6 +11493,9 @@ msgstr "Сбой обновления" msgid "Update successful" msgstr "Обновление успешно завершено" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Вы действительно хотите обновить прошивку? Это займёт около 10 минут. Не выключайте питание во время обновления принтера." @@ -10942,7 +11510,7 @@ msgstr "Плата расширения" #, boost-format msgid "Split into %1% parts" -msgstr "" +msgstr "Разделение на части (%1%)" msgid "Repair finished" msgstr "Восстановление завершено" @@ -10984,10 +11552,10 @@ msgid "Parts of the object at these heights may be too thin or the object may ha msgstr "Возможно, части модели на этой высоте слишком тонкие, или она имеет дефектную сетку" msgid "Process change extrusion role G-code" -msgstr "" +msgstr "G-код при смене типа линии с этими настройками печати" msgid "Filament change extrusion role G-code" -msgstr "" +msgstr "G-код при смене типа линии с этим материалом" msgid "No object can be printed. It may be too small." msgstr "Печать моделей невозможна. Возможно, они слишком маленькие." @@ -11010,15 +11578,17 @@ msgid "Generating G-code: layer %1%" msgstr "Генерация G-кода: слой %1%" msgid "Flush volumes matrix do not match to the correct size!" -msgstr "Матрица объёмов промывки не соответствует правильному размеру!" +msgstr "Матрица объёмов прочистки не соответствует правильному размеру!" msgid "set_accel_and_jerk() is only supported by Klipper" -msgstr "" +msgstr "set_accel_and_jerk() поддерживается только в Klipper" msgid "" "Input shaping is not supported by Marlin < 2.1.2.\n" "Check your firmware version and update your G-code flavor to ´Marlin 2´." msgstr "" +"Input Shaping поддерживается только в Marlin 2.1.2 и новее.\n" +"Обновите прошивку и установите тип G-кода на «Marlin 2»." msgid "Input shaping is only supported by Klipper, RepRapFirmware and Marlin 2." msgstr "" @@ -11030,6 +11600,9 @@ msgstr "Ошибка группировки: " msgid " can not be placed in the " msgstr " нельзя заправить в " +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Внутренний мост" @@ -11149,7 +11722,7 @@ msgid " is too close to exclusion area, there may be collisions when printing." msgstr " находится слишком близко к области исключения, что может привести к столкновению при печати." msgid " is too close to clumping detection area, there may be collisions when printing." -msgstr " находится слишком близко к зоне обнаружения комкования, возможны столкновения при печати." +msgstr " находится слишком близко к зоне обнаружения налипаний, возможны столкновения при печати." msgid "Prime Tower" msgstr "Черновая башня" @@ -11161,7 +11734,7 @@ msgid " is too close to an exclusion area, and collisions will be caused.\n" msgstr " находится слишком близко к области исключения, что приведёт к столкновению.\n" msgid " is too close to clumping detection area, and collisions will be caused.\n" -msgstr " находится слишком близко к зоне обнаружения комкования, столкновения неизбежны.\n" +msgstr " находится слишком близко к зоне обнаружения налипаний, столкновения неизбежны.\n" msgid "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." msgstr "" @@ -11179,16 +11752,16 @@ msgid "Smooth mode of timelapse is not supported when \"by object\" sequence is msgstr "Плавный режим таймлапса не поддерживается, когда включена последовательность печати моделей по очереди." msgid "Clumping detection is not supported when \"by object\" sequence is enabled." -msgstr "Обнаружение комкования не поддерживается при включённом режиме «по объектам»." +msgstr "Обнаружение налипаний не поддерживается при печати моделей по очереди." msgid "Enabling both precise Z height and the prime tower may cause slicing errors." msgstr "Одновременное включение точной высоты Z и башни очистки может вызвать ошибки нарезки." msgid "A prime tower is required for clumping detection; otherwise, there may be flaws on the model." -msgstr "Для обнаружения комкования требуется башня очистки; в противном случае на модели могут быть дефекты." +msgstr "Для обнаружения налипаний требуется башня очистки; в противном случае на модели могут быть дефекты." msgid "Please select \"By object\" print sequence to print multiple objects in spiral vase mode." -msgstr "Выберите последовательность печати «По очереди», для поддержки печати несколько моделей в режиме вазы." +msgstr "Выберите последовательность печати «По очереди» для поддержки печати несколько моделей в режиме вазы." msgid "Spiral (vase) mode does not work when an object contains more than one material." msgstr "Режим вазы не работает, когда модель печатается несколькими материалами." @@ -11292,7 +11865,7 @@ msgid "Layer height cannot exceed nozzle diameter." msgstr "Высота слоя не может быть больше диаметра сопла." msgid "Bridge line width must not exceed nozzle diameter" -msgstr "" +msgstr "Ширина линии моста не может превышать диаметр сопла" msgid "\"G92 E0\" was found in before_layer_change_gcode, but the G or E are not uppercase. Please change them to the exact uppercase \"G92 E0\"." msgstr "" @@ -11431,7 +12004,7 @@ msgid "The number of layers on which the elephant foot compensation will be acti msgstr "Количество слоёв, на которые будет распространяться компенсация слоновьей ноги. Первый слой будет уменьшен на величину компенсации слоновьей ноги с последующим линейным уменьшением до слоя, указанного здесь." msgid "Elephant foot layers density" -msgstr "" +msgstr "Плотность слоёв компенсации" msgid "" "Density of internal solid infill for Elephant foot layers compensation.\n" @@ -11471,10 +12044,10 @@ msgid "Allow controlling BambuLab's printer through 3rd party print hosts." msgstr "Позволяет управлять принтером BambuLab через сторонние хосты печати." msgid "Use 3MF instead of G-code" -msgstr "" +msgstr "Сжимать G-код перед отправкой" msgid "Enable this if the printer accepts a 3MF file as the print job. When enabled, Orca Slicer sends the sliced file as a .gcode.3mf, instead of a plain .gcode file." -msgstr "" +msgstr "Рекомендуется для принтеров, поддерживающих печать из архивов 3MF. Файлы печати будут отправляться с расширением \".gcode.3mf\"." msgid "Printer Agent" msgstr "Сетевой агент" @@ -11501,10 +12074,10 @@ msgid "Orca Slicer can upload G-code files to a printer host. This field should msgstr "Orca Slicer может загружать файл G-кода на хост принтера. Это поле должно содержать API-ключ или пароль, необходимые для проверки подлинности." msgid "Serial Number" -msgstr "" +msgstr "Серийный номер" msgid "Flashforge local API requires the printer serial number." -msgstr "" +msgstr "Локальный API Flashforge требует указания серийного номера." msgid "Name of the printer." msgstr "Название принтера." @@ -11554,7 +12127,7 @@ msgid "Maximum detour distance for avoiding crossing wall: The printer won't det msgstr "Максимальное расстояние обхода сопла от модели во избежание пересечения периметров при движении. Если расстояние обхода превышает это значение, то для данного маршрута эта опция не применяется. Можно указать значение в миллиметрах или процент от прямого пути перемещения (например, 50%). 0 – отключено." msgid "mm or %" -msgstr "мм или %" +msgstr "мм или %" msgid "Other layers" msgstr "Основная" @@ -11719,11 +12292,14 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" +"Ручное управление углом внешних мостов. 0 – автоматическое выравнивание каждого отдельного моста.\n" +"\n" +"Примечание: используйте 180° для направления в 0° без включения авторежима." msgid "Internal bridge infill direction" msgstr "Угол внутренних мостов" @@ -11733,17 +12309,20 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" +"Ручное управление углом внутренних мостов. 0 – автоматическое выравнивание каждого отдельного моста.\n" +"\n" +"Примечание: используйте 180° для направления в 0° без включения авторежима." msgid "Relative bridge angle" -msgstr "" +msgstr "Относительный угол" msgid "When enabled, the bridge angle values are added to the automatically calculated bridge direction instead of overriding it." -msgstr "" +msgstr "Прибавлять указанные выше значения к автоматически рассчитанному углу вместо его перезаписи." msgid "External bridge density" msgstr "Плотность внешних мостов" @@ -11760,6 +12339,20 @@ msgid "" " - Pros: Can create a string-like first layer. Faster and with better cooling because there is more space for air to circulate around the extruded bridge.\n" " - Cons: May lead to sagging and poorer surface finish." msgstr "" +"Плотность расположения линий внешних мостов.\n" +"\n" +"Повышение плотности:\n" +"• создаёт опору на предыдущие линии при печати каждой новой;\n" +"• требует точного подбора потока, хорошего охлаждения и низкой скорости печати;\n" +"• может вызвать переэкструзию, усадочную деформацию слоя и ухудшить отделяемость поддержек.\n" +"\n" +"Понижение плотности:\n" +"• улучшает эффективность охлаждения за счёт увеличения отступа;\n" +"• предотвращает усадочную деформацию слоя моста;\n" +"• позволяет усадке натягивать каждую из линий моста в струну;\n" +"• создаёт видимые зазоры между линиями.\n" +"\n" +"Примечание: при печати со сниженной плотностью рекомендуется немного занизить поток мостов." msgid "Internal bridge density" msgstr "Плотность внутренних мостов" @@ -11778,6 +12371,19 @@ msgid "" "\n" "This option works particularly well when combined with the second internal bridge over infill option to improve bridging further before solid infill is extruded." msgstr "" +"Плотность расположения линий внутренних мостов.\n" +"\n" +"Повышение плотности:\n" +"• позволяет быстро набрать прочность перед печатью внешних слоёв;\n" +"• требует точного подбора потока, хорошего охлаждения и/или низкой скорости печати;\n" +"• может вызвать усадочную деформацию слоя моста при охлаждении.\n" +"\n" +"Понижение плотности:\n" +"• улучшает эффективность охлаждения за счёт увеличения отступа;\n" +"• предотвращает усадочную деформацию слоя моста;\n" +"• позволяет усадке натягивать каждую из линий моста в струну.\n" +"\n" +"Примечание: рекомендуется использовать в паре с «Двухслойными мостами»." msgid "Bridge flow ratio" msgstr "Поток внешних мостов" @@ -11789,7 +12395,13 @@ msgid "" "\n" "The actual bridge flow used is calculated by multiplying this value with the filament flow ratio, and if set, the object's flow ratio." msgstr "" +"Управляет толщиной линии и слоя внешних (видимых) мостов.\n" +"Повышенные значения позволяют добиться качественной поверхности в паре с повышением плотности линий, а пониженные – минимального провисания и отклонения от заданных размеров.\n" +"\n" +"Внимание: при значениях меньше 1 плотность линий автоматически повышается для обеспечения печатаемости.\n" +"Примечание: фактический поток для моста рассчитывается путём умножения этого значения на поток материала и общий поток модели (если он задан)." +# Максимальное значение можно не указывать, т.к. теперь в каждой подсказке есть абзац с допустимым диапазоном значений. msgid "" "Line width of the Bridge. If expressed as a %, it will be computed over the nozzle diameter.\n" "Recommended to use with a higher Bridge density or Bridge flow ratio.\n" @@ -11797,6 +12409,10 @@ msgid "" "The maximum value is 100% or the nozzle diameter.\n" "If set to 0, the line width will match the Internal solid infill width." msgstr "" +"Ширина линий мостов. Можно указать процент от диаметра сопла.\n" +"Рекомендуется использовать в паре с увеличенными плотностью или потоком мостов.\n" +"\n" +"0 – использовать ширину линий сплошного заполнения." msgid "Internal bridge flow ratio" msgstr "Поток внутренних мостов" @@ -11808,6 +12424,11 @@ msgid "" "\n" "The actual bridge flow used is calculated by multiplying this value with the filament flow ratio, and if set, the object's flow ratio." msgstr "" +"Управляет толщиной линии и слоя внутренних (скрытых в модели) мостов. Внутренние мосты служат опорой для сплошного заполнения при переходе от разреженного.\n" +"Повышенные значения позволяют добиться быстрого набора плотности основы для внешней поверхности, а пониженные – минимального провисания и температурной деформации.\n" +"\n" +"Внимание: при значениях меньше 1 плотность линий автоматически повышается для обеспечения печатаемости.\n" +"Примечание: фактический поток для моста рассчитывается путём умножения этого значения на поток материала и общий поток модели (если он задан)." msgid "Top surface flow ratio" msgstr "Поток верхней поверхности" @@ -11959,8 +12580,9 @@ msgstr "Только один периметр на верхней поверх msgid "Use only one wall on flat top surfaces, to give more space to the top infill pattern." msgstr "Печатать только один периметр на верхней поверхности, чтобы оставить больше пространства для верхнего шаблона заполнения." +# Некорректное название в оригинальной строке – ломается связь с настройкой Арахны "Minimal wall length". Там настройка также (не) влияет только на верхние поверхности, и точно так же разблокирует эту настройку при установке повышенного значения. Но в последнем случае об одном периметре речи не идёт, т.к. там по определению заполняются щели между периметрами. msgid "One wall threshold" -msgstr "Порог одного периметра" +msgstr "Порог верхней поверхности" #, no-c-format, no-boost-format msgid "" @@ -12123,7 +12745,7 @@ msgstr "" "Внимание: смещение каймы фактически ослабляет её сцепление с моделью, что в паре с вертикальными стенками модели делает кайму бессмысленной." msgid "Brim flow ratio" -msgstr "" +msgstr "Поток каймы" msgid "" "This factor affects the amount of material for brims.\n" @@ -12132,6 +12754,9 @@ msgid "" "\n" "Note: The resulting value will not be affected by the first-layer flow ratio." msgstr "" +"Влияет на общее количество материала для печати каймы.\n" +"\n" +"Фактический поток для каймы рассчитывается путём умножения этого значения на коэффициенты потока материала и общего потока модели (если он задан)." msgid "Brim follows compensated outline" msgstr "Учитывать сдвиг контура" @@ -12148,10 +12773,11 @@ msgstr "" "Если текущие настройки уже работают хорошо, включение может привести к спеканию каймы со следующим слоем." msgid "Combine brims" -msgstr "" +msgstr "Общая кайма" +# Brim adhesion – трактуется по-разному. Адгезия – спекаемость двух отдельных структур, когезия – спекаемость внутри одной структуры. По идее, ввиду отсутствия упоминания стола, подразумевается проблема с адгезией двух независимых контуров друг к другу, которая полностью уходит при включении этой настройки. Если бы упоминался стол – тогда бы подразумевалась адгезия к столу. msgid "Combine multiple brims into one when they are close to each other. This can improve brim adhesion." -msgstr "" +msgstr "Объединять контуры каймы близлежащих объектов в один общий. Позволяет улучшить её спекаемость." msgid "Brim ears" msgstr "Ушки каймы" @@ -12181,9 +12807,6 @@ msgstr "" "Геометрия модели будет упрощена перед обнаружением острых углов. Этот параметр задаёт минимальную длину отклонения для её упрощения.\n" "Установите 0 для отключения." -msgid "Select printers" -msgstr "Профили принтеров" - msgid "upward compatible machine" msgstr "условия для совместимых принтеров" @@ -12196,9 +12819,6 @@ msgstr "" "\n" "Например, для совместимости материала только с соплами крупнее 0.4 мм используйте 'nozzle_diameter[0]>0.4'." -msgid "Select profiles" -msgstr "Профили настроек" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "" "Логическое выражение, с помощью которого можно настраивать условия совместимости этого профиля материала с профилями настроек печати. Если условие выполняется, материал считается совместимым с текущими настройками.\n" @@ -12239,18 +12859,20 @@ msgid "This is the default acceleration for both normal printing and travel afte msgstr "Ускорение по умолчанию для обычной печати и перемещений (кроме первого слоя)." msgid "Acceleration of travel moves." -msgstr "Ускорение холостого перемещения." +msgstr "Ускорение холостых перемещений." msgid "First layer travel" -msgstr "" +msgstr "Перемещения на первом слое" msgid "" "Travel acceleration of first layer.\n" "The percentage value is relative to Travel Acceleration." msgstr "" +"Ускорение холостых перемещений на первом слое.\n" +"Можно указать процент от ускорения холостых перемещений." msgid "mm/s² or %" -msgstr "мм/с² или %" +msgstr "мм/с² или %" msgid "Acceleration of bridges. If the value is expressed as a percentage (e.g. 50%), it will be calculated based on the outer wall acceleration." msgstr "Ускорение на мостах. Можно указать процент от ускорения внешних периметров." @@ -12291,10 +12913,13 @@ msgid "Speed of exhaust fan after printing completes." msgstr "Скорость вытяжного вентилятора после завершения печати." msgid "No cooling for the first" -msgstr "Не включать вентилятор на первых" +msgstr "Не обдувать первые слои" msgid "Turn off all cooling fans for the first few layers. This can be used to improve build plate adhesion." -msgstr "Количество слоёв, начиная с первого, на которых всем вентиляторам запрещено включаться, чтобы не ухудшить адгезию к столу." +msgstr "" +"Количество слоёв, начиная с первого, на которых всем вентиляторам запрещено включаться, чтобы не ухудшить адгезию к столу.\n" +"\n" +"Внимание: ненулевые значения блокируют и скрывают настройку принудительного охлаждения первых слоёв." msgid "Don't support bridges" msgstr "Не печатать поддержки под мостами" @@ -12303,22 +12928,28 @@ msgid "This disables supporting bridges, which decreases the amount of support r msgstr "Отключить создание поддержек под мостами. Относительно небольшие мосты обычно можно печатать без них." msgid "Thick external bridges" -msgstr "Толстые внешние мосты" +msgstr "Круглые внешние мосты" msgid "" "If enabled, bridge extrusion uses a line height equal to the nozzle diameter.\n" "This increases bridge strength and reliability, allowing longer spans, but may worsen appearance.\n" "If disabled, bridges may look better but are generally reliable only for shorter spans." msgstr "" +"Использовать современную модель формирования мостов на основе круглого сечения линии, равного диаметру сопла. Это повышает корректность расчётов требуемого материала и позволяет добиться более качественной поверхности после тонкой настройки плотности линий и потока мостов.\n" +"\n" +"Если отключено, используется старый подход к расчётам, который не отличает мосты от обычных сплюснутых линий с опорой под ними." msgid "Thick internal bridges" -msgstr "Толстые внутренние мосты" +msgstr "Круглые внутренние мосты" msgid "" "If enabled, internal bridge extrusion uses a line height equal to the nozzle diameter.\n" "This increases internal bridge strength and reliability when printed over sparse infill, but may worsen appearance.\n" "If disabled, internal bridges may look better but can be less reliable over sparse infill." msgstr "" +"Использовать современную модель формирования мостов на основе круглого сечения линии, равного диаметру сопла. Это повышает корректность расчётов требуемого материала и позволяет добиться более качественной поверхности после тонкой настройки плотности линий и потока мостов.\n" +"\n" +"Если отключено, используется старый подход к расчётам, который не отличает мосты от обычных сплюснутых линий с опорой под ними." msgid "Extra bridge layers (beta)" msgstr "Двухслойные мосты (beta)" @@ -12340,7 +12971,7 @@ msgid "" msgstr "" "Создание второго слоя моста над внешниеми/внутренними мостами.\n" "\n" -"Дополнительный слой улучшает внешний вид и надёжность мостов, создавая прочную опору для последующего сплошного заполнения. Это особенно полезно для быстрой печати, когда скорости печати мостов и сплошного заполнения значительно отличаются. Дополнительный слой у у внешнего моста повышает прочность стыковки с периметрами, а у внутреннего – снижает риск проявления и заметность \"тени\" шаблона заполнения на верхних поверхностях.\n" +"Дополнительный слой улучшает внешний вид и надёжность мостов, создавая прочную опору для последующего сплошного заполнения. Это особенно полезно для быстрой печати, когда скорости печати мостов и сплошного заполнения значительно отличаются. Дополнительный слой у внешнего моста повышает прочность стыковки с периметрами, а у внутреннего – снижает риск проявления и заметность \"тени\" шаблона заполнения на верхних поверхностях.\n" "\n" "Рекомендуется добавлять второй слой как минимум для внешних мостов, если это не создаёт особых проблем.\n" "\n" @@ -12359,10 +12990,11 @@ msgstr "Внутренние мосты" msgid "Apply to all" msgstr "Везде" +# "small" здесь лишняя, размер мостов в алгоритме фильтрации не учитывается. Разработчики, видимо, имели ввиду размер областей, требующих опоры. msgid "Filter out small internal bridges" -msgstr "Убрать небольшие внутренние мосты (beta)" +msgstr "Чувствительность внутренних мостов" -# ???? +# Переусложнённая настройка, исходящая из реализации алгоритма фильтрации внутренних нависающих зон. Можно кратно упростить без потери смысла, приняв "фильтрацию" как "чувствительность". Ждём перехода на новую систему локализации, чтобы убрать это инородное "(фильтровать)". msgid "" "This option can help reduce pillowing on top surfaces in heavily slanted or curved models.\n" "By default, small internal bridges are filtered out and the internal solid infill is printed directly over the sparse infill. This works well in most cases, speeding up printing without too much compromise on top surface quality.\n" @@ -12372,23 +13004,20 @@ msgid "" "2. Limited filtering - creates internal bridges on heavily slanted surfaces while avoiding unnecessary bridges. This works well for most difficult models\n" "3. No filtering - creates internal bridges on every potential internal overhang. This option is useful for heavily slanted top surface models; however, in most cases, it creates too many unnecessary bridges." msgstr "" -"Эта опция может помочь уменьшить образование эффекта «дырявой подушки» на верхних сильно наклонных поверхностях или изогнутых моделях\n" +"Чувствительность поддержки мостами внутренних нависаний:\n" +"• Низкая – создавать только для мест без опоры.\n" +"• Средняя – поддерживать крутые наклонные выступы.\n" +"• Высокая – поддерживать любые внутренние нависания.\n" "\n" -"По умолчанию, маленькие внутренние мосты отфильтровываются, а внутреннее сплошное заполнение печатается непосредственно поверх разреженного заполнения. В большинстве случаев это хорошо работает, ускоряя печать без особого ущерба для качества верхней поверхности. Однако, на сильно наклонных поверхностях или изогнутых моделях, особенно при низкой плотности заполнения, это может привести к скручиванию неподдерживаемого сплошного заполнения и образованию эффекта «дырявой подушки»\n" +"Снижение чувствительности позволяет экономить время при печати большинства моделей без особых потерь в качестве, однако некоторые модели с комплексной геометрией или низкой плотностью заполнения могут потребовать более частого размещения внутренних опор.\n" "\n" -"Отключение позволит печатать слой внутреннего моста над слабо поддерживаемым внутренним сплошным заполнением. Приведённые ниже параметры управляют степенью фильтрации, т.е. количеством создаваемых внутренних мостов.n\n" -"\n" -"Фильтрация включена по умолчанию и хорошо работает в большинстве случаев\n" -"\n" -"Ограниченная фильтрация - создаёт внутренние мосты на сильно наклонных поверхностях, при этом избегая создания ненужных внутренних мостов. Это хорошо работает с большинством сложных моделей.n\n" -"\n" -"Без фильтрации - мосты создаются над каждым потенциально внутреннем нависании. Этот вариант полезен для моделей с сильно наклонной верхней поверхностью. Однако в большинстве случаев этот вариант создаёт слишком много ненужных мостов." +"Примечание: в большинстве случаев высокая чувтствительность создаёт слишком много ненужных мостов." msgid "Limited filtering" -msgstr "Ограниченная фильтрация" +msgstr "Средняя" msgid "No filtering" -msgstr "Без фильтрации" +msgstr "Высокая" msgid "Max bridge length" msgstr "Максимальный интервал опор" @@ -12482,14 +13111,50 @@ msgstr "Спираль Архимеда" msgid "Octagram Spiral" msgstr "Спиральная октаграмма" -# ??? Плотность верхней оболочки +# Плотность верхней оболочки msgid "Top surface density" msgstr "Плотность верхней поверхности" -# ??? Плотность верхней поверхности. При 100% создаётся сплошной верхний слой. +# Плотность верхней поверхности. При 100% создаётся сплошной верхний слой. msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Плотность верхней поверхности. Если установить 100%, поверхность будет сплошной и гладкой. Уменьшение этого параметра создаст текстурированную поверхность в соответствии с выбранным шаблоном заполнения верхней поверхности. При значении 0% останутся только стенки верхнего слоя. Эта функция предназначена для улучшения внешнего вида или функциональности объекта, но не для решения проблем, таких как чрезмерная экструзия." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Шаблон заполнения нижней поверхности" @@ -12559,20 +13224,22 @@ msgstr "Ограничение скорости движения головы ( msgid "Small perimeters threshold" msgstr "Порог коротких периметров" +# Информация о формуле с Вики msgid "This sets the threshold for small perimeter length. Default threshold is 0mm." msgstr "Пороговое значение (радиус) для расчёта длины коротких периметров (по формуле длины окружности). Значение по умолчанию – 0 мм." msgid "Small support perimeters" -msgstr "" +msgstr "Короткие периметры поддержек" +# msgid "Same as \"Small perimeters\", but for supports. This separate setting will affect the speed of support for areas <= `small_support_perimeter_threshold`. If expressed as a percentage (for example: 80%), it will be calculated on the support or support interface speed setting above. Set to zero for auto." -msgstr "" +msgstr "Аналогично скорости «Коротких периметров», но для небольших отростков поддержек. Значительно повышает стабильность печати маленьких ветвей древовидных поддержек. Можно указать абсолютную скорость или процент от текущей скорости печати поддержки (например, 80%). 0 – рассчитывать автоматически." msgid "Small support perimeters threshold" -msgstr "" +msgstr "Порог коротких периметров поддержек" msgid "This sets the threshold for small support perimeter length. The default threshold is 0mm." -msgstr "" +msgstr "Пороговое значение (радиус) для расчёта длины коротких периметров поддержек (по формуле длины окружности). Значение по умолчанию – 0 мм." msgid "Walls printing order" msgstr "Порядок печати периметров" @@ -12625,6 +13292,10 @@ msgid "" "\n" "This option will be disabled if spiral vase mode is enabled." msgstr "" +"Напрвление, в котором печатаются контуры периметров на виде сверху.\n" +"Внутренние полости и отверстия печатаются в противоположном направлении, чтобы обеспечить равномерность при слиянии внутренней поверхности с наружней.\n" +"\n" +"При включении режима вазы эта настройках будет игнорироваться." msgid "Counter clockwise" msgstr "Против часовой стрелки" @@ -12784,7 +13455,7 @@ msgstr "" "3. Проверьте порядок введённых значений (PA, расход, ускорения) и сохраните профиль материала." msgid "Enable adaptive pressure advance within features (beta)" -msgstr "" +msgstr "Адаптироваться к изменениям линии" msgid "" "Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n" @@ -12795,7 +13466,7 @@ msgid "" msgstr "" msgid "Static pressure advance for bridges" -msgstr "" +msgstr "Фиксированный PA на мостах" msgid "" "Static pressure advance value for bridges. Set to 0 to apply the same pressure advance as \n" @@ -12803,6 +13474,10 @@ msgid "" "\n" "A lower PA value when printing bridges helps reduce the appearance of slight under-extrusion immediately after bridges. This is caused by the pressure drop in the nozzle when printing in the air and a lower PA helps counteract this." msgstr "" +"Фиксированный коэффициент Pressure Advance для мостов.\n" +"Более низкое значение PA при печати мостов помогает уменьшить появление небольшой недоэкструзии сразу после мостов. Это вызвано падением давления в сопле при печати в воздухе, и снижение значения PA помогает предотвратить это.\n" +"\n" +"0 – использовать адаптивный PA с настройками периметров." msgid "Default line width if other line widths are set to 0. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Стандартная ширина линии для отключённых (установленных на 0) значений ниже. Можно указать процент от диаметра сопла." @@ -12870,12 +13545,18 @@ msgstr "Авто для промывки" msgid "Auto For Match" msgstr "Авто для сопоставления" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "Температура прочистки" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Температура при прочистке. 0 – использовать верхний предел рекомендуемой температуры." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Расход при прочистке" @@ -13153,6 +13834,12 @@ msgstr "Пригодный для печати" msgid "The filament is printable in extruder." msgstr "Материалом можно печатать через экструдер." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Температура размягчения" @@ -13190,20 +13877,24 @@ msgid "Angle for solid infill pattern, which controls the start or main directio msgstr "Угол ориентации шаблона сплошного заполнения, который определяет начало или основное направление линий." msgid "Top layer direction" -msgstr "" +msgstr "Угол шаблона верхней поверхности" msgid "" "Fixed angle for the top solid infill and ironing lines.\n" "Set to -1 to follow the default solid infill direction." msgstr "" +"Фиксированный угол для заполнения и разглаживания верхней поверхности.\n" +"Установите -1 для отключения настройки." msgid "Bottom layer direction" -msgstr "" +msgstr "Угол шаблона нижней поверхности" msgid "" "Fixed angle for the bottom solid infill lines.\n" "Set to -1 to follow the default solid infill direction." msgstr "" +"Фиксированный угол для заполнения нижней поверхности.\n" +"Установите -1 для отключения настройки." msgid "Sparse infill density" msgstr "Плотность заполнения" @@ -13212,12 +13903,12 @@ msgstr "Плотность заполнения" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Плотность внутреннего заполнения, выраженная в процентах. 100% означает сплошное заполнение." -msgid "Align infill direction to model" -msgstr "Вращать заполнение с моделью" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13235,11 +13926,15 @@ msgstr "" "Внимание: плотность заполнения будет скорректирована для сохранения того же расхода материала." msgid "Z-buckling bias optimization (experimental)" -msgstr "" +msgstr "Оптимизация CRAMP (beta)" +# Расширил описание настройки на основе информации от автора алгоритма. На мой взгляд, оригинальное описание висит в воздухе и не обеспечивает понимания причинно-следственных связей, а просто даёт несколько утверждений в вакууме. Источники – обзорный лист: repository.library.brown.edu/studio/item/bdr:wudt8hse и PR: github.com/ELEGOO-3D/ElegooSlicer/pull/68 #, no-c-format, no-boost-format msgid "Tightens the gyroid wave along the Z (vertical) axis at low infill density to shorten the effective vertical column length and improve Z-axis compression buckling resistance. Filament use is preserved. No effect at ~30% sparse infill density and above. Only applies when Sparse infill pattern is set to Gyroid." msgstr "" +"Адаптирует длину вертикальной волны гироида к условиям печати при низкой плотности заполнения (меньше ≈30%) без дополнительного расхода материала. Согласно исследованиям проекта CRAMP на базе Брауновского университета, это повышает компрессионную устойчивость деталей на величину до 60% за счёт адаптации структуры гироида к особенностям FDM-печати. Включение этой оптимизации позволяет добиться рекордного соотношения прочности к массе среди всех шаблонов заполнения.\n" +"\n" +"Внимание: настройка экспериментальна и может привести к небольшому снижению прочности в горизонтальных направленииях вследствие снижения анизотропии гироида." msgid "Sparse infill pattern" msgstr "Шаблон заполнения" @@ -13449,21 +14144,29 @@ msgstr "Температура экструдера на первом слое" msgid "Nozzle temperature for printing the first layer with this filament" msgstr "Температура экструдера для печати первого слоя этим материалом." +# Адаптировал к настройке принудительного обдува на первых слоях msgid "Full fan speed at layer" -msgstr "Полная скорость вентилятора на слое" +msgstr "Восстанавливать обдув на" +# Ну Andy и намудрил тут, конечно... настройка же простая, описывается максимально лаконично :) +# +# Адаптировал к настройке принудительного обдува на первых слоях (заменил "повышать" на "равномерно менять"). msgid "Fan speed will be ramped up linearly from zero at layer \"close_fan_the_first_x_layers\" to maximum at layer \"full_fan_speed_layer\". \"full_fan_speed_layer\" will be ignored if lower than \"close_fan_the_first_x_layers\", in which case the fan will be running at maximum allowed speed at layer \"close_fan_the_first_x_layers\" + 1." msgstr "" -"Интенсивность охлаждения будет линейно увеличиваться от нуля со слоя заданным параметром «Не включать вентилятор на первых» до заданной максимальной скорости вращения вентилятора на слое заданным параметром «Полная скорость вентилятора на слое». Значение «Полная скорость вентилятора на слое» будет игнорироваться, если оно меньше значения «Не включать вентилятор на первых», в этом случае вентилятор будет работать на максимально допустимой скорости на слое заданном в «Не включать вентилятор на первых» + 1.\n" +"Интенсивность охлаждения будет равномерно меняться для перехода к требуемым условиям обдува детали.\n" "\n" -"Допустим, вы указали «Не включать вентилятор на первых» 2-ух слоях, а «Полная скорость вентилятора на слое» должна сработать на 5-ом слое. Тогда на первых 2-ух слоях вентилятор будет полностью выключен. На 5-ом слое он начнёт работать так, как указано в настройках максимальной скорости вращения вентилятора. Промежуточные же значения скорости вращения вентилятора на 3-ем и 4-ом слоях будут линейно изменяться." +"Если активна настройка «Не обдувать первые N слоёв» – с учётом этих слоёв.\n" +"\n" +"Примечание: если слоёв с заблокированным обдувом больше, чем указано здесь, то восстановление происходит моментально на первом доступном слое." +# Используется всего в одном месте, согласовываем msgid "layer" -msgstr "слой" +msgstr "слое" msgid "First layer fan speed" -msgstr "" +msgstr "Обдув первого слоя" +# Последнее предложение первого абзаца противоречит применимости настройки – её диапазон не ограничен "небольшим охлаждением". Поэтому упоминать о таком ограничении некорректно. Only available when \"No cooling for the first\" is 0 – перенёс в подсказку этой настройки, т.к., мягко говоря, глупо упоминать это здесь, а не там. msgid "" "Sets an exact fan speed for the first layer, overriding all other cooling settings. Useful for protecting 3D-printed toolhead parts (e.g. Voron-style ABS/ASA ducts) from a hot bed. A small amount of airflow cools the ducts down, without using full cooling that may in certain conditions hurt first-layer adhesion.\n" "From the second layer onwards, normal cooling resumes.\n" @@ -13471,6 +14174,11 @@ msgid "" "Only available when \"No cooling for the first\" is 0.\n" "Set to -1 to disable it." msgstr "" +"Фиксированный процент скорости вентилятора на первом слое. Может пригодиться самосборным принтерам для защиты печатных деталей со слабой термостойкостью от тепловой деформации из-за близости к разогретому столу (например, сопла системы охлаждения Voron). Небольшой обдув способен предотвратить их деформацию без значительного вреда для адгезии первого слоя.\n" +"\n" +"Если настроено «Восстанавливать обдув на N слое», интенсивность охлаждения будет равномерно меняться для перехода к требуемым условиям обдува детали.\n" +"\n" +"Установите -1 для отключения настройки." msgid "Support interface fan speed" msgstr "Обдув связующего слоя" @@ -13485,7 +14193,7 @@ msgstr "" "\n" "Чтобы отключить, установите значение -1.\n" "Установите значение -1, чтобы запретить переопределять этот параметр.\n" -"Если включена опция «Не включать вентилятор на первых» слоях, то она перекрывает эту настройку." +"Если включена опция «Не обдувать первые слои», то она перекрывает эту настройку." msgid "Internal bridges fan speed" msgstr "Обдув внутренних мостов" @@ -13581,6 +14289,7 @@ msgstr "Использовать нечёткую оболочку для изм msgid "Fuzzy skin generator mode" msgstr "Метод создания оболочки" +# Чтобы снять визуальную нагрузку, упоминание ошибки перенесено в конкретные параметры, которые их вызывают (где ему и место). #, c-format, boost-format msgid "" "Fuzzy skin generation mode. Works only with Arachne!\n" @@ -13590,11 +14299,13 @@ msgid "" "\n" "Attention! The [Extrusion] and [Combined] modes works only the fuzzy_skin_thickness parameter not more than the thickness of printed loop. At the same time, the width of the extrusion for a particular layer should also not be below a certain level. It is usually equal 15-25%% of a layer height. Therefore, the maximum fuzzy skin thickness with a perimeter width of 0.4 mm and a layer height of 0.2 mm will be 0.4-(0.2*0.25)=±0.35mm! If you enter a higher parameter than this, the error Flow::spacing() will displayed, and the model will not be sliced. You can choose this number until this error is repeated." msgstr "" -"Выбор способа создания нечёткой оболочки. Работает только с генератором периметров Arachne!\n" +"Выбор способа создания нечёткой оболочки.\n" "\n" -"• Смещение: классический подход, при котором фактура формируется за счёт частых колебаний относительно исходной траектории.\n" +"• Смещение: классический подход, при котором фактура формируется за счёт колебаний траектории.\n" "• Экструзия: фактура создаётся за счёт колебаний подачи пластика. Печать происходит быстро и без лишней тряски. Отлично подходит для создания просвечивающих стенок (режим «Все периметры»).\n" -"• Совместный: сочетает два предыдущих метода. Внешне напоминает первый, но не создаёт пустот между периметрами." +"• Совместный: сочетает два предыдущих метода. Внешне напоминает первый, но не создаёт пустот между периметрами.\n" +"\n" +"Внимание: только первый способ совместим с классическим генератором." msgid "Displacement" msgstr "Смещение" @@ -13607,7 +14318,7 @@ msgid "Combined" msgstr "Совместный" msgid "Fuzzy skin noise type" -msgstr "Алгоритм генерации" +msgstr "Алгоритм" msgid "" "Noise type to use for fuzzy skin generation:\n" @@ -13618,44 +14329,56 @@ msgid "" "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." msgstr "" +"Тип шума, используемый для генерации нечёткой оболочки.\n" +"\n" +"• Случайный: равномерно резкий шум.\n" +"• Шум Перлина: согласованный однородный шум.\n" +"• Волновой: более резкий вариант шума Перлина.\n" +"• Ребристый: резкий сглаженный шум с мраморной текстурой.\n" +"• Диаграмма Вороного: плоская диаграмма в виде природных форм.\n" +"• Синусоида: равномерное смещение с имитацией плетения.\n" +"\n" +"Примечание: для разных алгоритмов оптимальны разные масштабы." +# Поменял на "случайный" из-за нехватки места. msgid "Classic" -msgstr "Классический" +msgstr "Случайный" msgid "Perlin" msgstr "Шум Перлина" -# ??? Шум волн msgid "Billow" -msgstr "Волнообразный" +msgstr "Волновой" msgid "Ridged Multifractal" -msgstr "Гребенчатый" +msgstr "Ребристый" +# Felix: В Орке используется не шум, а обычная плоская диаграмма. Попытаюсь согласовать с названием настройки: "Алгоритм Вороного" (да и с другими алгоритмами согласуется лучше) msgid "Voronoi" -msgstr "Шум Вороного" +msgstr "Вороного" +# Судя по комментариям разработчика в коде, это адаптированный алгоритм синусоидальной волны. msgid "Ripple" -msgstr "Ripple" +msgstr "Синусоида" # Размер шероховатости msgid "Fuzzy skin feature size" -msgstr "Размер элемента нечёткой оболочки" +msgstr "Масштаб генерации" # 0.5 мм - Мелкая рябь # 2 мм - Крупные волны msgid "The base size of the coherent noise features, in mm. Higher values will result in larger features." msgstr "Параметр определяет базовый размер элемента когерентного шума в миллиметрах. Более высокое значение увеличивает размер этого элемента." -# уровень детализации шума Перлина +# Felix: программистами пользователей не считаем, поэтому заменил октавы на простую аналогию со слоями. Точное упоминание уже в описании. msgid "Fuzzy Skin Noise Octaves" -msgstr "Количество октав нечёткой оболочки" +msgstr "Количество слоёв шума" -# Чем больше октав, тем сложнее и «естественнее» выглядит шероховатость. -# Октавы - это количество кривых Перлина, которые отвечают за неоднородность -# шума. +# Andy: Чем больше октав, тем сложнее и «естественнее» выглядит шероховатость. Октавы - это количество кривых Перлина, которые отвечают за неоднородность шума. +# +# Felix: Не совсем за "неоднородность", скорее за проявление мелких деталей поверх предыдущей октавы. Грубо говоря, в процедурной генерации 1 октава – горы и основной ландшафт, 2 октава – бугры и расщелины, 3 октава – отдельные камни и микрорельеф, 4 октава – неровная фактура камней. Короче, уберу про неоднородность. msgid "The number of octaves of coherent noise to use. Higher values increase the detail of the noise, but also increase computation time." -msgstr "Количество октав когерентного шума, которые отвечают за его неоднородность. Более высокие значения повышают детализацию шума, но увеличивают время вычисления." +msgstr "Количество октав когерентного шума. Чем больше октав, тем выше время вычислений и детализация шума от смешивания его слоёв." # Интенсивность затухания шума нечёткой оболочки msgid "Fuzzy skin noise persistence" @@ -13667,13 +14390,13 @@ msgid "The decay rate for higher octaves of the coherent noise. Lower values wil msgstr "Скорость затухания для более высоких октав когерентного шума. Более низкие значения приведут к сглаживанию шума." msgid "Number of ripples per layer" -msgstr "" +msgstr "Количество волн на слое" msgid "Controls how many full cycles of ripples will be added per layer." -msgstr "" +msgstr "Поддерживать заданное количество максимумов в каждом контуре." msgid "Ripple offset" -msgstr "" +msgstr "Смещение волн" msgid "" "Shifts the ripple phase forward along the print path by the specified percentage of a wavelength each layer period.\n" @@ -13683,9 +14406,15 @@ msgid "" "\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." msgstr "" +"Смещать фазу волны с каждым новым слоем на заданный процент её длины.\n" +"• 0% – не использовать смещение.\n" +"• 50% – смещать в противофазу.\n" +"• 100% – по сути, возврат к 0%.\n" +"\n" +"Примечание: слои можно сгруппировать настройкой ниже." msgid "Layers between ripple offset" -msgstr "" +msgstr "Группировка слоёв" msgid "" "Specifies how many consecutive layers share the same ripple phase before the offset is applied.\n" @@ -13693,6 +14422,8 @@ msgid "" "- 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." msgstr "" +"Задаёт количество слоёв с общей фиксированной фазой.\n" +"Позволяет смещать синусоиду раз в несколько слоёв." msgid "Filter out tiny gaps" msgstr "Минимальная длина щели" @@ -13766,7 +14497,7 @@ msgid "Nozzle HRC" msgstr "Твёрдость сопла (HRC)" msgid "The nozzle's hardness. Zero means no checking for nozzle hardness during slicing." -msgstr "Твёрдость сопел. 0 - отключение контроля сопел на твёрдость при нарезке." +msgstr "Твёрдость сопел. 0 – отключить проверку твёрдости при нарезке." msgid "HRC" msgstr "HRC" @@ -13800,6 +14531,15 @@ msgstr "" "Если в принтере имеется вспомогательный вентилятор для охлаждения моделей (обычно это боковой вентилятор), можете включить эту опцию.\n" "Команда G-кода: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13818,7 +14558,7 @@ msgid "Will only take into account the delay for the cooling of overhangs." msgstr "Применять смещение времени только для охлаждения нависаний." msgid "Fan kick-start time" -msgstr "Продолжительность принудительного запуска вентилятора" +msgstr "Продолжительность принудительного запуска" msgid "" "Emit a max fan speed command for this amount of seconds before reducing to target speed to kick-start the cooling fan.\n" @@ -13829,13 +14569,19 @@ msgstr "" "Установите 0 для отключения." msgid "Minimum non-zero part cooling fan speed" -msgstr "" +msgstr "Скорость страгивания" +# "ideally" здесь, мягко скажем, неуместно. В идеале в прошивке должна быть настроена автоматическая нормализация, чтобы обороты шли уже при M106 S1. msgid "" "Some part-cooling fans cannot start spinning when commanded below a certain PWM duty cycle. When set above 0, any non-zero part-cooling fan command will be raised to at least this percentage so the fan reliably starts. A fan command of 0 (fan off) is always honoured exactly. This clamp is applied after every other fan calculation (first-layer ramp, layer-time interpolation, overhang/bridge/support-interface/ironing overrides), so scaling still operates within the range [this value, 100%].\n" "If your firmware already disables the fan below a threshold (for example Klipper's [fan] off_below: 0.10 shuts the fan off whenever the commanded duty cycle is below 10%), this option and the firmware threshold should ideally be set to the same value. Matching them (e.g. off_below: 0.10 in Klipper and 10% here) guarantees the slicer never emits a non-zero value that the firmware would silently drop, and the fan never receives a value below the one you know it can actually spool at.\n" "Set to 0 to deactivate." msgstr "" +"Минимальный процент скорости, при котором ротор вентилятора фактически способен начать вращаться. Если указать ненулевое значение, любые команды охлаждения с меньшими значениями будут повышаться до него, чтобы обеспечить обдув в расчётный момент.\n" +"\n" +"0 – не менять команды.\n" +"\n" +"Примечание: ограничение запуска в некоторых прошивках (например, [fan] off_below в Klipper) может автоматически занулять слишком низкие значения. В таком случае рекомендуется указать минимальный процент, который не сбрасывается прошивкой." msgid "%" msgstr "%" @@ -13869,6 +14615,12 @@ msgstr "" "Если в принтере имеется вытяжной вентилятор и вам требуется дополнительное охлаждение внутренней области принтера, включите эту опцию.\n" "Команда G-кода: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "Тип G-кода" @@ -14019,16 +14771,16 @@ msgid "Enable clumping detection" msgstr "Обнаружение налипания пластика на сопло" msgid "Clumping detection layers" -msgstr "Слои обнаружения комкования" +msgstr "Слои обнаружения" msgid "Clumping detection layers." -msgstr "Слои обнаружения комкования." +msgstr "Слои обнаружения налипшего материала на сопло." msgid "Probing exclude area of clumping" -msgstr "Исключаемая область зондирования комкования" +msgstr "Исключаемая область обнаружения" msgid "Probing exclude area of clumping." -msgstr "Исключаемая область зондирования комкования." +msgstr "Исключаемая область обнаружения налипшего на сопло материала." msgid "Lateral lattice angle 1" msgstr "Наклон боковой сетки 1" @@ -14102,6 +14854,8 @@ msgid "" "Filament to print internal sparse infill.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати разреженного заполнения.\n" +"«По умолчанию» – текущий материал модели/части." msgid "Line width of internal sparse infill. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Ширина линий заполнения. Можно указать процент от диаметра сопла." @@ -14244,40 +14998,55 @@ msgstr "Фиксированный угол" msgid "Use a fixed absolute angle for ironing." msgstr "Расчитывать угол относительно стола." +# На момент 2.4.2 не используется и скрыто в интерфейсе (см. "ironing_expansion") в Tab.cpp. Судя по всему, задумывалось как доп. фича для сглаживания слоёв (ZAA). msgid "Ironing expansion" -msgstr "" +msgstr "Расширение разглаживания" msgid "Expand or contract the ironing area." -msgstr "" +msgstr "Расширение (или сужение) границ разглаживания." msgid "Z contouring enabled" -msgstr "" +msgstr "Сглаживание слоёв" msgid "Enable Z-layer contouring (aka Z-layer anti-aliasing)." msgstr "" +"Динамическое управление высотой отдельных линий для сглаживания переходов между слоями.\n" +"\n" +"Примечание: поток линий не корректируется, линии просто смещаются по высоте." +# Прижимать к предыдущему слою периметры msgid "Minimize wall height angle" -msgstr "" +msgstr "Угол прижима периметров" msgid "" "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." msgstr "" +"Прижимать периметры к предыдущему слою на поверхностях с наклоном менее заданного значения.\n" +"Внимание: в настоящий момент действие настройки инвертировано (затрагивается всё, кроме верхних периметров с указанным углом), что делает её вредоносной." msgid "Don't alternate fill direction" -msgstr "" +msgstr "Отключить поворот шаблона заполнения" msgid "Disable alternating fill direction when using Z contouring." -msgstr "" +msgstr "Сохранять одинаковый угол шаблона сплошного заполнения при использовании сглаживания." +# Знаю, что звучит как реверсивный машинный перевод фразы "Допустимая высота сдвига", но тут по смыслу именно смещение диапазона допустимых высот (см. комментарий к переводу описания) msgid "Minimum Z height" -msgstr "" +msgstr "Сдвиг допустимой высоты" +# Z-layer – довольно технично, максимально упрощённо изложил суть. В алгоритме используется нестандартный подход через расчёт промежуточного диапазона отклонения слоя от его плоскости для каждой линии в пределах [-(layer_height - min_z), min_z]. Т.е., при слое 0.2 мм и стандартном сдвиге в 0.05 мм мы получим допустимый диапазон [-0.15, 0.05]. Если нормализовать к уровню предыдущего слоя (прибавить layer_height), то получатся фактические высоты линий в диапазоне [0.05, 0.25]. Если взять сдвиг 0.1 мм, то получаются высоты [0.1, 0.3]. Соответственно, если взять сдвиг 0.2, то получится [0.2, 0.4] – линии не будут опускаться ниже высоты слоя, но смогут получать удвоенную высоту. msgid "" "Minimum Z-layer height.\n" "Also controls the slicing plane." msgstr "" +"Положительное смещение нижней и верхней границ допустимого положения линии относительно плоскости слоя (h).\n" +"\n" +"Иными словами, если сдвиг равен ...\n" +"• 0: линии могут только опускаться (вплоть до предыдущего слоя).\n" +"• h/2: линии балансируют между ½ текущего и ½ следующего слоя.\n" +"• h: линии не могут опускаться, но могут иметь удвоенную высоту." msgid "This G-code is inserted at every layer change after the Z lift." msgstr "Команды в G-коде, которые выполняются каждый раз после смены слоя, то есть после поднятия оси Z." @@ -14322,7 +15091,7 @@ msgstr "Модель компенсации потока" msgid "Flow Compensation Model, used to adjust the flow for small infill areas. The model is expressed as a comma separated pair of values for extrusion length and flow correction factor. Each pair is on a separate line, followed by a semicolon, in the following format: \"1.234, 5.678;\"" msgstr "" -"Модель компенсации избытка потока в небольших областях заполнения.\n" +"Модель (график) компенсации избытка потока в небольших областях заполнения.\n" "Формат: пара значений (длина экструзии и применяемый поток), разделённых запятыми. Каждая пара указывается с новой строки и завершается точкой с запятой, например: «1.234, 5.678;»." msgid "Maximum speed X" @@ -14419,6 +15188,30 @@ msgstr "Минимальная скорость холостых перемещ msgid "Minimum travel speed (M205 T)" msgstr "Минимальная скорость перемещения без печати (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Максимальное ускорение при печати" @@ -14462,12 +15255,14 @@ msgid "Maximum speed of resonance avoidance." msgstr "Верхний порог скорости возникновения ряби." msgid "Emit input shaping" -msgstr "" +msgstr "Гашение эха" msgid "" "Override firmware input shaping settings.\n" "If disabled, firmware settings are used." msgstr "" +"Заменить настройки шейпера (алгоритма гашения), указанные в прошивке.\n" +"Если отключено, используются стандартные настройки прошивки." msgid "Input shaper type" msgstr "Тип шейпера" @@ -14477,6 +15272,8 @@ msgid "" "Default uses the firmware default settings.\n" "Disable turns off input shaping in the firmware." msgstr "" +"Выберите алгоритм гашения колебаний.\n" +"«По умолчанию» – не менять шейпер из прошивки.«Отключить» – не использовать гашение колебаний." msgid "MZV" msgstr "MZV" @@ -14520,6 +15317,11 @@ msgid "" "To disable input shaping, use the Disable type.\n" "RRF: X and Y values are equal." msgstr "" +"Частота резонанса для шейпера оси X.\n" +"0 – не менять частоту из прошивки.\n" +"Для отключения шейпера используйте настройку его типа.\n" +"\n" +"Примечание: прошивка RepRap не поддерживает раздельную настройку осей." msgid "Y" msgstr "Y" @@ -14529,19 +15331,32 @@ msgid "" "Zero will use the firmware frequency.\n" "To disable input shaping, use the Disable type." msgstr "" +"Частота резонанса для шейпера оси Y.\n" +"0 – не менять частоту из прошивки.\n" +"Для отключения шейпера используйте настройку его типа." +# коэфициент затухания msgid "" "Damping ratio for the X axis input shaper.\n" "Zero will use the firmware damping ratio.\n" "To disable input shaping, use the Disable type.\n" "RRF: X and Y values are equal." msgstr "" +"Коэффициент затухания для шейпера оси X.\n" +"0 – не менять коэффициент из прошивки.\n" +"Для отключения шейпера используйте настройку его типа.\n" +"\n" +"Примечание: прошивка RepRap не поддерживает раздельную настройку осей." +# коэфициент затухания msgid "" "Damping ratio for the Y axis input shaper.\n" "Zero will use the firmware damping ratio.\n" "To disable input shaping, use the Disable type." msgstr "" +"Коэффициент затухания для шейпера оси Y.\n" +"0 – не менять коэффициент из прошивки.\n" +"Для отключения шейпера используйте настройку его типа." msgid "The part cooling fan speed may be increased when auto cooling is enabled. This is the maximum speed for the part cooling fan." msgstr "Скорость вентилятора охлаждения моделей может быть увеличена, если включено автоматическое охлаждение. Это максимальное ограничение скорости вентилятора для охлаждения моделей." @@ -14669,17 +15484,17 @@ msgid "Volume of nozzle between the filament cutter and the end of the nozzle" msgstr "Объём остатка материала между ножом и кончиком сопла." msgid "Cooling tube position" -msgstr "Позиция охлаждающей трубки" +msgstr "Позиция холодной зоны" # ??? кончика сопла msgid "Distance of the center-point of the cooling tube from the extruder tip." -msgstr "Расстояние от центра охлаждающей трубки до сопла." +msgstr "Расстояние от кончика сопла до центра холодной зоны в канале подачи." msgid "Cooling tube length" -msgstr "Длина охлаждающей трубки" +msgstr "Длина холодной зоны" msgid "Length of the cooling tube to limit space for cooling moves inside it." -msgstr "Длина трубки охлаждения для ограничения перемещения при охлаждающих движениях." +msgstr "Длина холодной зоны в канале подачи для ограничения перемещения при охлаждающих движениях." msgid "High extruder current on filament swap" msgstr "Повышение тока при смене прутка" @@ -14733,29 +15548,29 @@ msgid "Users can decide project file names when exporting." msgstr "Имя файла проекта можно задать при экспорте." msgid "Make overhangs printable" -msgstr "Делать нависания пригодными для печати" +msgstr "Деформировать модель для печати без поддержек" msgid "Modify the geometry to print overhangs without support material." -msgstr "Изменение геометрии модели для печати нависающих частей без поддержки." +msgstr "Измененять геометрию модели для печати нависающих частей без поддержек." msgid "Make overhangs printable - Maximum angle" -msgstr "Делать нависания пригодными для печати под максимальным углом" +msgstr "Допустимый наклон" msgid "Maximum angle of overhangs to allow after making more steep overhangs printable.90° will not change the model at all and allow any overhang, while 0 will replace all overhangs with conical material." -msgstr "Максимальный угол нависания, получаемый после изменения геометрии крутых нависаний. При 90°не происходит изменения формы модели. При 0° же, все нависания заменяются материалом конической геометрии." +msgstr "Максимально допустимый угол наклона. Более крутые нависания будут подгоняться под указанный угол. Наклон в 90°, по сути, отключает деформацию. Наклон в 0° проецирует контур модели на стол." msgid "Make overhangs printable - Hole area" -msgstr "Делать нависания отверстий пригодными для печати" +msgstr "Площадь допустимых отверстий" msgid "Maximum area of a hole in the base of the model before it's filled by conical material. A value of 0 will fill all the holes in the model base." -msgstr "Максимальная площадь отверстия в основании модели до его заполнения материалом конической геометрии. При 0 все отверстия в основании модели будут заполнены." +msgstr "Глухие отверстия в основании модели расцениваются как нависания. Эта настройка позволяет сохранить неизменными отверстия и пустоты с площадью основания меньше указанного значения." msgid "Detect overhang walls" msgstr "Обнаруживать нависающие периметры" -#, c-format, boost-format +#, fuzzy, c-format, boost-format msgid "This detects the overhang percentage relative to line width and uses a different speed to print. For 100%% overhang, bridging speed is used." -msgstr "Определяет процент нависания относительно ширины линии и использует разную скорость печати. Для 100%%-го нависания используется скорость печати мостов." +msgstr "Определяет процент нависания относительно ширины линии и использует разную скорость печати. Для 100%-го нависания используется скорость печати мостов." # В секции "Материал для линий" msgid "Outer walls" @@ -14765,6 +15580,8 @@ msgid "" "Filament to print outer walls.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати внешних периметров.\n" +"«По умолчанию» – текущий материал модели/части." # В секции "Материал для линий" msgid "Inner walls" @@ -14774,6 +15591,8 @@ msgid "" "Filament to print inner walls.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати внутренних периметров.\n" +"«По умолчанию» – текущий материал модели/части." msgid "Line width of inner wall. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Ширина линий внутренних периметров. Можно указать процент от диаметра сопла." @@ -14804,10 +15623,10 @@ msgid "If you want to process the output G-code through custom scripts, just lis msgstr "Если вы хотите обработать выходной G-код с помощью пользовательских скриптов, просто перечислите здесь абсолютные пути к ним. Разделяйте скрипты точкой с запятой. Скриптам будет передан абсолютный путь к файлу G-кода в качестве первого аргумента, и они смогут получить доступ к настройкам конфигурации Orca Slicer, читая переменные окружения." msgid "Change extrusion role G-code (process)" -msgstr "" +msgstr "G-код при смене типа линии (настройки печати)" msgid "This G-code is inserted when the extrusion role is changed. It runs after the machine and filament extrusion role G-code." -msgstr "" +msgstr "Команды в G-коде, которые выполняются между печатью разных элементов структуры (например, при переходе от периметра к заполнению). Выполняются после команд смены типа линии из настроек принтера и материала." msgid "Printer type" msgstr "Тип принтера" @@ -15001,6 +15820,10 @@ msgstr "Прямой (Direct)" msgid "Bowden" msgstr "Внешний (Bowden)" +msgid "Hybrid" +msgstr "" + +# Разобраться позже: wiki.bambulab.com/en/software/bambu-studio/filament-track-switch-dynamic-mapping msgid "Enable filament dynamic map" msgstr "" @@ -15008,10 +15831,10 @@ msgid "Enable dynamic filament mapping during print." msgstr "" msgid "Has filament switcher" -msgstr "" +msgstr "Автосмена материала" msgid "Printer has a filament switcher hardware (e.g., AMS)." -msgstr "" +msgstr "Принтер поддерживает автоматическую смену материала (например, оборудован внешней системой смены материала)." msgid "Extra length on restart" msgstr "Доп. подача после отката" @@ -15034,6 +15857,12 @@ msgstr "Скорость возврата" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Скорость возврата материала в экструдер после отката. При значении 0 используется скорость отката." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Откат на уровне прошивки" @@ -15086,6 +15915,9 @@ msgstr "В углах" msgid "Aligned back" msgstr "В углах сзади" +msgid "Back" +msgstr "Сзади" + msgid "Random" msgstr "Случайная" @@ -15338,16 +16170,22 @@ msgid "" "Filament to print internal solid infill.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати сплошного заполнения.\n" +"«По умолчанию» – текущий материал модели/части." msgid "" "Filament to print top surface.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати верхней поверхности.\n" +"«По умолчанию» – текущий материал модели/части." msgid "" "Filament to print bottom surface.\n" "\"Default\" uses the active object/part filament." msgstr "" +"Материал для печати нижней поверхности.\n" +"«По умолчанию» – текущий материал модели/части." msgid "Line width of internal solid infill. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Ширина линий внутреннего сплошного заполнения. Можно указать процент от диаметра сопла." @@ -15401,6 +16239,12 @@ msgstr "На протяжении всей печати встроенная к msgid "Traditional" msgstr "По умолчанию" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Разница температур" @@ -15470,10 +16314,13 @@ msgid "Enable filament ramming" msgstr "Включить рэмминг прутка" msgid "Tool change on wipe tower" -msgstr "" +msgstr "Менять материал над башней" msgid "Force the toolhead to travel to the wipe tower before issuing the tool change command (Tx). Only relevant for multi-extruder (multi-toolhead) printers using a Type 2 wipe tower. By default Orca skips the travel on multi-toolhead machines because the firmware handles the head swap, which can result in the Tx command being issued above the printed part. Enable this option if you want the tool change to always be issued above the wipe tower instead." msgstr "" +"Перемещать печатающую голову в позицию над башней перед вызовом команды смены инструмента (T). Предполагается, что прошивка принтера выполняет смену материала с учётом позиции детали и учитывает возможные подтёки, но если это не так – данная настройка позволит принудительно перемещать сопло к черновой башне заранее.\n" +"\n" +"Внимание: применимо только к многоэкструдерным принтерам с черновой башней 2 типа." msgid "No sparse layers (beta)" msgstr "Без разреженных слоёв (beta)" @@ -15487,6 +16334,18 @@ msgstr "Подготовка всех печатающих экструдеро msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Если этот параметр включён, все печатающие экструдеры в начале печати будут подготавливаться на переднем крае стола." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Радиус закрытия зазоров полигональной сетки" @@ -15600,7 +16459,9 @@ msgstr "Поддержка/подложка" msgid "" "Filament to print support base and raft.\n" "\"Default\" means no specific filament for support and current filament is used." -msgstr "Материал для печати основной части поддержки и подложки. «По умолчанию» – использовать материал модели." +msgstr "" +"Материал для печати основной части поддержки и подложки.\n" +"«По умолчанию» – использовать материал модели." msgid "Avoid interface filament for base" msgstr "Избегать исп. материала связующего слоя для поддержки" @@ -15624,7 +16485,9 @@ msgstr "Связующий слой поддержки/подложки" msgid "" "Filament to print support interface.\n" "\"Default\" means no specific filament for support interface and current filament is used." -msgstr "Материал для печати связующего слоя поддержки. «По умолчанию» – использовать материал модели." +msgstr "" +"Материал для печати связующего слоя поддержки.\n" +"«По умолчанию» – использовать материал модели." msgid "Top interface layers" msgstr "Связующие слои сверху" @@ -15918,15 +16781,20 @@ msgstr "" "Это особенно полезно, если принтер не поддерживает команды M141/M191, или если управление температурой термокамеры реализовано через макросы (например, при отсутствии активного нагревателя камеры)." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" "Unlike the \"Target\" chamber temperature, this option does not emit any M141/M191 commands; it only exposes the value to your custom G-code. It should not exceed the \"Target\" chamber temperature." msgstr "" +"Температура термокамеры, с которой можно начать печать, не дожидаясь достижения целевой температуры. Не должна превышать целевую температуру.\n" +"\n" +"Доступ к значению можно получить через переменную с именем chamber_minimal_temperature. Её можно использовать в макросах начала печати или прогрева термокамеры, например:\n" +"PRINT_START <...> CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" +"В отличие от целевой температуры не приводит к автоматической генерации команд M141/M191 и нужна только для использования в секции G-кода." msgid "Chamber minimal temperature" -msgstr "" +msgstr "Минимальная температура термокамеры" msgid "Nozzle temperature after the first layer" msgstr "Температура при печати последующих слоёв." @@ -15947,10 +16815,10 @@ msgid "This G-code is inserted when the extrusion role is changed." msgstr "Команды в G-коде, которые выполняются между печатью разных элементов структуры (например, при переходе от периметра к заполнению)." msgid "Change extrusion role G-code (filament)" -msgstr "" +msgstr "G-код при смене типа линии (настройки материала)" msgid "This G-code is inserted when the extrusion role is changed for the active filament." -msgstr "" +msgstr "Команды в G-коде, которые выполняются между печатью разных элементов структуры этим материалом (например, при переходе от периметра к заполнению)." msgid "Line width for top surfaces. If expressed as a %, it will be computed over the nozzle diameter." msgstr "Ширина линий заполнения верхней поверхности. Можно указать процент от диаметра сопла." @@ -15970,6 +16838,45 @@ msgstr "Толщина оболочки сверху" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Минимальная толщина оболочки сверху в мм. Если толщина оболочки, рассчитанная по количеству сплошных слоёв сверху, меньше этого значения, количество сплошных слоёв сверху будет автоматически увеличено при нарезке, для удовлетворения минимальной толщины оболочки. Это позволяет избежать слишком тонкой оболочки при небольшой высоте слоя. 0 означает, что этот параметр отключён, а толщина оболочки сверху задаётся количеством сплошных слоёв сверху." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "Ограничение скорости холостых перемещений печатающей головы." @@ -16031,12 +16938,30 @@ msgstr "Множитель прочистки" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Реальные объёмы прочистки равны произведению множителя и значений, указанных в таблице." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Объём сброса материала на черновой башне" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Объём материала, который необходимо выдавить для подготовки экструдера на черновой башне." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "Размер черновой башни по оси X. Размер по оси Y будет автоматически вычислен исходя из необходимого объёма очистки и ширины башни. Таким образом, увеличивая ширину башни вы уменьшаете её длину и наоборот." @@ -16240,12 +17165,12 @@ msgid "Rotate the polyhole every layer." msgstr "Вращение многогранного отверстия на каждом слое." msgid "Maximum Polyhole edge count" -msgstr "" +msgstr "Число граней" msgid "" "Maximum number of polyhole edges\n" "This setting limits the amount of edges a polyhole can have" -msgstr "" +msgstr "Число граней многогранника при включённых многогранных отверстиях." msgid "G-code thumbnails" msgstr "Эскизы в G-коде" @@ -16281,10 +17206,14 @@ msgid "Arachne" msgstr "Arachne" msgid "Wall transition length" -msgstr "Длина перехода между периметрами" +msgstr "Длина уплотнения" +# Задаёт длину перехода между периметрами при изменении их количества (с чётного на нечётное, и обратно). Чем больше значение, тем плавнее переход, и наоборот: чем меньше, тем резче. Указывается в процентах от диаметра сопла. msgid "When transitioning between different numbers of walls as the part becomes thinner, a certain amount of space is allotted to split or join the wall segments. It's expressed as a percentage over nozzle diameter." -msgstr "Задаёт длину перехода между периметрами при изменении их количества (с чётного на нечётное, и обратно). Чем больше значение, тем плавнее переход, и наоборот: чем меньше, тем резче. Указывается в процентах от диаметра сопла." +msgstr "" +"Длина сегмента, закрывающего пустоты между периметрами. Чем короче уплотнение, тем лучше устраняются пустоты. Указывается в процентах от диаметра сопла.\n" +"\n" +"Внимание: низкие значения требуют точной калибровки коррекции давления (PA) и повышают нагрузку на электронику, поскольку приводят к генерации бóльшего количества команд на малом отрезке пути." msgid "Wall transitioning filter margin" msgstr "Допустимое отклонение ширины" @@ -16292,54 +17221,59 @@ msgstr "Допустимое отклонение ширины" msgid "Prevent transitioning back and forth between one extra wall and one less. This margin extends the range of extrusion widths which follow to [Minimum wall width - margin, 2 * Minimum wall width + margin]. Increasing this margin reduces the number of transitions, which reduces the number of extrusion starts/stops and travel time. However, large extrusion width variation can lead to under- or overextrusion problems. It's expressed as a percentage over nozzle diameter." msgstr "Параметр расширяет допустимый диапазон значений ширины периметров, чтобы уменьшить частые изменения их количества на тонких стенках, что улучшает качество печати. Однако слишком большой диапазон может привести к недоэкструзии или переэкструзии. Указывается в процентах от диаметра сопла. Например, для сопла 0,4 мм оптимальным считается значение 25% (0,1 мм)." +# Ранее было некорректно переведено как "... между периметрами". Тут речь идёт о "петле" (loop, wall) – замкнутом контуре, и конкретном эдж-кейсе на острых углах такого контура. + речь не о "переходе" (transition) между периметрами, а о структуре, формируемой внутри конкретной "петли" (контура) периметра. P.S. Немного хитрю с пробелами, чтобы не переносить строку из-за одного лишнего символа. msgid "Wall transitioning threshold angle" -msgstr "Пороговый угол перехода между периметрами" +msgstr "Порог угла для уплотнения" +# Опять же, это не переход от линии к линии – это место уплотнение с внешней стороны острого угла периметров внутри модели для закрытия пустот между ними msgid "When to create transitions between even and odd numbers of walls. A wedge shape with an angle greater than this setting will not have transitions and no walls will be printed in the center to fill the remaining space. Reducing this setting reduces the number and length of these center walls, but may leave gaps or overextrude." -msgstr "Этот параметр задаёт минимальный угол между периметрами, при котором требуется создавать переход между чётным и нечётным их количеством. Если угол в клиновидной зоне, то есть в месте схождения периметров, превышает заданное значение, переходы не генерируются, и в центре клина не будут печататься дополнительные периметры для заполнения пустоты. Если же угол меньше заданного значения, слайсер добавит переход и дополнительный периметр в клиновидной зоне, чтобы заполнить оставшуюся пустоту." +msgstr "По мере сужения контура модели могут возникать места с острыми углами, где между периметрами с классическим генератором образуются пустоты. Генератор Arachne позволяет резко локально расширить линию контура, чтобы сформировать уплотнение, закрыть им пустоту и повысить прочность. Здесь задаётся максимальный угол таких мест, при котором создаётся уплотнение." msgid "Wall distribution count" msgstr "Количество изменяемых периметров" -# Т.е. если значение этого параметра задано как 1, а на участке модели 3 -# периметра, то только самый внутренний периметр будет печататься с переменной -# толщиной, а 2 оставшихся — с постоянной. msgid "The number of walls, counted from the center, over which the variation needs to be spread. Lower values mean that the outer walls don't change in width." -msgstr "Количество периметров, отсчитываемое от заполнения, на которые будут распространяться изменения, вносимые генератором периметров Arachne. Если значение параметра низкое (например, 1), то только первый периметр от заполнения будет печататься с переменной толщиной, а все остальные периметры (второй, третий и т.д.) — с фиксированной шириной, заданной в настройках слайсера (например, 0.45 мм для сопла 0.4 мм)." +msgstr "Количество периметров, на которые будет распространяться допустимое отклонение ширины (начиная с внутренних)." msgid "Minimum feature size" -msgstr "Минимальный размер элемента" +msgstr "Допустимая ширина элемента" msgid "Minimum thickness of thin features. Model features that are thinner than this value will not be printed, while features thicker than than this value will be widened to the minimum wall width. It's expressed as a percentage over nozzle diameter." msgstr "" -"Минимальная ширина тонких элементов. Элементы модели тоньше этого значения не будут печататься, а более широкие элементы – расширены до «минимальной ширины периметра». Указывается в процентах от диаметра сопла.\n" +"Минимальная ширина элементов модели для печати. Позволяет игнорировать слишком тонкие элементы, а подходящие по ширине печатать с «минимальной шириной периметра». Указывается в процентах от диаметра сопла.\n" "\n" -"Например, при значении 25% и сопле 0,4 мм будут печататься элементы больше следующей толщины:\n" +"Например, при значении 25% и сопле 0,4 мм будут игнорироваться элементы меньше следующей толщины:\n" "0,4 мм × 25% = 0,1 мм." +# Инвертирую значение настройки без потери смысла, чтобы обеспечить нормальную читаемость и кратно упростить восприятие смысла. msgid "Minimum wall length" -msgstr "Минимальная длина периметра" +msgstr "Допустимая длина щели" msgid "" "Adjust this value to prevent short, unclosed walls from being printed, which could increase print time. Higher values remove more and longer walls.\n" "\n" "NOTE: Bottom and top surfaces will not be affected by this value to prevent visual gaps on the outside of the model. Adjust 'One wall threshold' in the Advanced settings below to adjust the sensitivity of what is considered a top-surface. 'One wall threshold' is only visible if this setting is set above the default value of 0.5, or if single-wall top surfaces is enabled." msgstr "" -"Отрегулируйте это значение, чтобы предотвратить печать коротких незамкнутых периметров, что может увеличить время печати. Более высокие значения удаляют большие и более длинные периметры.\n" +"Максимальная длина щели в месте уплотнения, которую можно игнорировать. Помогает избежать печати большого количества ненужных коротких линий.\n" "\n" -"Примечание: нижние и верхние поверхности не будут затронуты этим значением, чтобы избежать визуальных пробелов на наружной стороне модели. Настройте параметр «Порог одного периметра» в расширенных настройках ниже, чтобы настроить чувствительность определения верхней поверхности. «Порог одного периметра» будет отображаться только в том случае, если этот параметр установлен выше значения по умолчанию, равным 0,5 или если включён параметр «Только один периметр на верхней поверхности»." +"Примечание: не влияет на периметры на первом слое и верхних поверхностях во избежание появления видимых щелей в них. Дополнительно можно настроить чувствительность определения поверхности как верхней в настройке «Порог верхней поверхности», если значение превышает стандартное значение в 0.5 мм." +# Минимальный сегмент периметра msgid "Maximum wall resolution" -msgstr "" +msgstr "Минимальная длина сегмента" msgid "This value determines the smallest wall line segment length in mm. The smaller you set this value, the more accurate and precise the walls will be." msgstr "" +"Минимальная длина каждого прямого сегмента линии периметра. Чем меньше, тем выше точность генерации периметров.\n" +"\n" +"Примечание: фактическая длина может быть ограничена настройкой предельного отклонения." msgid "Maximum wall deviation" -msgstr "" +msgstr "Предельное отклонение" +# Перенёс упоминание главенства этой настройки в настройку выше. msgid "The maximum deviation allowed when reducing the resolution for the 'Maximum wall resolution' setting. If you increase this, the print will be less accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits 'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' takes precedence." -msgstr "" +msgstr "Максимальное отклонение сегментов от модели. Чем меньше, тем выше точность и размер файла." msgid "First layer minimum wall width" msgstr "Минимальная ширина периметра первого слоя" @@ -16350,8 +17284,63 @@ msgstr "Минимальная ширина периметра, использу msgid "Minimum wall width" msgstr "Минимальная ширина периметра" +# Без понятия, зачем тут в оригинале упоминается условие расширения, ведь за это отвечает другая настройка. Возможно, разработчикам так уж хотелось описать случай, обратный действию этой настройки... Перенёс в примечание, чтобы не сбивало с толку. msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." -msgstr "Минимальная ширина периметра для печати тонких элементов модели (в соответствии с «минимальным размером элемента»). Ширина периметра будет подогнана под размер элемента, если значение этого параметра меньше его ширины. Можно указать процент от диаметра сопла." +msgstr "" +"Минимальная ширина периметра для печати тонких элементов модели (в соответствии с «Допустимой шириной элемента»). Можно указать процент от диаметра сопла.\n" +"\n" +"Примечание: периметр может расширяться до ширины элемента." + +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Чтобы материал не подтекал, материал после рэмминга немного отъезжает назад. Этот параметр задаёт время движения в обратном направлении." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Для предотвращения подтекания материала, температура сопла будет снижена во время рэмминга. Поэтому время рэмминга должно быть больше времени охлаждения. 0 значит отключено." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" msgid "Detect narrow internal solid infills" msgstr "Оптимизация заполнения узких мест" @@ -16366,7 +17355,7 @@ msgid "Invalid value when spiral vase mode is enabled: " msgstr "Недопустимое значение при включенном режиме спиральной вазы: " msgid "Bridge line width must not exceed nozzle diameter: " -msgstr "" +msgstr "Ширина линии моста не может превышать диаметр сопла: " msgid "too large line width " msgstr "слишком большая ширина линии " @@ -16626,7 +17615,7 @@ msgstr "" " 5 – Трассировка\n" msgid "Log file" -msgstr "" +msgstr "Файл журнала" msgid "Redirects debug logging to file.\n" msgstr "" @@ -16651,11 +17640,11 @@ msgid "Load filament IDs for each object." msgstr "Загрузить идентификаторы материалов для каждого объекта." msgid "Allow multiple colors on one plate" -msgstr "Разрешить многоцветную печать на одном столе" +msgstr "Игнорировать разницу в цвете" # ???? msgid "If enabled, Arrange will allow multiple colors on one plate." -msgstr "Если включено, то функция расстановки позволяет использовать несколько цветов на одном столе." +msgstr "Если включено, модели разных цветов не будут разделяться на разные столы." msgid "Allow rotation when arranging" msgstr "Разрешить вращение при расстановке" @@ -17142,12 +18131,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Калибровка не поддерживается" -msgid "Error desc" -msgstr "Описание ошибки" - -msgid "Extra info" -msgstr "Доп. информация" - msgid "Flow Dynamics" msgstr "Динамика потока" @@ -17354,6 +18337,12 @@ msgstr "Введите имя, которое хотите сохранить н msgid "The name cannot exceed 40 characters." msgstr "Максимальная длина имени 40 символов." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Пожалуйста, найдите лучшую линию на столе" @@ -17446,9 +18435,6 @@ msgstr "Информация об экструдере и AMS синхрониз msgid "Nozzle Flow" msgstr "Расход сопла" -msgid "Nozzle Info" -msgstr "Информация о сопле" - msgid "Filament position" msgstr "положение прутка" @@ -17478,7 +18464,7 @@ msgid "TPU is not supported for Flow Dynamics Auto-Calibration." msgstr "Автоматическая калибровка динамики потока для TPU не поддерживается." msgid "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." -msgstr "" +msgstr "Обнаружен недопустимый перепад температур. Каждый из используемых материалов должен иметь в профиле температуру печати в пределах допустимого диапазона других материалов. В противном случае сопло может забиться и повредить принтер." msgid "Sync AMS and nozzle information" msgstr "Синхронизировать информацию об экструдере и AMS" @@ -17522,6 +18508,10 @@ msgstr "История успешных результатов калибров msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Обновление записей прошлых калибровок динамики потока" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "Действие" @@ -17724,8 +18714,8 @@ msgid "" msgstr "" "Введите допустимое значение:\n" "Начальное > 10\n" -"Шаг >= 0\n" -"Конечное > Начальное + Шаг" +"Шаг ≥ 0\n" +"Конечное > начальное + шаг" msgid "Start retraction length: " msgstr "Начальная длина отката: " @@ -17734,7 +18724,7 @@ msgid "End retraction length: " msgstr "Конечная длина отката: " msgid "Input shaping Frequency test" -msgstr "Подбор частоты Input Shaping" +msgstr "Ручной подбор частоты шейпера" msgid "Test model" msgstr "Тестовая модель" @@ -17748,8 +18738,7 @@ msgstr "Быстрый тест (Fast Tower)" msgid "Please ensure the selected type is compatible with your firmware version." msgstr "Убедитесь, что выбранный шейпер совместим с версией прошивки." -# https://marlinfw.org/docs/features/ft_motion.html и -# https://youtu.be/6sN71fx9frk +# Подробности: https://marlinfw.org/docs/features/ft_motion.html и https://youtu.be/6sN71fx9frk msgid "" "Marlin version => 2.1.2\n" "Fixed-Time motion not yet implemented." @@ -17785,25 +18774,25 @@ msgid "RepRap firmware uses the same frequency range for both axes." msgstr "Прошивка RepRap использует общий диапазон частот для обеих осей." msgid "Damp: " -msgstr "Затухание (Damp): " +msgstr "Коэф. затухания: " msgid "" "Recommended: Set Damp to 0.\n" "This will use the printer's default or saved value." -msgstr "Совет: установите значение затухания (Damp) равным 0 для использования значения из прошивки принтера." +msgstr "Совет: установите коэффициент равным 0 для использования значения из прошивки принтера." msgid "" "Please input valid values:\n" "(0 < FreqStart < FreqEnd < 500)" msgstr "" "Введите допустимые значения:\n" -"(0 < Нач. частота < Конеч. частота < 500)" +"(0 < нач. частота < конеч. частота < 500)" msgid "Please input a valid damping factor (0 < Damping/zeta factor <= 1)" -msgstr "Введите допустимый коэффициент затухания (0 < Затухание/коэффициент затухания ≤ 1)" +msgstr "Введите допустимый коэффициент затухания (0 < коэффициент затухания ≤ 1)" msgid "Input shaping Damp test" -msgstr "Тест затухания Input shaping" +msgstr "Ручной подбор коэффициента затухания" msgid "Check firmware compatibility." msgstr "Проверьте совместимость с прошивкой." @@ -17811,8 +18800,9 @@ msgstr "Проверьте совместимость с прошивкой." msgid "Frequency: " msgstr "Частота: " +# Коэффициент затухания msgid "Damp" -msgstr "Затухание" +msgstr "Коэффициент" msgid "RepRap firmware uses the same frequency for both axes." msgstr "Прошивка RepRap использует общую частоту для обеих осей." @@ -17883,36 +18873,36 @@ msgid "NOTE: High values may cause Layer shift (>%s)" msgstr "Примечание: высокие значения могут привести к смещению слоёв (>%s)" msgid "Flow Ratio Calibration" -msgstr "" +msgstr "Калибровка коэффициента потока" msgid "Calibration Test Type" -msgstr "" +msgstr "Вариант калибровки" msgid "Pass 1 (Coarse)" -msgstr "" +msgstr "Проход 1 (примерный)" msgid "Pass 2 (Fine)" -msgstr "" +msgstr "Проход 2 (точный)" # YOLO – калибровка "с первого раза", "Одним махом", You Only Look Once # (https://github.com/OrcaSlicer/OrcaSlicer/pull/6479) msgid "YOLO (Recommended)" -msgstr "Экспресс-калибровка потока (YOLO, шаг 0.01, рекомендуется)" +msgstr "Экспресс-калибровка YOLO (шаг 0,01)" msgid "YOLO (Perfectionist)" -msgstr "" +msgstr "Экспресс-калибровка YOLO (шаг 0,005)" msgid "Top Surface Pattern" -msgstr "" +msgstr "Шаблон поверхности" msgid "Choose a slot for the selected color" -msgstr "" +msgstr "Укажите слот для выбранного цвета" msgid "Material in the material station" -msgstr "" +msgstr "Материал в хранилище" msgid "Only materials of the same type can be selected." -msgstr "" +msgstr "Можно выбрать материал только того же типа." msgid "Send G-code to printer host" msgstr "Отправить G-код на хост принтера" @@ -17937,41 +18927,41 @@ msgid "Upload" msgstr "Загрузить" msgid "Leveling before print" -msgstr "" +msgstr "Калибровка перед печатью" msgid "Time-lapse" msgstr "Таймлапсы" msgid "Enable IFS" -msgstr "" +msgstr "Включить IFS" #, c-format, boost-format msgid "Detected %d IFS slots on printer." -msgstr "" +msgstr "Обнаруженные в принтере слоты IFS: %d." msgid "This printer does not report a material station." -msgstr "" +msgstr "Принтер не сообщил о подключённом хранилище материалов." msgid "Unable to read IFS slots from printer." -msgstr "" +msgstr "Не удалось получить от принтера сведения о слотах IFS." msgid "Loading IFS slots from printer..." -msgstr "" +msgstr "Загрузка сведений об IFS..." msgid "Slice the plate first to get project material information." -msgstr "" +msgstr "Для получения информации о материалах необходимо нарезать стол." msgid "This plate uses multiple materials. Enable IFS and assign each tool to a printer slot." -msgstr "" +msgstr "На столе используется несколько материалов. Включите IFS и назначьте для них слоты." msgid "Each project material must be assigned to an IFS slot before printing." -msgstr "" +msgstr "Для печати каждый материал должен быть назначен на слот IFS." msgid "Each project material must be assigned to a loaded IFS slot before printing." -msgstr "" +msgstr "Для печати каждый материал в проекте должен быть назначен на слот IFS." msgid "Each project material must match the material loaded in the selected IFS slot." -msgstr "" +msgstr "Каждый материал в проекте должен соответствовать материалу, загруженному в назначенный слот IFS." msgid "Print host upload queue" msgstr "Очередь загрузки на хост печати" @@ -18026,13 +19016,14 @@ msgstr "Текстурный лист (сторона Б)" #, c-format, boost-format msgid "Printer: %s" -msgstr "" +msgstr "Принтер: %s" msgid "Calibrate before printing" -msgstr "" +msgstr "Выполнить калибровку" +# Сопоставление, назначение, назначенные материалы msgid "Filament Mapping:" -msgstr "" +msgstr "Назначение материалов:" msgid "Unable to perform boolean operation on selected parts" msgstr "Невозможно выполнить булеву операцию над выбранными элементами." @@ -18368,12 +19359,18 @@ msgid "" "\n" "Available nozzle profiles for this printer:" msgstr "" +"\n" +"\n" +"Доступные профили сопел для этого принтера:" msgid "" "\n" "\n" "Choose YES to switch existing preset:" msgstr "" +"\n" +"\n" +"Выберите «Да» для переключения профиля:" msgid "Printer Created Successfully" msgstr "Профиль принтера успешно создан" @@ -18650,16 +19647,17 @@ msgid "Select the network agent implementation for printer communication. Availa msgstr "Реализация сетевого агента для обмена информацией с принтером. Доступные реализации определяются при запуске." msgid "Select a Flashforge printer" -msgstr "" +msgstr "Выберите принтер Flashforge" msgid "Discovered Printers" -msgstr "" +msgstr "Обнаруженные принтеры" +# Reference тут – кодерский термин. Перефразировал, чтобы было понятно "не технарям" msgid "Could not get a valid Printer Host reference" -msgstr "Не удалось получить действительную ссылку на хост принтера" +msgstr "Не удалось получить настройки хоста принтера; проверьте конфигурацию" msgid "Valid session not detected. Proceed with login to 3DPrinterOS?" -msgstr "" +msgstr "Недействительная сессия. Выполнить вход в 3DPrinterOS?" msgid "Success!" msgstr "Успешно!" @@ -18700,169 +19698,171 @@ msgid "Login/Test" msgstr "Вход/Тест" msgid "Connection to printers connected via the print host failed." -msgstr "Не удалось подключиться к принтерам, подключенным через хост печати." +msgstr "Не удалось подключиться к принтерам, подключённым через хост печати." msgid "Detect Creality K-series printer" -msgstr "" +msgstr "Обнаружение принтеров Creality K-серии" msgid "Click Scan to look for K-series printers on your network." -msgstr "" +msgstr "Нажмите «Сканировать» для поиска принтеров K-серии в локальной сети." msgid "Use Selected" -msgstr "" +msgstr "Использовать" msgid "Scanning the LAN for K-series printers... this takes a few seconds." -msgstr "" +msgstr "Сканирование локальной сети... это может занять несколько секунд." msgid "No K-series printers found. Make sure the printer is on the same network and not blocked by Wi-Fi client isolation, then click Scan again." -msgstr "" +msgstr "Принтеров K-серии не найдено. Убедитесь, что принтер подключён к той же сети и не заблокирован функцией изоляции устройств (она же «гостевая сеть»)." #, c-format msgid "Found %zu Creality printer(s). Select one and click Use Selected." -msgstr "" +msgstr "Найдено принтеров: %zu. Выберите нужный и нажмите «Использовать»." msgid "Active" -msgstr "" +msgstr "Активно" msgid "Printers" -msgstr "" +msgstr "Принтеры" msgid "Processes" -msgstr "" +msgstr "Настройки печати" msgid "Show/Hide system information" -msgstr "" +msgstr "Переключить отображение системной информации" msgid "Copy system information to clipboard" -msgstr "" +msgstr "Копировать в буфер обмена" msgid "We need information for diagnosing source of the issue. Check wiki page for detailed guide." -msgstr "" +msgstr "Эта информация требуется для диагностики проблем. Ознакомьтесь с руководством для получения подробностей." msgid "Pack button collects project file and logs of current session onto a zip file." -msgstr "" +msgstr "Нажмите «Экспорт», чтобы сохранить текущий проект и журнал сессии в ZIP-архив." msgid "Any additional visual examples like images or screen recordings might be helpful while reporting the issue." -msgstr "" +msgstr "Дополнительная информация (снимки или записи экрана) также будет весьма полезной для понимания условий возникновения проблемы." msgid "Report issue" -msgstr "" +msgstr "Сообщить о проблеме" msgid "Pack" -msgstr "" +msgstr "Экспорт" msgid "Cleans and rebuilds system profiles cache on next launch" -msgstr "" +msgstr "Удалить файлы кэша системных профилей. Кэш необходим для ускорения загрузки и будет создан снова при перезапуске." msgid "Clean system profiles cache" -msgstr "" +msgstr "Очистить кэш системных профилей" msgid "Clean" -msgstr "" +msgstr "Очистить" msgid "Loaded profiles overview" -msgstr "" +msgstr "Сведения о загруженных профилях" msgid "This section shows information for loaded profiles" -msgstr "" +msgstr "Информация о количестве загруженных профилей" msgid "Exports detailed overview of loaded profiles in json format" -msgstr "" +msgstr "Экспорт подробной информации о загруженных профилях в JSON-файл" msgid "Configurations folder" -msgstr "" +msgstr "Расположение слайсера" msgid "Opens configurations folder" -msgstr "" +msgstr "Открыть расположение пользовательской конфигурации слайсера в файловом менеджере" msgid "Log level" -msgstr "" +msgstr "Уровень ведения журнала" msgid "Stored logs" -msgstr "" +msgstr "Сохранённые журналы" msgid "Packs all stored logs onto a zip file." -msgstr "" +msgstr "Нажмите «Экспорт», чтобы упаковать все сохранённые журналы в единый ZIP-архив" msgid "Profiles" -msgstr "" +msgstr "Профили" msgid "Select NO to close dialog and review project" -msgstr "" +msgstr "Нет – отменить экспорт и вернуться к проекту." msgid "No project file on current session. Only logs will be included to package" -msgstr "" +msgstr "Проект не сохранён. Будет экспортирован только журнал." msgid "Select NO to close dialog and review project." -msgstr "" +msgstr "Нет – отменить экспорт и вернуться к проекту." msgid "Please make sure any instances of OrcaSlicer are not running" -msgstr "" +msgstr "Убедитесь, что других экземпляров слайсера не запущено." msgid "System folder cannot be deleted because some files are in use by another application. Please close any applications using these files and try again." -msgstr "" +msgstr "Хранилище системных профилей занято другим приложением. Закройте приложения, использующие OrcaSlicer/system и попробуйте ещё раз." msgid "Failed to delete system folder..." -msgstr "" +msgstr "Не удалось удалить копии системных профилей..." msgid "Failed to determine executable path." -msgstr "" +msgstr "Не удалось найти исполняемый файл для перезапуска." msgid "Failed to launch a new instance." -msgstr "" +msgstr "Не удалось запустить новый экземпляр." msgid "log(s)" -msgstr "" +msgstr "журналов" msgid "Choose where to save the exported JSON file" -msgstr "" +msgstr "Укажите расположение для экспорта JSON-файла" msgid "" "Export failed\n" "Please check write permissions or file in use by another application" msgstr "" +"Ошибка экспорта.\n" +"Временный файл занят другим процессом или не может быть сохранён в защищённое от записи расположение." msgid "Choose where to save the exported ZIP file" -msgstr "" +msgstr "Укажите расположение для экспорта ZIP-файла" msgid "File already exists. Overwrite?" -msgstr "" +msgstr "Файл с таким именем уже существует. Перезаписать?" msgid "3DPrinterOS Cloud upload options" -msgstr "" +msgstr "Варианты отправки в 3DPrinterOS Cloud" msgid "Single file" -msgstr "" +msgstr "Только файл" msgid "Project File" -msgstr "" +msgstr "Весь проект" msgid "Project:" -msgstr "" +msgstr "Проект:" msgid "Printer type:" -msgstr "" +msgstr "Принтер:" msgid "Printer type not found, please select manually." -msgstr "" +msgstr "Требуется указать принтер вручную" msgid "Authorizing..." -msgstr "" +msgstr "Авторизация..." msgid "Error. Can't get api token for authorization" -msgstr "" +msgstr "Ошибка получения токена авторизации" msgid "Could not parse server response." -msgstr "" +msgstr "Ошибка анализа ответа сервера." msgid "Error saving session to file" -msgstr "" +msgstr "Ошибка записи сеанса в файл" msgid "Error session check" -msgstr "" +msgstr "Ошибка проверки сеанса" msgid "Error during file upload" -msgstr "" +msgstr "Ошибка при отправке файла" #, c-format, boost-format msgid "Mismatched type of print host: %s" @@ -18907,21 +19907,22 @@ msgstr "Примечание: для активации функцией заг msgid "Connection to MKS is working correctly." msgstr "Подключение к MKS успешно установлено." +# Ну не могу пройти мимо, пускай будет пасхалка ;-; msgid "Could not connect to MKS" -msgstr "Не удалось подключиться к MKS" +msgstr "Не удалось подключиться к MKS. Проверьте, не сведена ли она с орбиты" msgid "Connection to Moonraker is working correctly." -msgstr "" +msgstr "Подключение к Moonraker успешно установлено." msgid "Could not connect to Moonraker" -msgstr "" +msgstr "Не удалось подключиться к Moonraker" msgid "The host responded but it doesn't look like Moonraker (missing result.klippy_state)." -msgstr "" +msgstr "ответ получен, но не похоже, что его отправил Moonraker (отсутствует result.klippy_state)." #, c-format, boost-format msgid "Could not parse Moonraker server response: %s" -msgstr "" +msgstr "Ошибка анализа ответа Moonraker: %s " msgid "Connection to OctoPrint is working correctly." msgstr "Подключение к OctoPrint успешно установлено." @@ -18983,7 +19984,7 @@ msgid "" "Message body: \"%2%\"" msgstr "" "Статус HTTP: %1%\n" -"Текст сообщения: \"%2%\"" +"Текст сообщения: «%2%»" #, boost-format msgid "" @@ -18993,7 +19994,7 @@ msgid "" msgstr "" "Не удалось проанализировать ответ хоста.\n" "Текст сообщения: \"%1%\"\n" -"Ошибка: \"%2%\"" +"Ошибка: «%2%»" #, boost-format msgid "" @@ -19003,7 +20004,7 @@ msgid "" msgstr "" "Ошибка при перечислении хост-принтеров.\n" "Текст сообщения: \"%1%\"\n" -"Ошибка: \"%2%\"" +"Ошибка: «%2%»" msgid "It has a small layer height. This results in almost negligible layer lines and high print quality. It is suitable for most printing cases." msgstr "Стандартная высота слоя для сопла 0.2 мм. Обеспечивает практически незаметные слои и высокое качество печати. Подходит для большинства обычных сценариев печати." @@ -19296,6 +20297,12 @@ msgstr "Ошибка печати" msgid "Removed" msgstr "Удалено" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Больше не показывать" @@ -19331,12 +20338,25 @@ msgstr "Видеоурок" msgid "(Sync with printer)" msgstr " (состояние принтера)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Осуществлять нарезку в соответствии с этой группировкой:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "Совет: для назначения материала перетащите его в нужное поле." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Режим группировки материалов для этого стола определяется в выпадающем меню при наведении на кнопку «Нарезать стол»." @@ -19362,116 +20382,117 @@ msgid "SimplyPrint account not linked. Go to Connect options to set it up." msgstr "Учётная запись SimplyPrint не привязана. Перейдите в раздел подключения для настройки." msgid "Flashforge returned an invalid JSON response." -msgstr "" +msgstr "Ответ Flashforge содержит повреждённый JSON." msgid "No Flashforge printers were discovered on the local network." -msgstr "" +msgstr "В локальной сети не обнаружено принтеров Flashforge." msgid "Connected to Flashforge local API successfully." -msgstr "" +msgstr "Подключение к локальному API Flashforge успешно установлено." msgid "Serial connection to Flashforge is working correctly." msgstr "Подключение к Flashforge через послеовательный порт успешно установлено." msgid "Could not connect to Flashforge local API" -msgstr "" +msgstr "Не удалось подключиться к локальному API Flashforge" msgid "Could not connect to Flashforge via serial" msgstr "Не удалось подключиться к Flashforge через последовательный порт" msgid "Flashforge local API requires both serial number and access code." -msgstr "" +msgstr "Подключение к локальному API требует указания серийного номера и кода доступа." msgid "Printer returned an error" -msgstr "" +msgstr "Принтер сообщил об ошибке" msgid "Missing system_info in response" -msgstr "" +msgstr "В ответе отсутствует system_info" msgid "Missing printer serial number in response" -msgstr "" +msgstr "В ответе отсутствует серийный номер" msgid "Error parsing response" -msgstr "" +msgstr "Ошибка анализа ответа" msgid "ElegooLink not detected" -msgstr "" +msgstr "Сервер ElegooLink не обнаружен" msgid "Invalid access code" -msgstr "" +msgstr "Недействительный код доступа" msgid "CC2 device not detected" -msgstr "" +msgstr "CC2 не обнаружен" msgid "Connection to ElegooLink is working correctly." -msgstr "" +msgstr "Подключение к ElegooLink успешно установлено" msgid "Could not connect to ElegooLink" -msgstr "" +msgstr "Не удалось подключиться к ElegooLink" #, boost-format msgid "Error code: %1%" -msgstr "" +msgstr "Код ошибки: %1%" msgid "Upload failed" -msgstr "" +msgstr "Отправка не удалась" msgid "The file has been transferred, but some unknown errors occurred. Please check the device page for the file and try to start printing again." -msgstr "" +msgstr "Файл был отправлен, однако при запуске печати возникла неизвестная ошибка. Проверьте наличие файла в интерфейсе принтера и попробуйте запустить печать заново." msgid "Failed to open file for upload." -msgstr "" +msgstr "Не удалось прочитать файл для отправки." msgid "Failed to read file chunk for upload." -msgstr "" +msgstr "Не удалось прочитать фрагмент файла." msgid "CC2 upload failed" -msgstr "" +msgstr "Ошибка отправки на CC2" msgid "The file is empty or could not be read." -msgstr "" +msgstr "Файл пуст или нечитаем." msgid "Failed to calculate file checksum." -msgstr "" +msgstr "Не удалось вычислить контрольную сумму файла." msgid "Error code not found" -msgstr "" +msgstr "Код ошибки не определён" msgid "The printer is busy, Please check the device page for the file and try to start printing again." -msgstr "" +msgstr "Принтер занят; убедитесь в отсутствии выполняемых заданий в интерфейсе принтера и попробуйте ещё раз." msgid "The file is lost, please check and try again." -msgstr "" +msgstr "Файл для передачи не найден; попробуйте ещё раз." msgid "The file is corrupted, please check and try again." -msgstr "" +msgstr "Файл повреждён; проверьте целостность и попробуйте ещё раз." msgid "Transmission abnormality, please check and try again." -msgstr "" +msgstr "Аномальное поведение при передаче, попробуйте ещё раз." msgid "The file does not match the printer, please check and try again." -msgstr "" +msgstr "Модель принтера не соответствует файлу; проверьте выбранный профиль и попробуйте ещё раз." msgid "Start print timeout" -msgstr "" +msgstr "Не удалось запустить печать: превышено время ожидания" msgid "Start print failed" -msgstr "" +msgstr "Не удалось запустить печать" msgid "Connected to CrealityPrint successfully!" -msgstr "" +msgstr "Подключение к CrealityPrint успешно установлено" msgid "Could not connect to CrealityPrint" -msgstr "" +msgstr "Не удалось подключиться к CrealityPrint" msgid "Connection timed out. Please check if the printer and computer network are functioning properly, and confirm that they are on the same network." -msgstr "" +msgstr "Превышено время ожидания. Убедитесь, что компьютер и принтер подключены к общей корректно функционирующей сети." msgid "The Hostname/IP/URL could not be parsed, please check it and try again." -msgstr "" +msgstr "Не удалось распознать имя хоста/IP/URL. Проверьте указанные сведения и попробуйте ещё раз." +# В коде это буквально connection_reset: error.find("Connection was reset") msgid "File/data transfer interrupted. Please check the printer and network, then try it again." -msgstr "" +msgstr "Передача сброшена. Проверьте функционирование сети и подключение к ней и попробуйте ещё раз." msgid "The provided state is not correct." msgstr "Указано неверное состояние." @@ -19495,16 +20516,16 @@ msgid "Detection radius" msgstr "Радиус обнаружения" msgid "Selected" -msgstr "" +msgstr "Выбранные" msgid "Auto-generate" -msgstr "" +msgstr "Авторазмещение" msgid "Generate brim ears using Max angle and Detection radius" -msgstr "" +msgstr "Расположить мышиные ушки автоматически на основе указанного угла и радиуса обнаружения" msgid "Add or Select" -msgstr "" +msgstr "Выбрать/добавить" msgid "Warning: The brim type is not set to \"painted\", the brim ears will not take effect!" msgstr "Предупреждение: ручная расстановка каймы не будет учитваться в автоматических режимах генерации!" @@ -19522,10 +20543,10 @@ msgid "Please select single object." msgstr "Пожалуйста, выберите один объект." msgid "Entering Brim Ears" -msgstr "" +msgstr "Запуск режима размещения мышиных ушек" msgid "Leaving Brim Ears" -msgstr "" +msgstr "Выход из режима размещения мышиных ушек" msgid "Zoom Out" msgstr "Отдалить" @@ -19537,7 +20558,7 @@ msgid "Load skipping objects information failed. Please try again." msgstr "Не удалось загрузить информацию о пропуске объектов, попробуйте ещё раз." msgid "Failed to create the temporary folder." -msgstr "" +msgstr "Не удалось создать временное расположение" #, c-format, boost-format msgid "/%d Selected" @@ -19568,9 +20589,6 @@ msgstr "Это действие необратимо. Продолжить?" msgid "Skipping objects." msgstr "Исключение объектов." -msgid "Select Filament" -msgstr "Выбрать филамент" - msgid "Null Color" msgstr "Цвет не задан" @@ -19683,43 +20701,46 @@ msgid "Calculating, please wait..." msgstr "Расчёт, подождите..." msgid "Save these settings as default" -msgstr "" +msgstr "Сохранить как настройки по умолчанию" msgid "If enabled, the values above are stored as the defaults used for future STEP imports (and shown in Preferences)." -msgstr "" +msgstr "Активируйте для сохранения настроек импорта после его завершения." msgid "PresetBundle" msgstr "" msgid "Bundle folder does not exist." -msgstr "" +msgstr "Хранилище пакета профилей не найдено." msgid "Failed to open folder." -msgstr "" +msgstr "Не удалось открыть папку." msgid "Delete selected bundle from folder and all presets loaded from it?" -msgstr "" +msgstr "Удалить из хранилища выбранный пакет и все его профили?" +# Кнопка удаления msgid "Delete Bundle" -msgstr "" +msgstr "Удалить пакет" msgid "Failed to remove bundle." -msgstr "" +msgstr "Не удалось удалить пакет." +# Заголовок сообщения (судя по коду) msgid "Remove Bundle" -msgstr "" +msgstr "Удаление пакета" msgid "Unsubscribe bundle?" -msgstr "" +msgstr "Отписаться от пакета?" msgid "UnsubscribeBundle" msgstr "" msgid "Failed to unsubscribe bundle." -msgstr "" +msgstr "Не удалось отписаться от пакета." +# Не знаю, как это ещё можно не косячно озаглавить msgid "Unsubscribe Bundle" -msgstr "" +msgstr "Ошибка" msgid "ExportPresetBundle" msgstr "" @@ -19728,48 +20749,54 @@ msgid "Save preset bundle" msgstr "" msgid "Performing desktop integration failed - boost::filesystem::canonical did not return appimage path." -msgstr "" +msgstr "Не удалось выполнить интеграцию с окружением: boost::filesystem::canonical не вернул путь к AppImage." msgid "Performing desktop integration failed - Could not find executable." -msgstr "" +msgstr "Не удалось выполнить интеграцию с окружением: исполняемый файл не найден." msgid "Performing desktop integration failed because the application directory was not found." -msgstr "" +msgstr "Не удалось выполнить интеграцию с окружением: директория приложения не найдена." +# Это же вообще легаси времён отдельного просмотрщика PrusaSlicer Gcodeviewer? Он был выпилен ещё из Bambu Studio, если не ошибаюсь msgid "Performing desktop integration failed - could not create Gcodeviewer desktop file. OrcaSlicer desktop file was probably created successfully." -msgstr "" +msgstr "Не удалось выполнить интеграцию с окружением: ошибка создания .desktop для просмотрщика Gcode. Однако .desktop для OrcaSlicer, вероятно, был создан успешно." +# Downloader – интеграция с окружением рабочего стола для открытия ссылок в браузере. msgid "Performing downloader desktop integration failed - boost::filesystem::canonical did not return appimage path." -msgstr "" +msgstr "Не удалось настроить ассоциации ссылок: boost::filesystem::canonical не вернул путь к AppImage." msgid "Performing downloader desktop integration failed - Could not find executable." -msgstr "" +msgstr "Не удалось настроить ассоциации ссылок: исполняемый файл не найден." msgid "Performing downloader desktop integration failed because the application directory was not found." -msgstr "" +msgstr "Не удалось настроить ассоциации ссылок: директория приложения не найдена." msgid "Desktop Integration" -msgstr "" +msgstr "Интеграция с окружением" +# В коде там дальше идёт не Perform, а *btn_perform = new wxButton(this, wxID_ANY, _L("Apply")); msgid "" "Desktop Integration sets this binary to be searchable by the system.\n" "\n" "Press \"Perform\" to proceed." msgstr "" +"Интеграция с окружением рабочего стола настраивает обнаружение этого файла системой.\n" +"\n" +"Нажмите «Применить» для выполнения настройки." msgid "The download has failed" -msgstr "" +msgstr "Ошибка загрузки" #. TRN %1% = file path #, boost-format msgid "Can't create file at %1%" -msgstr "" +msgstr "Невозможно создать файл в %1%" msgid "Archive preview" -msgstr "" +msgstr "Просмотр архива" msgid "Open File" -msgstr "" +msgstr "Открыть файл" msgid "The filament may not be compatible with the current machine settings. Generic filament presets will be used." msgstr "Материал может быть несовместим с текущими настройками принтера. Будет использоваться базовый профиль материала." @@ -19860,7 +20887,7 @@ msgid "" "You can switch between Prepare and Preview workspaces by pressing the Tab key." msgstr "" "Переключение между вкладками\n" -"Вы можете переключаться между вкладками Подготовка и Предпросмотр нарезки, нажав клавишу Tab." +"При помощи клавиши Tab можно переключаться между вкладками Подготовка и Просмотр нарезки." #: resources/data/hints.ini: [hint:How to use keyboard shortcuts] msgid "" @@ -19874,7 +20901,7 @@ msgstr "" msgid "" "Reverse on even\n" "Did you know that Reverse on even feature can significantly improve the surface quality of your overhangs? However, it can cause wall inconsistencies so use carefully!" -msgstr "" +msgstr "Реверс на чётных слояхСовет: настройка Реверс на чётных слоях может существенно улучшить качество нависающих поверхностей. Как и нарушить их однородность, так что используйте с осторожностью." #: resources/data/hints.ini: [hint:Cut Tool] msgid "" @@ -20096,6 +21123,45 @@ msgstr "" "Предотвращение коробления материала\n" "Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "Отрисовывать тени в режиме продвинутой графики." + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "Применять сглаживание нормалей в режиме продвинутой графики. Требует перезагрузки." + +#~ msgid "" +#~ "Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n" +#~ "\n" +#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n" +#~ "\n" +#~ "This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues.Enable adaptive PA whenever there are flow changes in a feature, such as line width changes in a corner or overhangs.\n" +#~ "\n" +#~ "Not compatible with Prusa printers as they pause to process PA changes, which causes delays and defects.\n" +#~ "\n" +#~ "This is an experimental option, as if the PA profile is not set accurately, it will cause uniformity issues." +#~ msgstr "" +#~ "Экспериментальный режим смены коэффициента PA прямо посреди печати линии для адаптации к изменениям расхода на ней (например, на нависаниях или периметрах переменной ширины).\n" +#~ "\n" +#~ "Предупреждение: неточный подбор значений PA может привести дефектам при работе этой настройки.\n" +#~ "\n" +#~ "Внимание: несовместимо с принтерами Prusa, поскольку им требуется остановка для изменения коэффициента PA." + +#~ msgid "Continue to sync filaments" +#~ msgstr "Продолжить синхронизацию филаментов" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Отмена" + +#~ msgid "Align infill direction to model" +#~ msgstr "Вращать заполнение с моделью" + +#~ msgid "Print" +#~ msgstr "Печать" + #~ msgid "in" #~ msgstr "дюйм" @@ -21034,9 +22100,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Невозможно запустить без SD-карты." -#~ msgid "Update" -#~ msgstr "Обновление" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Чувствительность" diff --git a/localization/i18n/sv/OrcaSlicer_sv.po b/localization/i18n/sv/OrcaSlicer_sv.po index 1f6843c487..8ea2df6ba9 100644 --- a/localization/i18n/sv/OrcaSlicer_sv.po +++ b/localization/i18n/sv/OrcaSlicer_sv.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -32,6 +32,24 @@ msgstr "TPU stöds inte av AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -44,6 +62,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF-trådar är hårda och spröda, så de kan lätt gå sönder eller fastna i en AMS; använd dem med försiktighet." @@ -53,10 +74,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "" + +msgid "TPU High Flow" +msgstr "TPU Hög Flöde" + +msgid "Unknown" +msgstr "Okänd" + +msgid "Hardened Steel" +msgstr "Härdat stål" + +msgid "Stainless Steel" +msgstr "Rostfritt stål" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "Verktygs huvudet och hotend stället kan röra sig. Håll händerna borta från kammaren." + +msgid "Warning" +msgstr "Varning" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "Informationen om hotend kan vara felaktig. Vill du läsa av hotend igen? (Informationen om hotend kan ändras vid avstängning)." + +msgid "I confirm all" +msgstr "Jag bekräftar allt" + +msgid "Re-read all" +msgstr "Läs om allt" + +msgid "Reading the hotends, please wait." +msgstr "Läser av hotends, vänta." + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "Under hotend uppgraderingen kommer verktygshuvudet att röra sig. Stoppa inte in något i kammaren." + +msgid "Update" +msgstr "Uppdatera" + msgid "Current AMS humidity" msgstr "" @@ -87,6 +188,85 @@ msgstr "" msgid "Latest version" msgstr "Senaste version" +msgid "Row A" +msgstr "Rad A" + +msgid "Row B" +msgstr "Rad B" + +msgid "Toolhead" +msgstr "Verktygshuvud" + +msgid "Empty" +msgstr "Tom" + +msgid "Error" +msgstr "FEL" + +msgid "Induction Hotend Rack" +msgstr "Induktion Hotend Ställning" + +msgid "Hotends Info" +msgstr "Hotend Information" + +msgid "Read All" +msgstr "Läs allt" + +msgid "Reading " +msgstr "Läser " + +msgid "Please wait" +msgstr "Vänligen vänta" + +msgid "Running..." +msgstr "Kör..." + +msgid "Raised" +msgstr "Upphöjd" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "Hotend är i ett onormalt tillstånd och är inte tillgängligt. Gå till 'Enhet -> Uppgradera' för att uppgradera firmware." + +msgid "Abnormal Hotend" +msgstr "Onormal Hotend" + +msgid "Refresh" +msgstr "Uppdatera" + +msgid "Refreshing" +msgstr "Uppdaterar" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "Hotend status onormal, ej tillgänglig för närvarande. Uppgradera firmware och försök igen." + +msgid "Cancel" +msgstr "Avbryt" + +msgid "Jump to the upgrade page" +msgstr "Gå till uppgraderings sidan" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "Använd tid: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "Dynamiska nozzles är tilldelade på den aktuella plattan. Val av hotend stöds inte." + +msgid "Hotend Rack" +msgstr "Hotend Ställning" + +msgid "ToolHead" +msgstr "Verktygshuvud" + +msgid "Nozzle information needs to be read" +msgstr "Nozzle information måste läsas" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Färgläggning av Support" @@ -159,6 +339,12 @@ msgstr "Fyll" msgid "Gap Fill" msgstr "Gap Fyllning" +msgid "Vertical" +msgstr "Vertikal" + +msgid "Horizontal" +msgstr "Horisontell" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Tillåter målning endast på fasetter som valts av: ”%1%”" @@ -254,12 +440,6 @@ msgstr "Triangel" msgid "Height Range" msgstr "Höjd intervall" -msgid "Vertical" -msgstr "Vertikal" - -msgid "Horizontal" -msgstr "Horisontell" - msgid "Remove painted color" msgstr "Ta bort färgläggning" @@ -324,6 +504,7 @@ msgstr "" msgid "Optimize orientation" msgstr "Optimisera placering" +msgctxt "Verb" msgid "Scale" msgstr "Skala" @@ -368,6 +549,9 @@ msgstr "Skalnings förhållande" msgid "Object operations" msgstr "Objekt Åtgärder" +msgid "Scale" +msgstr "Skala" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Volym Åtgärder" @@ -418,6 +602,10 @@ msgstr "" msgid "Reset current rotation to real zeros." msgstr "" +msgctxt "Noun" +msgid "Scale" +msgstr "Skala" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Storlek" @@ -595,9 +783,6 @@ msgstr "" msgid "Confirm connectors" msgstr "Bekräfta kontakterna" -msgid "Cancel" -msgstr "Avbryt" - msgid "Flip cut plane" msgstr "" @@ -638,12 +823,12 @@ msgstr "Beskär till delar" msgid "Reset cutting plane and remove connectors" msgstr "" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Utför beskärning" -msgid "Warning" -msgstr "Varning" - msgid "Invalid connectors detected" msgstr "Ogiltiga anslutningar upptäckta" @@ -674,6 +859,13 @@ msgstr "" msgid "Connector" msgstr "Kontakt" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "" @@ -721,9 +913,6 @@ msgstr "Förenkla" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Förenkling är för tillfället endast accepterat när en enkel del är vald" -msgid "Error" -msgstr "FEL" - msgid "Extra high" msgstr "Extra hög" @@ -1967,6 +2156,9 @@ msgstr "" msgid "Loading user preset" msgstr "Laddar användarens förinställning" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -1980,6 +2172,18 @@ msgstr "Välj språk" msgid "Language" msgstr "Språk" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2610,6 +2814,45 @@ msgstr "Klicka på ikonen för att redigera färgläggningen av objektet" msgid "Click the icon to shift this object to the bed" msgstr "Klicka på ikonen för att flytta detta föremål till byggplattan" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Laddar fil" @@ -2619,6 +2862,9 @@ msgstr "Fel!" msgid "Failed to get the model data in the current file." msgstr "Det gick inte att hämta modelldata i den aktuella filen." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Allmän" @@ -2631,6 +2877,12 @@ msgstr "Växla till inställningsläge för varje objekt för att redigera proce msgid "Remove paint-on fuzzy skin" msgstr "" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Ta bort höjdintervall" + msgid "Delete connector from object which is a part of cut" msgstr "Ta bort kopplingen från objekt som är en del av snittet" @@ -2661,12 +2913,24 @@ msgstr "Ta bort alla kopplingar" msgid "Deleting the last solid part is not allowed." msgstr "Ej tillåtet att radera den senaste fasta delen." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "" +msgid "Split to parts" +msgstr "Dela upp i delar" + msgid "Assembly" msgstr "Montering" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Information om kontakter" @@ -2700,6 +2964,9 @@ msgstr "Höjd intervall" msgid "Settings for height range" msgstr "Inställningar för höjdintervall" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Lager" @@ -2722,6 +2989,9 @@ msgstr "Typ:" msgid "Choose part type" msgstr "Välj en del typ" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Skriv in nytt namn" @@ -2749,6 +3019,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Ytterligare process inställning" @@ -2758,9 +3031,6 @@ msgstr "Ta bort parameter" msgid "to" msgstr "till" -msgid "Remove height range" -msgstr "Ta bort höjdintervall" - msgid "Add height range" msgstr "Lägg till höjdintervall" @@ -2972,6 +3242,9 @@ msgstr "Välj ett AMS fack och tryck sedan på knappen \"Ladda\" eller \"Mata ut msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3094,6 +3367,24 @@ msgstr "Bekräfta extruderad" msgid "Check filament location" msgstr "Kontrollera filamentets placering" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3147,6 +3438,62 @@ msgstr "Utvecklingsläge" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "Ange antal nozzle" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "Fel: Kan inte ställa in båda nozzle till noll." + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "Fel: Antal nozzle får inte överskrida %d." + +msgid "Confirm" +msgstr "Acceptera" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "Val av nozzle" + +msgid "Available Nozzles" +msgstr "Tillgängliga nozzle" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "Synkronisera nozzle status" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "Varning: Blandning av nozzle diametrar i en utskrift stöds inte. Om den valda storleken bara är på en extruder kommer singel extruder utskrift att utföras." + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "Uppdatera %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "Okänd nozzle upptäckt. Uppdatera för att uppdatera info (ej uppdaterad nozzle kommer att uteslutas under beredning). Verifiera nozzle diameter och flödes hastighet mot visade värden." + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "Okänd nozzle upptäckt. Uppdatera för att uppdatera (ej uppdaterad nozzle kommer att hoppas över i beredning)." + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "Bekräfta om den önskade nozzle diametern och flödes hastigheten matchar de värden som visas just nu." + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "Din printer har olika nozzle installerade. Välj en nozzle för denna utskrift." + +msgid "Ignore" +msgstr "Ignorera" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3480,15 +3827,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "" - msgid "AMS Materials Setting" msgstr "AMS Material Inställning" -msgid "Confirm" -msgstr "Acceptera" - msgid "Close" msgstr "Stäng" @@ -3509,12 +3850,12 @@ msgstr "" msgid "The input value should be greater than %1% and less than %2%" msgstr "Inmatningsvärdet ska vara större än %1% och mindre än %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Faktorer för kalibrering av flödesdynamik" +msgid "Wiki Guide" +msgstr "" + msgid "PA Profile" msgstr "PA profil" @@ -3603,7 +3944,7 @@ msgstr "Kalibreringen klar. Vänligen hitta den mest enhetliga extruderingslinje msgid "Save" msgstr "Spara" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Tillbaka" @@ -3678,6 +4019,19 @@ msgstr "" msgid "Nozzle" msgstr "Nozzel" +msgid "Select Filament && Hotends" +msgstr "Välj Filament && Hotends" + +msgid "Select Filament" +msgstr "Välj filament" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "Utskrift med det aktuell nozzle kan ge extra %0.2fg avfall." + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4374,9 +4728,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "Okänd" - msgid "Update successful." msgstr "Uppdateringen lyckades." @@ -4888,9 +5239,6 @@ msgstr "" msgid "Regroup filament" msgstr "" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "upp till" @@ -4927,8 +5275,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Fläkt hastighet (%)" -msgid "Temperature (°C)" -msgstr "Temperatur (°C)" +msgid "Temperature (℃)" +msgstr "Temperatur (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Volymetrisk flödeshastighet (mm³/s)" @@ -4946,9 +5294,6 @@ msgstr "Filament byten" msgid "Options" msgstr "Val" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "Kostnad" @@ -4961,6 +5306,7 @@ msgstr "" msgid "Color change" msgstr "Färg byte" +msgctxt "Noun" msgid "Print" msgstr "Skriv ut" @@ -5120,11 +5466,15 @@ msgstr "Undvik kalibrerings området" msgid "Align to Y axis" msgstr "Justera mot Y-axeln" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Tillbaka" + +msgctxt "Camera View" msgid "Left" msgstr "Vänster" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Höger" @@ -5149,9 +5499,6 @@ msgstr "Ordna alla objekt på vald platta" msgid "Split to objects" msgstr "Dela upp till objekt" -msgid "Split to parts" -msgstr "Dela upp i delar" - msgid "Assembly View" msgstr "Monterings vy" @@ -5448,6 +5795,10 @@ msgstr "Skriv ut byggplattan" msgid "Export G-code file" msgstr "Exportera G-kod filen" +msgctxt "Verb" +msgid "Print" +msgstr "Skriv ut" + msgid "Export plate sliced file" msgstr "Exportera byggplattans beredda fil" @@ -5621,15 +5972,6 @@ msgstr "Exportera aktuell konfiguration till filer" msgid "Export" msgstr "Exportera" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Avsluta" @@ -5746,6 +6088,15 @@ msgstr "Vy" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5866,6 +6217,9 @@ msgstr "Exportera resultat" msgid "Select profile to load:" msgstr "Välj den profil som ska laddas:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6028,9 +6382,6 @@ msgstr "Ladda ner valda filer från skrivaren." msgid "Batch manage files." msgstr "Batch hantera filer." -msgid "Refresh" -msgstr "Uppdatera" - msgid "Reload file list from printer." msgstr "" @@ -6339,6 +6690,9 @@ msgstr "Utskriftsalternativ" msgid "Safety Options" msgstr "" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Lampa" @@ -6372,6 +6726,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6422,9 +6782,6 @@ msgstr "Detta gäller endast under utskrift." msgid "Silent" msgstr "Tyst" -msgid "Standard" -msgstr "" - msgid "Sport" msgstr "" @@ -6458,6 +6815,12 @@ msgstr "Lägg till en bild" msgid "Delete Photo" msgstr "Ta bort foto" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Skicka in" @@ -6634,6 +6997,9 @@ msgstr "" msgid "Don't show this dialog again" msgstr "" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "3D mus bortkopplad." @@ -6888,26 +7254,17 @@ msgstr "Flöde" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "Härdat stål" - -msgid "Stainless Steel" -msgstr "Rostfritt stål" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "Mässing" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" -msgstr "Uppdaterar" +msgid "No wiki link available for this printer." +msgstr "" msgid "Unavailable while heating maintenance function is on." msgstr "" @@ -7031,6 +7388,15 @@ msgstr "" msgid "Configuration incompatible" msgstr "Ej kompatibel konfiguration" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "" + msgid "Sync printer information" msgstr "" @@ -7057,6 +7423,9 @@ msgstr "Tryck för att redigera inställningar" msgid "Project Filaments" msgstr "" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Rensnings volymer" @@ -7282,9 +7651,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "" - msgid "The file does not contain any geometry data." msgstr "Filen innehåller ingen geometrisk data." @@ -7332,9 +7698,21 @@ msgstr "" "Denna åtgärd kommer att bryta en klippt korrespondens.\n" "Efter det kan modell konsistens inte garanteras." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Det valda objektet kan inte delas." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7361,6 +7739,9 @@ msgstr "Välj en ny fil" msgid "File for the replacement wasn't selected" msgstr "Ersättningsfilen valdes inte" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7407,6 +7788,9 @@ msgstr "Det gick inte att ladda om:" msgid "Error during reload" msgstr "Fel vid omladdning" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Varningar efter beredning:" @@ -8159,6 +8543,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8174,16 +8567,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8463,6 +8847,9 @@ msgstr "Ej giltliga förinställningar" msgid "My Printer" msgstr "" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8482,6 +8869,9 @@ msgstr "Lägg till/Ta bort förinställningar" msgid "Edit preset" msgstr "Redigera förinställningar" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "" @@ -8513,9 +8903,6 @@ msgstr "Välj/ta bort printer(systemet inställningar)" msgid "Create printer" msgstr "Skapa printer" -msgid "Empty" -msgstr "Tom" - msgid "Incompatible" msgstr "Inkompatibel" @@ -8741,11 +9128,41 @@ msgstr "Skicka komplett" msgid "Error code" msgstr "Felkod" -msgid "High Flow" +msgid "Error desc" +msgstr "Fel desc" + +msgid "Extra info" +msgstr "" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, c-format, boost-format @@ -8810,7 +9227,37 @@ msgstr "" msgid "nozzle" msgstr "" -msgid "both extruders" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8824,10 +9271,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -8938,9 +9392,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -9122,6 +9573,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Klicka för att återställa alla inställningar till den senast sparade förinställningen." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "Prime tower krävs för nozzle byte. Det kan bli brister på modellen utan prime tower. Är du säker på att du vill inaktivera prime tower?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Prime tower krävs för smooth timelapse-läge. Det kan bli fel på modellen utan ett prime tower. Är du säker på att du vill inaktivera prime tower?" @@ -9197,9 +9651,6 @@ msgstr "Justera automatiskt till det inställda området?\n" msgid "Adjust" msgstr "Justera" -msgid "Ignore" -msgstr "Ignorera" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "" @@ -9698,6 +10149,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Välja %1% den valda förinställningen?" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9917,6 +10374,12 @@ msgstr "" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Lägg till fil" @@ -10164,13 +10627,9 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" +msgid "Do you want to continue to sync filaments?" msgstr "" -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Avbryt" - msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10274,6 +10733,9 @@ msgstr "Logga in" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10588,6 +11050,9 @@ msgstr "" msgid "Where to find your printer's IP and Access Code?" msgstr "Var hittar du skrivarens IP- och åtkomstkod?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Anslut" @@ -10652,6 +11117,9 @@ msgstr "" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10670,6 +11138,9 @@ msgstr "Uppdateringen misslyckades" msgid "Update successful" msgstr "Uppdateringen lyckades" +msgid "Hotends on Rack" +msgstr "Hotends på ställning" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Är du säker på att du vill uppdatera? Uppdateringen tar ca 10 minuter. Stäng inte av strömmen medans printern uppdaterar." @@ -10778,6 +11249,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "" @@ -11464,7 +11938,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11478,7 +11952,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11864,9 +12338,6 @@ msgid "" "0 to deactivate." msgstr "" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "uppåt kompatibel maskin" @@ -11876,9 +12347,6 @@ msgstr "Villkor" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "" -msgid "Select profiles" -msgstr "" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "" @@ -12120,6 +12588,42 @@ msgstr "" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Botten ytans mönster" @@ -12411,12 +12915,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "Nozzle manual" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12673,6 +13183,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Mjuknings temperatur" @@ -12735,12 +13251,12 @@ msgstr "Sparsam ifyllnads densitet" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13242,6 +13758,15 @@ msgstr "Bästa automatiska arrangemangs position i intervallet [0,1] w.r.t. bäd msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13302,6 +13827,12 @@ msgid "" "G-code command: M106 P3 S(0-255)" msgstr "" +msgid "Use cooling filter" +msgstr "Använd kylfilter" + +msgid "Enable this if printer support cooling filter" +msgstr "Aktivera detta om printern stöder kylfilter" + msgid "G-code flavor" msgstr "G-kod smak" @@ -13814,6 +14345,30 @@ msgstr "Min förflyttnings hastighet" msgid "Minimum travel speed (M205 T)" msgstr "Min förflyttnings hastighet (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "Maximal kraft för Y-axeln" + +msgid "The allowed maximum output force of Y axis" +msgstr "Den maximalt tillåtna utgående kraften för Y-axeln" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "Y-axelns bäddmassa" + +msgid "The machine bed mass load of Y axis" +msgstr "Maskinbäddens massbelastning på Y-axeln" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "Den maximalt tillåtna tryckta massan" + +msgid "The allowed max printed mass on a plate" +msgstr "Den maximalt tillåtna tryckta massan på en platta" + msgid "Maximum acceleration for extruding" msgstr "Max acceleration för extrudering" @@ -14334,6 +14889,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -14369,6 +14927,12 @@ msgstr "Åter retraktions hastighet" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Använd firmware retraktion" @@ -14400,6 +14964,10 @@ msgstr "Linjerad" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Tillbaka" + msgid "Random" msgstr "Slumpmässig" @@ -14656,6 +15224,12 @@ msgstr "Om Smooth eller Traditionellt läge väljs genereras en timelapse-video msgid "Traditional" msgstr "Traditionell" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Temperatur variation" @@ -14743,6 +15317,18 @@ msgstr "" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Bered spaltens stängningsradie" @@ -15115,7 +15701,7 @@ msgid "" msgstr "" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15170,6 +15756,45 @@ msgstr "Övre skalets tjocklek" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Antal solida övre lager ökas när tjockleken kalkyleras och övre skalet är tunnare än detta värde. Detta kan undvika att ha för tunt skal när lagerhöjden är liten. 0 betyder att den här inställningen är inaktiverad och tjockleken på det övre skalet bestäms av de övre skal lagerna" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Förflyttnings hastighet" @@ -15213,6 +15838,12 @@ msgstr "Rensnings multiplikator" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Den faktiska rensnings volymen är lika med värdet för rensnings multiplikatorn multiplicerat med rensnings volymerna i tabellen." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Prime volym (volymen av ut pressat material)" @@ -15220,6 +15851,18 @@ msgstr "Prime volym (volymen av ut pressat material)" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Material volymen att (pressa ut) genom extrudern på tornet." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Prime tornets bredd" @@ -15491,6 +16134,57 @@ msgstr "Minsta vägg bredd" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Bredden på den vägg som ska ersätta tunna element (enligt minsta storlek för element) i modellen. Om den minsta väggbredden är tunnare än tjockleken på elementet blir väggen lika tjock som själva elementet. Den uttrycks i procent av nozzel diametern." +msgid "Hotend change time" +msgstr "Tid för byte av hotend" + +msgid "Time to change hotend." +msgstr "Dags att byta hotend." + +msgid "Hotend change" +msgstr "Byte av hotend" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "När du byter hotend, rekommenderas det att extrudera en viss längd av filament från det ursprungliga nozzle. Detta hjälper till att minimera nozzle läckage." + +msgid "Extruder change" +msgstr "Extruder byte" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "För att förhindra oozing ur nozzle görs en bakåtriktad rörelse under en viss period efter att ramningen är klar. Inställningen definierar rörelse tiden." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "För att förhindra ooze ur nozzle kyls nozzle temperatur under ramning. Ramningstiden måste därför vara längre än nedkylningstiden. 0 betyder avaktiverad." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "Den maximala volymetriska hastigheten för ramning före extruder byte, där -1 innebär att den maximala volymetriska hastigheten används." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "För att förhindra läckage kyls nozzle temperatur ner under ramningen. Obs: endast ett nedkylnings kommando och fläktaktivering utlöses, det är inte garanterat att måltemperaturen uppnås. 0 betyder inaktiverad." + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "Den maximala volymetriska hastigheten för ramning före ett hotend byte, där -1 innebär att den maximala volymetriska hastigheten används." + +msgid "length when change hotend" +msgstr "längd vid byte av hotend" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "När detta indragnings värde ändras, kommer det att användas som mängden indraget filament inuti hotend innan du byter hotend." + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "Volymen av material som krävs för att prima extrudern för en hotend förändring på tower." + +msgid "Preheat temperature delta" +msgstr "Förvärmningstemperaturdelta" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "Temperaturdelta tillämpad under förvärmning före verktygsbyte." + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Upptäck tight inre solid ifyllnad" @@ -16242,12 +16936,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibrering stöds inte" -msgid "Error desc" -msgstr "Fel desc" - -msgid "Extra info" -msgstr "" - msgid "Flow Dynamics" msgstr "Flödesdynamik" @@ -16436,6 +17124,12 @@ msgstr "Ange det namn som du vill spara på skrivaren." msgid "The name cannot exceed 40 characters." msgstr "Namnet får inte innehålla mer än 40 tecken." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "Standard flöde" + msgid "Please find the best line on your plate" msgstr "Hitta den bästa linjen på din platta." @@ -16526,9 +17220,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "" @@ -16603,6 +17294,10 @@ msgstr "Lyckades med att få historiskt resultat" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Uppdatering av tidigare kalibreringsposter för flödesdynamik" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "Obs: Hotend numret på %s är kopplat till hållaren. När hotend flyttas till en ny hållare uppdateras dess nummer automatiskt." + msgid "Action" msgstr "Åtgärd" @@ -18290,6 +18985,12 @@ msgstr "" msgid "Removed" msgstr "Borttagen" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -18323,12 +19024,25 @@ msgstr "Videohandledning" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -18561,9 +19275,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "Välj filament" - msgid "Null Color" msgstr "" @@ -19055,6 +19766,13 @@ msgstr "" "Undvik vridning\n" "Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?" +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Avbryt" + +#~ msgid "Print" +#~ msgstr "Skriv ut" + #~ msgid "in" #~ msgstr "i" @@ -19747,9 +20465,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Kan inte starta utan SD-kort." -#~ msgid "Update" -#~ msgstr "Uppdatera" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Känsligheten för paus är" @@ -20228,10 +20943,6 @@ msgstr "" #~ msgid "Thick bridges" #~ msgstr "Tjocka bridges" -#~ msgctxt "Verb" -#~ msgid "Scale" -#~ msgstr "Skala" - #~ msgid "Z-hop when retract" #~ msgstr "Z-hopp vid retraktion" diff --git a/localization/i18n/th/OrcaSlicer_th.po b/localization/i18n/th/OrcaSlicer_th.po index 3a4d12dd6b..55b5bd6a95 100644 --- a/localization/i18n/th/OrcaSlicer_th.po +++ b/localization/i18n/th/OrcaSlicer_th.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-06-19 13:40+0700\n" "Last-Translator: Icezaza\n" "Language-Team: Thai\n" @@ -38,6 +38,24 @@ msgstr "AMS ไม่รองรับ TPU" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS ไม่รองรับ 'Bambu Lab PET-CF'" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "โปรดทำ cold pull ก่อนพิมพ์ TPU เพื่อหลีกเลี่ยงการอุดตัน คุณสามารถใช้การบำรุงรักษาแบบ cold pull บนเครื่องพิมพ์ได้" @@ -50,6 +68,9 @@ msgstr "PVA ที่ชื้นมีความยืดหยุ่นแ msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "พื้นผิวที่ขรุขระของ PLA Glow สามารถเร่งการสึกหรอในระบบ AMS ได้ โดยเฉพาะอย่างยิ่งกับชิ้นส่วนภายในของ AMS Lite" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "เส้นพลาสติก CF/GF มีความแข็งและเปราะบาง แตกหักหรือติดค้างใน AMS ได้ง่าย โปรดใช้งานด้วยความระมัดระวัง" @@ -59,10 +80,90 @@ msgstr "PPS-CF มีความเปราะบางและอาจแ msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF มีความเปราะบางและอาจแตกหักในท่อ PTFE ที่โค้งงอเหนือหัวพิมพ์" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s ไม่รองรับกับชุดดันเส้น %s" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "อัตราไหลสูง" + +msgid "Standard" +msgstr "มาตรฐาน" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "ไม่ทราบ" + +msgid "Hardened Steel" +msgstr "เหล็กชุบแข็ง" + +msgid "Stainless Steel" +msgstr "สแตนเลส" + +msgid "Tungsten Carbide" +msgstr "ทังสเตนคาร์ไบด์" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "คำเตือน" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "ความชื้น AMS ปัจจุบัน" @@ -93,6 +194,85 @@ msgstr "เวอร์ชัน:" msgid "Latest version" msgstr "เวอร์ชันล่าสุด" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "ว่างเปล่า" + +msgid "Error" +msgstr "ข้อผิดพลาด" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "รีเฟรช" + +msgid "Refreshing" +msgstr "สดชื่น" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "ยกเลิก" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "ส.น" + +msgid "Version" +msgstr "เวอร์ชัน" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + msgid "Support Painting" msgstr "ระบายส่วนรองรับ" @@ -162,6 +342,12 @@ msgstr "เติม" msgid "Gap Fill" msgstr "เติมช่องว่าง" +msgid "Vertical" +msgstr "แนวตั้ง" + +msgid "Horizontal" +msgstr "แนวนอน" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "อนุญาตให้วาดภาพเฉพาะด้านที่เลือกโดย: \"%1%\"" @@ -254,12 +440,6 @@ msgstr "สามเหลี่ยม" msgid "Height Range" msgstr "ช่วงความสูง" -msgid "Vertical" -msgstr "แนวตั้ง" - -msgid "Horizontal" -msgstr "แนวนอน" - msgid "Remove painted color" msgstr "ลบสีที่ทาสี" @@ -324,6 +504,7 @@ msgstr "Gizmo-หมุน" msgid "Optimize orientation" msgstr "ปรับการวางแนวให้เหมาะสม" +msgctxt "Verb" msgid "Scale" msgstr "ปรับขนาด" @@ -367,6 +548,9 @@ msgstr "อัตราส่วนการปรับขนาด" msgid "Object operations" msgstr "การทำงานกับวัตถุ" +msgid "Scale" +msgstr "ปรับขนาด" + msgid "Volume operations" msgstr "การทำงานกับวอลลุ่ม" @@ -412,6 +596,10 @@ msgstr "รีเซ็ตการหมุนปัจจุบันเป็ msgid "Reset current rotation to real zeros." msgstr "รีเซ็ตการหมุนปัจจุบันให้เป็นศูนย์จริง" +msgctxt "Noun" +msgid "Scale" +msgstr "ปรับขนาด" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "ขนาด" @@ -594,9 +782,6 @@ msgstr "สัดส่วนพื้นที่สัมพันธ์กั msgid "Confirm connectors" msgstr "ยืนยันตัวเชื่อมต่อ" -msgid "Cancel" -msgstr "ยกเลิก" - msgid "Flip cut plane" msgstr "พลิกระนาบตัด" @@ -637,12 +822,12 @@ msgstr "ตัดเป็นชิ้นส่วน" msgid "Reset cutting plane and remove connectors" msgstr "รีเซ็ตระนาบการตัดและถอดตัวเชื่อมต่อออก" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "ดำเนินการตัด" -msgid "Warning" -msgstr "คำเตือน" - msgid "Invalid connectors detected" msgstr "พบตัวเชื่อมที่ไม่ถูกต้อง" @@ -671,6 +856,13 @@ msgstr "ระนาบการตัดที่มีร่องไม่ถ msgid "Connector" msgstr "ตัวเชื่อม" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "ตัดด้วยระนาบ" @@ -717,9 +909,6 @@ msgstr "ลดรายละเอียด" msgid "Simplification is currently only allowed when a single part is selected" msgstr "ขณะนี้อนุญาตให้ลดความซับซ้อนได้เฉพาะเมื่อเลือกส่วนเดียวเท่านั้น" -msgid "Error" -msgstr "ข้อผิดพลาด" - msgid "Extra high" msgstr "สูงมาก" @@ -1990,6 +2179,9 @@ msgstr "การเข้าถึง Bundle %s ไม่ได้รับอ msgid "Loading user preset" msgstr "กำลังโหลดค่าที่ตั้งล่วงหน้าของผู้ใช้" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "ลบ %s แล้ว" @@ -2003,6 +2195,18 @@ msgstr "เลือกภาษา" msgid "Language" msgstr "ภาษา" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2596,6 +2800,45 @@ msgstr "คลิกไอคอนเพื่อแก้ไขการระ msgid "Click the icon to shift this object to the bed" msgstr "คลิกที่ไอคอนเพื่อเลื่อนวัตถุนี้ไปที่ฐานพิมพ์" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "กำลังโหลดไฟล์" @@ -2605,6 +2848,9 @@ msgstr "ข้อผิดพลาด!" msgid "Failed to get the model data in the current file." msgstr "ไม่สามารถรับข้อมูลโมเดลในไฟล์ปัจจุบัน" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "ทั่วไป" @@ -2617,6 +2863,12 @@ msgstr "สลับไปที่โหมดการตั้งค่าต msgid "Remove paint-on fuzzy skin" msgstr "ลบสีบนผิวที่คลุมเครือ" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "ลบช่วงความสูง" + msgid "Delete connector from object which is a part of cut" msgstr "ลบตัวเชื่อมต่อออกจากวัตถุที่เป็นส่วนหนึ่งของการตัด" @@ -2646,12 +2898,24 @@ msgstr "ลบตัวเชื่อมต่อทั้งหมด" msgid "Deleting the last solid part is not allowed." msgstr "ไม่อนุญาตให้ลบส่วนที่เป็นของแข็งสุดท้าย" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "วัตถุเป้าหมายมีเพียงส่วนเดียวและไม่สามารถแยกออกได้" +msgid "Split to parts" +msgstr "แยกเป็นส่วนๆ" + msgid "Assembly" msgstr "การประกอบ" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "ตัดข้อมูลตัวเชื่อมต่อ" @@ -2682,6 +2946,9 @@ msgstr "ช่วงความสูง" msgid "Settings for height range" msgstr "การตั้งค่าช่วงความสูง" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "เลเยอร์" @@ -2703,6 +2970,9 @@ msgstr "ชนิด:" msgid "Choose part type" msgstr "เลือกประเภทชิ้นส่วน" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "ป้อนชื่อใหม่" @@ -2728,6 +2998,9 @@ msgstr "\"%s\" จะมีเกิน 1 ล้านผิวหน้าห msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "mesh ของส่วน \"%s\" มีข้อผิดพลาด กรุณาซ่อมแซมก่อน." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "พรีเซ็ตกระบวนการเพิ่มเติม" @@ -2737,9 +3010,6 @@ msgstr "ลบพารามิเตอร์" msgid "to" msgstr "ถึง" -msgid "Remove height range" -msgstr "ลบช่วงความสูง" - msgid "Add height range" msgstr "เพิ่มช่วงความสูง" @@ -2942,6 +3212,9 @@ msgstr "เลือกช่อง AMS แล้วกดปุ่ม \"โห msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "ไม่ทราบประเภทเส้นพลาสติกซึ่งจำเป็นต่อการดำเนินการนี้ กรุณาตั้งค่าข้อมูลของเส้นพลาสติกเป้าหมาย" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "การเปลี่ยนความเร็วพัดลมระหว่างการพิมพ์อาจส่งผลต่อคุณภาพการพิมพ์ โปรดเลือกอย่างระมัดระวัง" @@ -3063,6 +3336,24 @@ msgstr "ยืนยันการอัดขึ้นรูป" msgid "Check filament location" msgstr "ตรวจสอบตำแหน่งของเส้นพลาสติก" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "อุณหภูมิสูงสุดต้องไม่เกิน " @@ -3114,6 +3405,62 @@ msgstr "โหมดนักพัฒนา" msgid "Launch troubleshoot center" msgstr "เปิดศูนย์แก้ปัญหา" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "ยืนยัน" + +msgid "Extruder" +msgstr "ชุดดันเส้น" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "ข้อมูลหัวฉีด" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "ละเว้น" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3437,15 +3784,9 @@ msgstr "OrcaSlicer เริ่มต้นด้วยจิตวิญญา msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "ปัจจุบัน OrcaSlicer เป็นตัวแบ่งส่วนข้อมูลแบบโอเพ่นซอร์สที่ใช้กันอย่างแพร่หลายและได้รับการพัฒนาอย่างแข็งขันที่สุดในชุมชนการพิมพ์ 3 มิติ นวัตกรรมหลายอย่างของบริษัทได้ถูกนำไปใช้โดยตัวแบ่งส่วนข้อมูลอื่นๆ ทำให้สิ่งนี้เป็นแรงผลักดันสำหรับอุตสาหกรรมทั้งหมด" -msgid "Version" -msgstr "เวอร์ชัน" - msgid "AMS Materials Setting" msgstr "การตั้งค่าวัสดุ AMS" -msgid "Confirm" -msgstr "ยืนยัน" - msgid "Close" msgstr "ปิด" @@ -3466,12 +3807,12 @@ msgstr "ต่ำสุด" msgid "The input value should be greater than %1% and less than %2%" msgstr "ค่าอินพุตควรมากกว่า %1% และน้อยกว่า %2%" -msgid "SN" -msgstr "ส.น" - msgid "Factors of Flow Dynamics Calibration" msgstr "ปัจจัยของการสอบเทียบโฟลว์ไดนามิกส์" +msgid "Wiki Guide" +msgstr "คู่มือวิกิ" + msgid "PA Profile" msgstr "โปรไฟล์ PA" @@ -3559,6 +3900,7 @@ msgstr "การสอบเทียบเสร็จสิ้น โปร msgid "Save" msgstr "บันทึก" +msgctxt "Navigation" msgid "Back" msgstr "กลับ" @@ -3642,6 +3984,19 @@ msgstr "หัวฉีดขวา" msgid "Nozzle" msgstr "หัวฉีด" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "เลือกเส้นพลาสติก" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "หมายเหตุ: ประเภทเส้นพลาสติก (%s) ไม่ตรงกับประเภทเส้นพลาสติก (%s) ในไฟล์การแบ่งส่วน หากคุณต้องการใช้ช่องนี้ คุณสามารถติดตั้ง %s แทน %s และเปลี่ยนข้อมูลช่องบนหน้า 'อุปกรณ์'" @@ -4327,9 +4682,6 @@ msgstr "การวัดพื้นผิว" msgid "Calibrating the detection position of nozzle clumping" msgstr "การปรับเทียบตำแหน่งการตรวจจับการเกาะตัวของหัวฉีด" -msgid "Unknown" -msgstr "ไม่ทราบ" - msgid "Update successful." msgstr "อัปเดตสำเร็จ" @@ -4838,9 +5190,6 @@ msgstr "ตั้งค่าให้เหมาะสมที่สุด" msgid "Regroup filament" msgstr "จัดกลุ่มเส้นพลาสติกใหม่" -msgid "Wiki Guide" -msgstr "คู่มือวิกิ" - msgid "up to" msgstr "ขึ้นไป" @@ -4874,8 +5223,8 @@ msgstr "กระตุก (มม./วินาที)" msgid "Fan speed (%)" msgstr "ความเร็วพัดลม (%)" -msgid "Temperature (°C)" -msgstr "อุณหภูมิ (°C)" +msgid "Temperature (℃)" +msgstr "อุณหภูมิ (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "อัตราการไหลเชิงปริมาตร (มม.³/วินาที)" @@ -4892,9 +5241,6 @@ msgstr "การเปลี่ยนเส้นพลาสติก" msgid "Options" msgstr "ตัวเลือก" -msgid "Extruder" -msgstr "ชุดดันเส้น" - msgid "Cost" msgstr "ต้นทุน" @@ -4907,6 +5253,7 @@ msgstr "การเปลี่ยนแปลงเครื่องมือ msgid "Color change" msgstr "เปลี่ยนสี" +msgctxt "Noun" msgid "Print" msgstr "พิมพ์" @@ -5066,11 +5413,15 @@ msgstr "หลีกเลี่ยงบริเวณการสอบเท msgid "Align to Y axis" msgstr "จัดแนวตามแกน Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "กลับ" + +msgctxt "Camera View" msgid "Left" msgstr "ซ้าย" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "ขวา" @@ -5095,9 +5446,6 @@ msgstr "จัดเรียงวัตถุบนจานที่เลื msgid "Split to objects" msgstr "แยกเป็นวัตถุ" -msgid "Split to parts" -msgstr "แยกเป็นส่วนๆ" - msgid "Assembly View" msgstr "มุมมองการประกอบ" @@ -5393,6 +5741,10 @@ msgstr "พิมพ์ฐานพิมพ์" msgid "Export G-code file" msgstr "ส่งออกไฟล์ G-code" +msgctxt "Verb" +msgid "Print" +msgstr "พิมพ์" + msgid "Export plate sliced file" msgstr "ส่งออกไฟล์แผ่นสไลซ์บาง ๆ" @@ -5566,15 +5918,6 @@ msgstr "ส่งออกการกำหนดค่าปัจจุบั msgid "Export" msgstr "ส่งออก" -msgid "Sync Presets" -msgstr "ซิงค์พรีเซ็ต" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "ดึงและใช้ค่าที่ตั้งล่วงหน้าล่าสุดจาก OrcaCloud" - -msgid "You must be logged in to sync presets from cloud." -msgstr "คุณต้องเข้าสู่ระบบเพื่อซิงค์ค่าที่ตั้งล่วงหน้าจากคลาวด์" - msgid "Quit" msgstr "ออก" @@ -5689,6 +6032,15 @@ msgstr "มุมมอง" msgid "Preset Bundle" msgstr "ชุดที่ตั้งไว้ล่วงหน้า" +msgid "Sync Presets" +msgstr "ซิงค์พรีเซ็ต" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "ดึงและใช้ค่าที่ตั้งล่วงหน้าล่าสุดจาก OrcaCloud" + +msgid "You must be logged in to sync presets from cloud." +msgstr "คุณต้องเข้าสู่ระบบเพื่อซิงค์ค่าที่ตั้งล่วงหน้าจากคลาวด์" + msgid "Syncing presets from cloud…" msgstr "กำลังซิงค์ค่าที่ตั้งล่วงหน้าจากคลาวด์..." @@ -5805,6 +6157,9 @@ msgstr "ผลลัพธ์การส่งออก" msgid "Select profile to load:" msgstr "เลือกโปรไฟล์ที่จะโหลด:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -5970,9 +6325,6 @@ msgstr "ดาวน์โหลดไฟล์ที่เลือกจาก msgid "Batch manage files." msgstr "จัดการไฟล์เป็นกลุ่ม" -msgid "Refresh" -msgstr "รีเฟรช" - msgid "Reload file list from printer." msgstr "โหลดรายการไฟล์จากเครื่องพิมพ์อีกครั้ง" @@ -6278,6 +6630,9 @@ msgstr "ตัวเลือกพิมพ์" msgid "Safety Options" msgstr "ตัวเลือกความปลอดภัย" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "ไฟ" @@ -6311,6 +6666,12 @@ msgstr "เมื่อหยุดการพิมพ์ชั่วครา msgid "Current extruder is busy changing filament." msgstr "ปัจจุบันชุดดันเส้นกำลังยุ่งอยู่กับการเปลี่ยนเส้นพลาสติก" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "ช่องปัจจุบันถูกโหลดแล้ว" @@ -6359,9 +6720,6 @@ msgstr "ซึ่งจะมีผลเฉพาะระหว่างกา msgid "Silent" msgstr "เงียบ" -msgid "Standard" -msgstr "มาตรฐาน" - msgid "Sport" msgstr "สปอร์ต" @@ -6395,6 +6753,12 @@ msgstr "เพิ่มรูปภาพ" msgid "Delete Photo" msgstr "ลบรูปภาพ" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "ส่ง" @@ -6575,6 +6939,9 @@ msgstr "วิธีใช้โหมด LAN เท่านั้น" msgid "Don't show this dialog again" msgstr "อย่าแสดงกล่องโต้ตอบนี้อีก" +msgid "Please refer to Wiki before use->" +msgstr "โปรดดู Wiki ก่อนใช้งาน ->" + msgid "3D Mouse disconnected." msgstr "เมาส์ 3D ถูกตัดการเชื่อมต่อ" @@ -6818,27 +7185,18 @@ msgstr "อัตราการไหล" msgid "Please change the nozzle settings on the printer." msgstr "กรุณาเปลี่ยนการตั้งค่าหัวฉีดบนเครื่องพิมพ์" -msgid "Hardened Steel" -msgstr "เหล็กชุบแข็ง" - -msgid "Stainless Steel" -msgstr "สแตนเลส" - -msgid "Tungsten Carbide" -msgstr "ทังสเตนคาร์ไบด์" - msgid "Brass" msgstr "ทองเหลือง" msgid "High flow" msgstr "อัตราไหลสูง" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "ไม่มีลิงก์ wiki สำหรับเครื่องพิมพ์นี้" -msgid "Refreshing" -msgstr "สดชื่น" - msgid "Unavailable while heating maintenance function is on." msgstr "ไม่สามารถใช้งานได้ในขณะที่เปิดฟังก์ชันบำรุงรักษาเครื่องทำความร้อน" @@ -6961,6 +7319,15 @@ msgstr "สลับเส้นผ่านศูนย์กลาง" msgid "Configuration incompatible" msgstr "การกำหนดค่าเข้ากันไม่ได้" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "เคล็ดลับ" + msgid "Sync printer information" msgstr "ซิงค์ข้อมูลเครื่องพิมพ์" @@ -6989,6 +7356,9 @@ msgstr "คลิกเพื่อแก้ไขค่าที่ตั้ง msgid "Project Filaments" msgstr "เส้นพลาสติกโครงการ" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "ปริมาตรไล่เส้น" @@ -7204,9 +7574,6 @@ msgstr "เครื่องพิมพ์ที่เชื่อมต่อ msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "คุณต้องการซิงค์ข้อมูลเครื่องพิมพ์และสลับการตั้งค่าล่วงหน้าโดยอัตโนมัติหรือไม่" -msgid "Tips" -msgstr "เคล็ดลับ" - msgid "The file does not contain any geometry data." msgstr "ไฟล์นี้ไม่มีข้อมูลเรขาคณิตใดๆ" @@ -7254,9 +7621,21 @@ msgstr "" "การกระทำนี้จะตัดการติดต่อทางจดหมาย\n" "หลังจากนั้นจึงไม่สามารถรับประกันความสอดคล้องของโมเดลได้" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "ไม่สามารถแยกวัตถุที่เลือกได้" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "ปิดการใช้งานการวางอัตโนมัติเพื่อรักษาตำแหน่ง z หรือไม่\n" @@ -7281,6 +7660,9 @@ msgstr "เลือกไฟล์ใหม่" msgid "File for the replacement wasn't selected" msgstr "ไม่ได้เลือกไฟล์สำหรับการแทนที่" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "เลือกโฟลเดอร์ที่จะแทนที่" @@ -7327,6 +7709,9 @@ msgstr "ไม่สามารถโหลดซ้ำได้:" msgid "Error during reload" msgstr "เกิดข้อผิดพลาดระหว่างการโหลดซ้ำ" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "มีคำเตือนหลังจากการแบ่งโมเดล:" @@ -8082,6 +8467,15 @@ msgstr "ล้างตัวเลือกของฉันในการซ msgid "Graphics" msgstr "กราฟิก" +msgid "Smooth normals" +msgstr "นอร์มัลแบบเรียบ" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "การแรเงาแบบ Phong" @@ -8097,20 +8491,8 @@ msgstr "ใช้ SSAO ในมุมมองแบบสมจริง" msgid "Shadows" msgstr "เงา" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "แสดงเงาแบบทอดบนเพลตในมุมมองแบบสมจริง" - -msgid "Smooth normals" -msgstr "นอร์มัลแบบเรียบ" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"ใช้นอร์มัลแบบเรียบในมุมมองแบบสมจริง\n" -"\n" -"ต้องโหลดฉากใหม่ด้วยตนเองจึงจะมีผล (คลิกขวาที่มุมมอง 3D → \"Reload All\")." msgid "Anti-aliasing" msgstr "ต่อต้านนามแฝง" @@ -8400,6 +8782,9 @@ msgstr "ค่าที่ตั้งล่วงหน้าที่เข้ msgid "My Printer" msgstr "เครื่องพิมพ์ของฉัน" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "เส้นพลาสติกด้านซ้าย" @@ -8418,6 +8803,9 @@ msgstr "เพิ่ม/ลบค่าที่ตั้งล่วงหน msgid "Edit preset" msgstr "พรีเซ็ตแก้ไข" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "ไม่ระบุ" @@ -8448,9 +8836,6 @@ msgstr "เลือก/ลบเครื่องพิมพ์ (ค่าท msgid "Create printer" msgstr "สร้างเครื่องพิมพ์" -msgid "Empty" -msgstr "ว่างเปล่า" - msgid "Incompatible" msgstr "เข้ากันไม่ได้" @@ -8679,12 +9064,42 @@ msgstr "ส่งเสร็จแล้ว" msgid "Error code" msgstr "รหัสข้อผิดพลาด" -msgid "High Flow" -msgstr "อัตราไหลสูง" +msgid "Error desc" +msgstr "คำอธิบายข้อผิดพลาด" + +msgid "Extra info" +msgstr "ข้อมูลเพิ่มเติม" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "การตั้งค่าการไหลของหัวฉีดของ %s(%s) ไม่ตรงกับไฟล์การแบ่งส่วน (%s) โปรดตรวจสอบให้แน่ใจว่าหัวฉีดที่ติดตั้งตรงกับการตั้งค่าในเครื่องพิมพ์ จากนั้นตั้งค่าเครื่องพิมพ์ล่วงหน้าที่เกี่ยวข้องขณะสไลซ์" +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8746,8 +9161,38 @@ msgstr "ราคา %dg เส้นพลาสติกและ %d เปล msgid "nozzle" msgstr "หัวฉีด" -msgid "both extruders" -msgstr "ชุดดันเส้นทั้งสอง" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "การตั้งค่าการไหลของหัวฉีดของ %s(%s) ไม่ตรงกับไฟล์การแบ่งส่วน (%s) โปรดตรวจสอบให้แน่ใจว่าหัวฉีดที่ติดตั้งตรงกับการตั้งค่าในเครื่องพิมพ์ จากนั้นตั้งค่าเครื่องพิมพ์ล่วงหน้าที่เกี่ยวข้องขณะสไลซ์" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "เคล็ดลับ: หากคุณเปลี่ยนหัวฉีดของเครื่องพิมพ์เมื่อเร็วๆ นี้ โปรดไปที่ 'อุปกรณ์ -> ชิ้นส่วนเครื่องพิมพ์' เพื่อเปลี่ยนการตั้งค่าหัวฉีดของคุณ" @@ -8760,10 +9205,17 @@ msgstr "เส้นผ่านศูนย์กลาง %s(%.1fmm) ของ msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "เส้นผ่านศูนย์กลางหัวฉีดปัจจุบัน (%.1fmm) ไม่ตรงกับไฟล์การแบ่งส่วน (%.1fmm) โปรดตรวจสอบให้แน่ใจว่าหัวฉีดที่ติดตั้งตรงกับการตั้งค่าในเครื่องพิมพ์ จากนั้นตั้งค่าเครื่องพิมพ์ล่วงหน้าที่เกี่ยวข้องเมื่อสไลซ์" +msgid "both extruders" +msgstr "ชุดดันเส้นทั้งสอง" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "ความแข็งของวัสดุปัจจุบัน (%s) เกินความแข็งของ %s(%s) โปรดตรวจสอบการตั้งค่าหัวฉีดหรือวัสดุแล้วลองอีกครั้ง" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] จำเป็นต้องพิมพ์ในสภาพแวดล้อมที่มีอุณหภูมิสูง กรุณาปิดประตู." @@ -8873,9 +9325,6 @@ msgstr "เฟิร์มแวร์ปัจจุบันรองรับ msgid "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." msgstr "ไม่ทราบประเภทของเส้นพลาสติกภายนอกหรือไม่ตรงกับประเภทเส้นพลาสติกในไฟล์สไลซ์ โปรดตรวจสอบให้แน่ใจว่าคุณได้ติดตั้งเส้นพลาสติกที่ถูกต้องในแกนม้วนสายภายนอก" -msgid "Please refer to Wiki before use->" -msgstr "โปรดดู Wiki ก่อนใช้งาน ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "เฟิร์มแวร์ปัจจุบันไม่รองรับการถ่ายโอนไฟล์ไปยังที่จัดเก็บข้อมูลภายใน" @@ -9054,6 +9503,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "คลิกเพื่อรีเซ็ตการตั้งค่าทั้งหมดเป็นค่าที่ตั้งไว้ล่วงหน้าที่บันทึกไว้ล่าสุด" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "โหมดไทม์แลปส์แบบราบรื่นต้องใช้ไพรม์ทาวเวอร์ หากไม่มีไพรม์ทาวเวอร์อาจเกิดตำหนิบนโมเดลได้ คุณแน่ใจหรือไม่ว่าต้องการปิดไพรม์ทาวเวอร์?" @@ -9132,9 +9584,6 @@ msgstr "ปรับเป็นช่วงที่ตั้งไว้อั msgid "Adjust" msgstr "ปรับ" -msgid "Ignore" -msgstr "ละเว้น" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "คุณลักษณะการทดลอง: การดึงกลับและตัดเส้นพลาสติกออกในระยะห่างที่มากขึ้นระหว่างการเปลี่ยนเส้นพลาสติกเพื่อลดการไล่เส้น แม้ว่าจะสามารถลดการไล่เส้นได้อย่างเห็นได้ชัด แต่ก็อาจเพิ่มความเสี่ยงของการอุดตันของหัวฉีดหรือภาวะแทรกซ้อนในการพิมพ์อื่นๆ อีกด้วย" @@ -9625,6 +10074,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "คุณแน่ใจหรือไม่ว่าต้องการ %1% ค่าที่ตั้งไว้ล่วงหน้าที่เลือก?" +msgid "Select printers" +msgstr "เลือกเครื่องพิมพ์" + +msgid "Select profiles" +msgstr "โปรไฟล์เลือก" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9868,6 +10323,12 @@ msgstr "โอนค่าจากซ้ายไปขวา" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "หากเปิดใช้งาน กล่องโต้ตอบนี้สามารถใช้เพื่อโอนค่าที่เลือกจากค่าที่ตั้งไว้ล่วงหน้าจากซ้ายไปขวาได้" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "เพิ่มไฟล์" @@ -10123,12 +10584,8 @@ msgstr "ซิงโครไนซ์ข้อมูลหัวฉีดสำ msgid "Successfully synchronized nozzle and AMS number information." msgstr "ซิงโครไนซ์ข้อมูลหัวฉีดและหมายเลข AMS เรียบร้อยแล้ว" -msgid "Continue to sync filaments" -msgstr "ทำการซิงค์ฟิลาเมนต์ต่อไป" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "ยกเลิก" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "ซิงโครไนซ์สีฟิลาเมนต์จากเครื่องพิมพ์สำเร็จแล้ว" @@ -10236,6 +10693,9 @@ msgstr "เข้าสู่ระบบ" msgid "Login failed. Please try again." msgstr "การเข้าสู่ระบบล้มเหลว โปรดลองอีกครั้ง" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[ต้องดำเนินการ]" @@ -10542,6 +11002,9 @@ msgstr "ชื่อเครื่องพิมพ์" msgid "Where to find your printer's IP and Access Code?" msgstr "จะค้นหา IP และรหัสการเข้าถึงเครื่องพิมพ์ของคุณได้ที่ไหน" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "เชื่อมต่อ" @@ -10606,6 +11069,9 @@ msgstr "โมดูลการตัด" msgid "Auto Fire Extinguishing System" msgstr "ระบบดับเพลิงอัตโนมัติ" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10624,6 +11090,9 @@ msgstr "การอัปเดตล้มเหลว" msgid "Update successful" msgstr "อัปเดตสำเร็จ" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "คุณแน่ใจหรือไม่ว่าต้องการอัปเดต การดำเนินการนี้จะใช้เวลาประมาณ 10 นาที อย่าปิดเครื่องในขณะที่เครื่องพิมพ์กำลังอัปเดต" @@ -10725,6 +11194,9 @@ msgstr "ข้อผิดพลาดในการจัดกลุ่ม:" msgid " can not be placed in the " msgstr "ไม่สามารถวางใน" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "สะพานภายใน" @@ -11400,19 +11872,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"แทนที่มุมสะพานด้านนอก\n" -"หากปล่อยเป็นศูนย์ มุมสะพานจะคำนวณอัตโนมัติสำหรับสะพานแต่ละจุด\n" -"มิฉะนั้นจะใช้มุมที่กำหนดตาม:\n" -" - พิกัดสัมบูรณ์\n" -" - พิกัดสัมบูรณ์ + การหมุนโมเดล: หากเปิดใช้งานจัดทิศทางไส้ในให้สอดคล้องกับโมเดล\n" -" - มุมอัตโนมัติที่เหมาะสม + ค่านี้: หากเปิดใช้งาน 'มุมสะพานแบบสัมพันธ์'\n" -"\n" -"ใช้ 180° สำหรับมุมสัมบูรณ์ศูนย์" msgid "Internal bridge infill direction" msgstr "ทิศทางไส้ในสะพานภายใน" @@ -11422,19 +11886,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"แทนที่มุมสะพานด้านใน\n" -"หากปล่อยเป็นศูนย์ มุมสะพานจะคำนวณอัตโนมัติสำหรับสะพานแต่ละจุด\n" -"มิฉะนั้นจะใช้มุมที่กำหนดตาม:\n" -" - พิกัดสัมบูรณ์\n" -" - พิกัดสัมบูรณ์ + การหมุนโมเดล: หากเปิดใช้งานจัดทิศทางไส้ในให้สอดคล้องกับโมเดล\n" -" - มุมอัตโนมัติที่เหมาะสม + ค่านี้: หากเปิดใช้งาน 'มุมสะพานแบบสัมพันธ์'\n" -"\n" -"ใช้ 180° สำหรับมุมสัมบูรณ์ศูนย์" msgid "Relative bridge angle" msgstr "มุมสะพานแบบสัมพันธ์" @@ -11924,9 +12380,6 @@ msgstr "" "รูปทรงจะถูกทำลายก่อนที่จะตรวจจับมุมแหลม พารามิเตอร์นี้ระบุความยาวขั้นต่ำของการเบี่ยงเบนสำหรับการทำลาย\n" "0 เพื่อปิดการใช้งาน" -msgid "Select printers" -msgstr "เลือกเครื่องพิมพ์" - msgid "upward compatible machine" msgstr "เครื่องที่รองรับขึ้นไป" @@ -11936,9 +12389,6 @@ msgstr "เงื่อนไข" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "นิพจน์บูลีนที่ใช้ค่าการกำหนดค่าของโปรไฟล์เครื่องพิมพ์ที่ใช้งานอยู่ หากนิพจน์นี้ประเมินว่าเป็นจริง โปรไฟล์นี้จะถือว่าเข้ากันได้กับโปรไฟล์เครื่องพิมพ์ที่ใช้งานอยู่" -msgid "Select profiles" -msgstr "โปรไฟล์เลือก" - msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "นิพจน์บูลีนที่ใช้ค่าการกำหนดค่าของโปรไฟล์การพิมพ์ที่ใช้งานอยู่ หากนิพจน์นี้ประเมินว่าเป็นจริง โปรไฟล์นี้จะถือว่าเข้ากันได้กับโปรไฟล์การพิมพ์ที่ใช้งานอยู่" @@ -12204,6 +12654,42 @@ msgstr "ความหนาแน่นผิวด้านบน" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "ความหนาแน่นของชั้นผิวด้านบน ค่า 100% จะสร้างชั้นบนสุดที่เรียบและแข็งเต็มที่ การลดค่านี้ส่งผลให้พื้นผิวด้านบนมีพื้นผิวตามรูปแบบพื้นผิวด้านบนที่เลือก ค่า 0% จะส่งผลให้มีการสร้างเฉพาะผนังชั้นบนสุดเท่านั้น มีวัตถุประสงค์เพื่อความสวยงามหรือการใช้งาน ไม่ใช่เพื่อแก้ไขปัญหา เช่น การอัดขึ้นรูปมากเกินไป" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "รูปแบบผิวด้านล่าง" @@ -12527,12 +13013,18 @@ msgstr "อัตโนมัติสำหรับไล่เส้น" msgid "Auto For Match" msgstr "อัตโนมัติสำหรับการแข่งขัน" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "อุณหภูมิไล่เส้น" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "อุณหภูมิเมื่อทำการล้างเส้นพลาสติก 0 หมายถึงขอบเขตบนของช่วงอุณหภูมิหัวฉีดที่แนะนำ" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "ความเร็วเชิงปริมาตรไล่เส้น" @@ -12795,6 +13287,12 @@ msgstr "พิมพ์เส้นพลาสติกได้" msgid "The filament is printable in extruder." msgstr "เส้นพลาสติกสามารถพิมพ์ได้ในชุดดันเส้น" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "อุณหภูมิอ่อนลง" @@ -12854,15 +13352,13 @@ msgstr "ความหนาแน่นไส้ในแบบโปร่ง msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "ความหนาแน่นของไส้ในแบบโปร่งภายใน 100% จะเปลี่ยนไส้ในแบบโปร่งทั้งหมดให้เป็นไส้ในแบบทึบ และจะใช้รูปแบบไส้ในแบบทึบภายใน" -msgid "Align infill direction to model" -msgstr "จัดทิศทาง ไส้ใน ให้ตรงกับโมเดล" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"จัดทิศทางไส้ใน สะพาน การรีดเรียบ และการเติมผิวให้สอดคล้องกับการวางแนวของโมเดลบนฐานรองพิมพ์\n" -"เมื่อเปิดใช้งาน ทิศทางจะหมุนตามโมเดลเพื่อรักษาคุณสมบัติความแข็งแรงที่เหมาะสม" msgid "Insert solid layers" msgstr "แทรกชั้นทึบ" @@ -13382,6 +13878,15 @@ msgstr "ตำแหน่งการจัดเรียงอัตโนม msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "เปิดใช้งานตัวเลือกนี้หากเครื่องมีพัดลมระบายความร้อนชิ้นส่วนเสริม คำสั่งรหัส G: M106 P2 S(0-255)" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13455,6 +13960,12 @@ msgstr "" "เปิดใช้งานสิ่งนี้หากเครื่องพิมพ์รองรับการกรองอากาศ\n" "คำสั่งรหัส G: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "รสจีโค้ด" @@ -13976,6 +14487,30 @@ msgstr "ความเร็วในการเดินทางขั้น msgid "Minimum travel speed (M205 T)" msgstr "ความเร็วในการเดินทางขั้นต่ำ (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "ความเร่งสูงสุดสำหรับการอัดขึ้นรูป" @@ -14528,6 +15063,9 @@ msgstr "ขับตรง" msgid "Bowden" msgstr "โบว์เดน" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "เปิดใช้งานแผนที่ไดนามิกของเส้นพลาสติก" @@ -14561,6 +15099,12 @@ msgstr "ความเร็วในการถอนกลับ" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "ความเร็วในการบรรจุเส้นพลาสติกลงในหัวฉีด ศูนย์หมายถึงความเร็วการถอยกลับเท่ากัน" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "ใช้การเพิกถอนเฟิร์มแวร์" @@ -14591,6 +15135,9 @@ msgstr "จัดตำแหน่ง" msgid "Aligned back" msgstr "จัดแนวกลับ" +msgid "Back" +msgstr "กลับ" + msgid "Random" msgstr "สุ่ม" @@ -14863,6 +15410,12 @@ msgstr "หากเลือกโหมดเรียบหรือโหม msgid "Traditional" msgstr "แบบดั้งเดิม" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "การเปลี่ยนแปลงของอุณหภูมิ" @@ -14948,6 +15501,18 @@ msgstr "ใช้ชุดดันเส้นการพิมพ์ทั้ msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "หากเปิดใช้งาน ชุดดันเส้นการพิมพ์ทั้งหมดจะถูกลงสีพื้นที่ขอบด้านหน้าของฐานพิมพ์เมื่อเริ่มต้นการพิมพ์" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "รัศมีการปิดช่องว่างของ Slice" @@ -15322,7 +15887,7 @@ msgstr "" "หากเปิดใช้งาน พารามิเตอร์นี้จะตั้งค่าตัวแปร G-code ชื่อ Chamber_temperature ซึ่งสามารถใช้เพื่อส่งอุณหภูมิห้องเพาะเลี้ยงที่ต้องการไปยังมาโครเริ่มการพิมพ์ของคุณ หรือมาโครความร้อนแช่เช่นนี้: PRINT_START (ตัวแปรอื่นๆ) CHAMBER_TEMP=[chamber_temperature] วิธีนี้อาจเป็นประโยชน์หากเครื่องพิมพ์ของคุณไม่รองรับคำสั่ง M141/M191 หรือหากคุณต้องการจัดการกับความร้อนที่แช่อยู่ในมาโครเริ่มการพิมพ์ หากไม่มีการติดตั้งเครื่องทำความร้อนในห้องที่ใช้งานอยู่" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15371,6 +15936,45 @@ msgstr "ความหนาผนังด้านบน" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "จำนวนชั้นทึบด้านบนจะเพิ่มขึ้นเมื่อสไลซ์หากความหนาที่คำนวณโดยชั้นเปลือกด้านบนบางกว่าค่านี้ วิธีนี้สามารถหลีกเลี่ยงไม่ให้เปลือกบางเกินไปเมื่อชั้นมีความสูงน้อย 0 หมายความว่าการตั้งค่านี้ถูกปิดใช้งาน และความหนาของเปลือกด้านบนถูกกำหนดโดยชั้นเปลือกด้านบนอย่างแน่นอน" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + msgid "This is the speed at which traveling is done." msgstr "ความเร็วที่ใช้ในการเคลื่อนที่แบบไม่อัดเส้น" @@ -15414,12 +16018,30 @@ msgstr "ตัวคูณการไล่เส้น" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "ปริมาตรการไล่เส้นตามจริงจะเท่ากับตัวคูณการไล่เส้นคูณด้วยปริมาตรการไล่เส้นในตาราง" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "ปริมาณเฉพาะ" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "ปริมาตรวัสดุสำหรับเตรียมหัวฉีดบนไพรม์ทาวเวอร์" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + msgid "This is the width of prime towers." msgstr "ความกว้างของไพรม์ทาวเวอร์" @@ -15705,6 +16327,57 @@ msgstr "ความกว้างของผนังขั้นต่ำ" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "ความกว้างของผนังที่จะมาแทนที่คุณสมบัติบาง (ตามขนาดคุณสมบัติขั้นต่ำ) ของแบบจำลอง หากความกว้างของผนังขั้นต่ำบางกว่าความหนาของคุณสมบัติ ผนังจะหนาเท่ากับคุณสมบัตินั้นเอง โดยแสดงเป็นเปอร์เซ็นต์ของเส้นผ่านศูนย์กลางของหัวฉีด" +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "ตรวจจับไส้ในของแข็งภายในที่แคบ" @@ -16445,12 +17118,6 @@ msgstr "" msgid "Calibration not supported" msgstr "ไม่รองรับการปรับเทียบ" -msgid "Error desc" -msgstr "คำอธิบายข้อผิดพลาด" - -msgid "Extra info" -msgstr "ข้อมูลเพิ่มเติม" - msgid "Flow Dynamics" msgstr "ไดนามิกการไหล" @@ -16653,6 +17320,12 @@ msgstr "กรุณากรอกชื่อที่คุณต้องก msgid "The name cannot exceed 40 characters." msgstr "ชื่อต้องมีความยาวไม่เกิน 40 ตัวอักษร" +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "โปรดค้นหาเส้นที่ดีที่สุดบนจานของคุณ" @@ -16742,9 +17415,6 @@ msgstr "ข้อมูล AMS และหัวฉีดจะซิงค์ msgid "Nozzle Flow" msgstr "การไหลของหัวฉีด" -msgid "Nozzle Info" -msgstr "ข้อมูลหัวฉีด" - msgid "Filament position" msgstr "ตำแหน่งเส้นพลาสติก" @@ -16818,6 +17488,10 @@ msgstr "ประสบความสำเร็จในการรับผ msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "การรีเฟรชบันทึกการปรับเทียบ Flow Dynamics ในอดีต" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "การทำงาน" @@ -18558,6 +19232,12 @@ msgstr "พิมพ์ล้มเหลว" msgid "Removed" msgstr "ลบออก" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "ไม่ต้องเตือนฉันอีก" @@ -18591,12 +19271,25 @@ msgstr "วิดีโอสอน" msgid "(Sync with printer)" msgstr "(ซิงค์กับเครื่องพิมพ์)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "เราจะสไลซ์ตามวิธีการจัดกลุ่มนี้:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "เคล็ดลับ: คุณสามารถลากเส้นพลาสติกเพื่อกำหนดใหม่ให้กับหัวฉีดที่แตกต่างกันได้" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "วิธีการจัดกลุ่มเส้นพลาสติกสำหรับเพลตปัจจุบันถูกกำหนดโดยตัวเลือกแบบเลื่อนลงที่ปุ่มแผ่นสไลซ์" @@ -18828,9 +19521,6 @@ msgstr "การทำงานนี้ไม่สามารถย้อน msgid "Skipping objects." msgstr "ข้ามวัตถุ" -msgid "Select Filament" -msgstr "เลือกเส้นพลาสติก" - msgid "Null Color" msgstr "สีว่าง" @@ -19345,6 +20035,77 @@ msgstr "" "หลีกเลี่ยงการบิดเบี้ยว\n" "คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "แสดงเงาแบบทอดบนเพลตในมุมมองแบบสมจริง" + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "ใช้นอร์มัลแบบเรียบในมุมมองแบบสมจริง\n" +#~ "\n" +#~ "ต้องโหลดฉากใหม่ด้วยตนเองจึงจะมีผล (คลิกขวาที่มุมมอง 3D → \"Reload All\")." + +#~ msgid "Continue to sync filaments" +#~ msgstr "ทำการซิงค์ฟิลาเมนต์ต่อไป" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "ยกเลิก" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "แทนที่มุมสะพานด้านนอก\n" +#~ "หากปล่อยเป็นศูนย์ มุมสะพานจะคำนวณอัตโนมัติสำหรับสะพานแต่ละจุด\n" +#~ "มิฉะนั้นจะใช้มุมที่กำหนดตาม:\n" +#~ " - พิกัดสัมบูรณ์\n" +#~ " - พิกัดสัมบูรณ์ + การหมุนโมเดล: หากเปิดใช้งานจัดทิศทางไส้ในให้สอดคล้องกับโมเดล\n" +#~ " - มุมอัตโนมัติที่เหมาะสม + ค่านี้: หากเปิดใช้งาน 'มุมสะพานแบบสัมพันธ์'\n" +#~ "\n" +#~ "ใช้ 180° สำหรับมุมสัมบูรณ์ศูนย์" + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "แทนที่มุมสะพานด้านใน\n" +#~ "หากปล่อยเป็นศูนย์ มุมสะพานจะคำนวณอัตโนมัติสำหรับสะพานแต่ละจุด\n" +#~ "มิฉะนั้นจะใช้มุมที่กำหนดตาม:\n" +#~ " - พิกัดสัมบูรณ์\n" +#~ " - พิกัดสัมบูรณ์ + การหมุนโมเดล: หากเปิดใช้งานจัดทิศทางไส้ในให้สอดคล้องกับโมเดล\n" +#~ " - มุมอัตโนมัติที่เหมาะสม + ค่านี้: หากเปิดใช้งาน 'มุมสะพานแบบสัมพันธ์'\n" +#~ "\n" +#~ "ใช้ 180° สำหรับมุมสัมบูรณ์ศูนย์" + +#~ msgid "Align infill direction to model" +#~ msgstr "จัดทิศทาง ไส้ใน ให้ตรงกับโมเดล" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "จัดทิศทางไส้ใน สะพาน การรีดเรียบ และการเติมผิวให้สอดคล้องกับการวางแนวของโมเดลบนฐานรองพิมพ์\n" +#~ "เมื่อเปิดใช้งาน ทิศทางจะหมุนตามโมเดลเพื่อรักษาคุณสมบัติความแข็งแรงที่เหมาะสม" + +#~ msgid "Print" +#~ msgstr "พิมพ์" + #~ msgid "in" #~ msgstr "นิ้ว" diff --git a/localization/i18n/tr/OrcaSlicer_tr.po b/localization/i18n/tr/OrcaSlicer_tr.po index d879d550c5..c5d91ffbf9 100644 --- a/localization/i18n/tr/OrcaSlicer_tr.po +++ b/localization/i18n/tr/OrcaSlicer_tr.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-04-08 23:59+0300\n" "Last-Translator: GlauTech\n" "Language-Team: \n" @@ -35,6 +35,24 @@ msgstr "TPU, AMS tarafından desteklenmez." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS, 'Bambu Lab PET-CF'yi desteklemez." +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "Tıkanmayı önlemek için lütfen TPU'yu yazdırmadan önce soğuk çekin. Yazıcıda soğuk çekme bakımını kullanabilirsiniz." @@ -47,6 +65,9 @@ msgstr "Nemli PVA esnektir ve ekstrüderde sıkışabilir. Kullanmadan önce kur msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "PLA Glow'un pürüzlü yüzeyi, AMS sistemindeki, özellikle de AMS Lite'ın dahili bileşenlerindeki aşınmayı hızlandırabilir." +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF filamentleri sert ve kırılgandır. AMS'de kırılması veya sıkışması kolaydır, lütfen dikkatli kullanın." @@ -56,10 +77,90 @@ msgstr "PPS-CF kırılgandır ve Takım Başlığının üzerindeki bükülmüş msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF kırılgandır ve Alet Başlığının üzerindeki bükülmüş PTFE tüpünde kırılabilir." +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s, %s ekstruder tarafından desteklenmiyor." +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "Yüksek Akış" + +msgid "Standard" +msgstr "Standart" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Bilinmeyen" + +msgid "Hardened Steel" +msgstr "Güçlendirilmiş çelik" + +msgid "Stainless Steel" +msgstr "Paslanmaz çelik" + +msgid "Tungsten Carbide" +msgstr "Tungsten Karbür" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Uyarı" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "Mevcut AMS nemi" @@ -90,6 +191,85 @@ msgstr "Sürüm:" msgid "Latest version" msgstr "Son sürüm" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Boş" + +msgid "Error" +msgstr "Hata" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Yenile" + +msgid "Refreshing" +msgstr "Canlandırıcı" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "İptal" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Sürüm" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Destek boyama" @@ -162,6 +342,12 @@ msgstr "Doldur" msgid "Gap Fill" msgstr "Boşluk doldurma" +msgid "Vertical" +msgstr "Dikey" + +msgid "Horizontal" +msgstr "Yatay" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Yalnızca şu kişi tarafından seçilen yüzeylerde boyamaya izin verir: \"%1%\"" @@ -257,12 +443,6 @@ msgstr "Üçgen" msgid "Height Range" msgstr "Yükseklik Aralığı" -msgid "Vertical" -msgstr "Dikey" - -msgid "Horizontal" -msgstr "Yatay" - msgid "Remove painted color" msgstr "Boyalı rengi kaldır" @@ -327,6 +507,7 @@ msgstr "Gizmo-Döndür" msgid "Optimize orientation" msgstr "Yönü optimize edin" +msgctxt "Verb" msgid "Scale" msgstr "Ölçeklendir" @@ -371,6 +552,9 @@ msgstr "Ölçek oranları" msgid "Object operations" msgstr "Nesne İşlemleri" +msgid "Scale" +msgstr "Ölçeklendir" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Hacim İşlemleri" @@ -422,6 +606,10 @@ msgstr "Döndürme aracını açtığınızda mevcut döndürme değerini sıfı msgid "Reset current rotation to real zeros." msgstr "Mevcut dönüşü gerçek sıfırlara sıfırla." +msgctxt "Noun" +msgid "Scale" +msgstr "Ölçeklendir" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Boyut" @@ -604,9 +792,6 @@ msgstr "Yarıçapla ilgili alan oranı" msgid "Confirm connectors" msgstr "Bağlayıcıları onayla" -msgid "Cancel" -msgstr "İptal" - msgid "Flip cut plane" msgstr "Kesim düzlemini çevir" @@ -647,12 +832,12 @@ msgstr "Parçalara ayır" msgid "Reset cutting plane and remove connectors" msgstr "Kesme düzlemini sıfırlayın ve bağlayıcıları çıkarın" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Kesimi gerçekleştir" -msgid "Warning" -msgstr "Uyarı" - msgid "Invalid connectors detected" msgstr "Geçersiz bağlayıcılar algılandı" @@ -683,6 +868,13 @@ msgstr "Oluklu kesme düzlemi geçersiz" msgid "Connector" msgstr "Bağlayıcı" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Düzlemsel Kes" @@ -730,9 +922,6 @@ msgstr "Sadeleştir" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Sadeleştirmeye şu anda yalnızca tek bir parça seçildiğinde izin veriliyor" -msgid "Error" -msgstr "Hata" - msgid "Extra high" msgstr "Ekstra yüksek" @@ -2004,6 +2193,9 @@ msgstr "" msgid "Loading user preset" msgstr "Kullanıcı ön ayarı yükleniyor" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2017,6 +2209,18 @@ msgstr "Dili seçin" msgid "Language" msgstr "Dil" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2650,6 +2854,45 @@ msgstr "Nesnenin renk resmini düzenlemek için simgeye tıklayın" msgid "Click the icon to shift this object to the bed" msgstr "Bu nesneyi yatağa taşımak için simgeye tıklayın" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Dosya yükleniyor" @@ -2659,6 +2902,9 @@ msgstr "Hata!" msgid "Failed to get the model data in the current file." msgstr "Geçerli dosyadaki model verileri alınamadı." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Genel" @@ -2671,6 +2917,12 @@ msgstr "Seçilen nesnelerin işlem ayarlarını düzenlemek için nesne başına msgid "Remove paint-on fuzzy skin" msgstr "Boyalı pütürlü yüzeyi çıkarın" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Yükseklik aralığını kaldır" + msgid "Delete connector from object which is a part of cut" msgstr "Kesilen parçanın parçası olan nesneden bağlayıcıyı sil" @@ -2701,12 +2953,24 @@ msgstr "Tüm bağlayıcıları sil" msgid "Deleting the last solid part is not allowed." msgstr "Son katı kısmın silinmesine izin verilmez." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Hedef nesne yalnızca bir parçadan oluşur ve bölünemez." +msgid "Split to parts" +msgstr "Parçalara bölme" + msgid "Assembly" msgstr "Birleştir" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Kesim Konnektörleri bilgileri" @@ -2740,6 +3004,9 @@ msgstr "Yükseklik aralıkları" msgid "Settings for height range" msgstr "Yükseklik aralığı ayarları" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Katman" @@ -2762,6 +3029,9 @@ msgstr "Tip:" msgid "Choose part type" msgstr "Parça tipini seçin" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Yeni adı girin" @@ -2789,6 +3059,9 @@ msgstr "Bu alt bölümden sonra \"%s\" 1 milyon yüzü aşacak ve bu da dilimlem msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "\"%s\" bölümünün ağı hatalar içeriyor. Lütfen önce onu onarın." +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Ek işlem ön ayarı" @@ -2798,9 +3071,6 @@ msgstr "Parametreyi kaldır" msgid "to" msgstr "ile" -msgid "Remove height range" -msgstr "Yükseklik aralığını kaldır" - msgid "Add height range" msgstr "Yükseklik aralığı ekle" @@ -3011,6 +3281,9 @@ msgstr "Bir AMS yuvası seçin ve filamentleri otomatik olarak yüklemek veya bo msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "Bu eylemi gerçekleştirmek için gereken filaman türü bilinmiyor. Lütfen hedef filamanın bilgilerini ayarlayın." +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "Yazdırma sırasında fan hızının değiştirilmesi baskı kalitesini etkileyebilir, lütfen seçiminizi dikkatli yapın." @@ -3133,6 +3406,24 @@ msgstr "Filamentin ekstrude edildiğini onayla" msgid "Check filament location" msgstr "Filament konumunu kontrol et" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "Maksimum sıcaklık aşılamaz" @@ -3186,6 +3477,62 @@ msgstr "Geliştirici Modu" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Onayla" + +msgid "Extruder" +msgstr "Ekstruder" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "Nozul Bilgisi" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Atla" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3519,15 +3866,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Sürüm" - msgid "AMS Materials Setting" msgstr "AMS Malzeme Ayarı" -msgid "Confirm" -msgstr "Onayla" - msgid "Close" msgstr "Kapat" @@ -3548,12 +3889,12 @@ msgstr "minimum" msgid "The input value should be greater than %1% and less than %2%" msgstr "Giriş değeri %1%'den büyük ve %2%'den küçük olmalıdır" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Akış Dinamiği Kalibrasyonunun Faktörleri" +msgid "Wiki Guide" +msgstr "Viki Kılavuzu" + msgid "PA Profile" msgstr "PA Profili" @@ -3644,7 +3985,7 @@ msgstr "Kalibrasyon tamamlandı. Lütfen sıcak yatağınızdaki en düzgün eks msgid "Save" msgstr "Kaydet" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Arka" @@ -3728,6 +4069,19 @@ msgstr "Sağ Nozul" msgid "Nozzle" msgstr "Nozul" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "Filament Seçin" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "Not: filament türü(%s), dilimleme dosyasındaki filament türü(%s) ile eşleşmiyor. Bu slotu kullanmak istiyorsanız %s yerine %s yükleyebilir ve 'Cihaz' sayfasında slot bilgilerini değiştirebilirsiniz." @@ -4440,9 +4794,6 @@ msgstr "Ölçüm Yüzeyi" msgid "Calibrating the detection position of nozzle clumping" msgstr "Meme topaklanmasının algılama konumunu kalibre etme" -msgid "Unknown" -msgstr "Bilinmeyen" - msgid "Update successful." msgstr "Güncelleme başarılı." @@ -4954,9 +5305,6 @@ msgstr "Optimum'a Ayarla" msgid "Regroup filament" msgstr "Filamenti yeniden gruplandır" -msgid "Wiki Guide" -msgstr "Viki Kılavuzu" - msgid "up to" msgstr "kadar" @@ -4993,8 +5341,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Fan hızı (%)" -msgid "Temperature (°C)" -msgstr "Sıcaklık (°C)" +msgid "Temperature (℃)" +msgstr "Sıcaklık (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Hacimsel akış hızı (mm³/s)" @@ -5012,9 +5360,6 @@ msgstr "Filament değişiklikleri" msgid "Options" msgstr "Seçenekler" -msgid "Extruder" -msgstr "Ekstruder" - msgid "Cost" msgstr "Maliyet" @@ -5027,6 +5372,7 @@ msgstr "Takım değişiklikleri" msgid "Color change" msgstr "Renk değişimi" +msgctxt "Noun" msgid "Print" msgstr "Yazdır" @@ -5190,11 +5536,15 @@ msgstr "Ekstrüzyon kalibrasyon bölgesinden kaçın" msgid "Align to Y axis" msgstr "Y eksenine hizala" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Arka" + +msgctxt "Camera View" msgid "Left" msgstr "Sol" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Sağ" @@ -5219,9 +5569,6 @@ msgstr "Seçilen plakalardaki nesneleri hizala" msgid "Split to objects" msgstr "Nesnelere böl" -msgid "Split to parts" -msgstr "Parçalara bölme" - msgid "Assembly View" msgstr "Montaj görünümü" @@ -5522,6 +5869,10 @@ msgstr "Plakayı Yazdır" msgid "Export G-code file" msgstr "G-kod dosyasını dışa aktar" +msgctxt "Verb" +msgid "Print" +msgstr "Yazdır" + msgid "Export plate sliced file" msgstr "Dilimlenmiş plaka dosyasını dışa aktar" @@ -5695,15 +6046,6 @@ msgstr "Geçerli yapılandırmayı dosyalara aktar" msgid "Export" msgstr "Dışa Aktar" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Çıkış" @@ -5820,6 +6162,15 @@ msgstr "Görünüm" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5940,6 +6291,9 @@ msgstr "Sonucu dışa aktar" msgid "Select profile to load:" msgstr "Yüklenecek profili seç:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6103,9 +6457,6 @@ msgstr "Seçilen dosyaları yazıcıdan indirin." msgid "Batch manage files." msgstr "Dosyaları toplu olarak yönet." -msgid "Refresh" -msgstr "Yenile" - msgid "Reload file list from printer." msgstr "Dosya listesini yazıcıdan yeniden yükleyin." @@ -6418,6 +6769,9 @@ msgstr "Yazdırma Seçenekleri" msgid "Safety Options" msgstr "Güvenlik Seçenekleri" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Lamba" @@ -6451,6 +6805,12 @@ msgstr "Yazdırma duraklatıldığında filament yükleme ve boşaltma yalnızca msgid "Current extruder is busy changing filament." msgstr "Mevcut ekstruder filamanı değiştirmekle meşgul." +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "Geçerli yuva zaten yüklendi." @@ -6501,9 +6861,6 @@ msgstr "Bu yalnızca yazdırma sırasında etkili olur" msgid "Silent" msgstr "Sessiz" -msgid "Standard" -msgstr "Standart" - msgid "Sport" msgstr "Spor" @@ -6537,6 +6894,12 @@ msgstr "Resim Ekle" msgid "Delete Photo" msgstr "Resmi Sil" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Gönder" @@ -6718,6 +7081,9 @@ msgstr "Yalnızca LAN modu nasıl kullanılır" msgid "Don't show this dialog again" msgstr "Bu iletişim kutusunu bir daha gösterme" +msgid "Please refer to Wiki before use->" +msgstr "Lütfen kullanmadan önce Wiki'ye bakın->" + msgid "3D Mouse disconnected." msgstr "3D Fare bağlantısı kesildi." @@ -6972,27 +7338,18 @@ msgstr "Akış" msgid "Please change the nozzle settings on the printer." msgstr "Lütfen yazıcıdaki püskürtme ucu ayarlarını değiştirin." -msgid "Hardened Steel" -msgstr "Güçlendirilmiş çelik" - -msgid "Stainless Steel" -msgstr "Paslanmaz çelik" - -msgid "Tungsten Carbide" -msgstr "Tungsten Karbür" - msgid "Brass" msgstr "Pirinç" msgid "High flow" msgstr "Yüksek akış" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "Bu yazıcı için wiki bağlantısı yok." -msgid "Refreshing" -msgstr "Canlandırıcı" - msgid "Unavailable while heating maintenance function is on." msgstr "Isıtma bakım fonksiyonu açıkken kullanılamaz." @@ -7115,6 +7472,15 @@ msgstr "Anahtar çapı" msgid "Configuration incompatible" msgstr "Yapılandırma uyumsuz" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "İpuçları" + msgid "Sync printer information" msgstr "Yazıcı bilgilerini senkronize edin" @@ -7143,6 +7509,9 @@ msgstr "Ön ayarı düzenlemek için tıklayın" msgid "Project Filaments" msgstr "Proje Filamentleri" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Yıkama hacimleri" @@ -7368,9 +7737,6 @@ msgstr "Bağlı yazıcı: %s. Yazdırma için proje ön ayarıyla eşleşmelidir msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "Yazıcı bilgilerini senkronize etmek ve ön ayarı otomatik olarak değiştirmek ister misiniz?" -msgid "Tips" -msgstr "İpuçları" - msgid "The file does not contain any geometry data." msgstr "Dosya herhangi bir geometri verisi içermiyor." @@ -7421,9 +7787,21 @@ msgstr "" "Bu eylem kesilmiş bir yazışmayı bozacaktır.\n" "Bundan sonra model tutarlılığı garanti edilemez." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Seçilen nesne bölünemedi." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7450,6 +7828,9 @@ msgstr "Yeni dosya seç" msgid "File for the replacement wasn't selected" msgstr "Değiştirme dosyası seçilmedi" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "Değiştirilecek klasörü seçin" @@ -7496,6 +7877,9 @@ msgstr "Yeniden yüklenemiyor:" msgid "Error during reload" msgstr "Yeniden yükleme sırasında hata oluştu" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Modellerin dilimlenmesinden sonra uyarılar vardır:" @@ -8267,6 +8651,15 @@ msgstr "Dosyayı yükledikten sonra yazıcı ön ayarını senkronize etmek içi msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8282,16 +8675,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8572,6 +8956,9 @@ msgstr "Uyumsuz ön ayarlar" msgid "My Printer" msgstr "Yazıcım" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "Sol filamentler" @@ -8591,6 +8978,9 @@ msgstr "Ön ayarları ekle/kaldır" msgid "Edit preset" msgstr "Ön ayarı düzenle" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "belirtilmemiş" @@ -8622,9 +9012,6 @@ msgstr "Yazıcıları Seç/Kaldır (sistem ön ayarları)" msgid "Create printer" msgstr "Yazıcı oluştur" -msgid "Empty" -msgstr "Boş" - msgid "Incompatible" msgstr "Uyumsuz" @@ -8856,12 +9243,42 @@ msgstr "gönderme tamamlandı" msgid "Error code" msgstr "Hata kodu" -msgid "High Flow" -msgstr "Yüksek Akış" +msgid "Error desc" +msgstr "Hata açıklaması" + +msgid "Extra info" +msgstr "Fazladan bilgi" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s(%s)'nin püskürtme ucu akış ayarı dilimleme dosyasıyla(%s) eşleşmiyor. Lütfen takılan püskürtme ucunun yazıcıdaki ayarlarla eşleştiğinden emin olun, ardından dilimleme sırasında ilgili yazıcı ön ayarını yapın." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8925,8 +9342,38 @@ msgstr "Maliyet %dg filament ve %d, optimum gruplandırmadan daha fazla değişi msgid "nozzle" msgstr "meme" -msgid "both extruders" -msgstr "her iki ekstruder" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s(%s)'nin püskürtme ucu akış ayarı dilimleme dosyasıyla(%s) eşleşmiyor. Lütfen takılan püskürtme ucunun yazıcıdaki ayarlarla eşleştiğinden emin olun, ardından dilimleme sırasında ilgili yazıcı ön ayarını yapın." msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "İpuçları: Yazıcınızın püskürtme ucunu yakın zamanda değiştirdiyseniz, püskürtme ucu ayarınızı değiştirmek için lütfen 'Cihaz -> Yazıcı parçaları'na gidin." @@ -8939,10 +9386,17 @@ msgstr "Geçerli yazıcının %s çapı(%.1fmm) dilimleme dosyasıyla (%.1fmm) e msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "Mevcut nozül çapı (%.1fmm) dilimleme dosyasıyla (%.1fmm) eşleşmiyor. Lütfen takılan püskürtme ucunun yazıcıdaki ayarlarla eşleştiğinden emin olun, ardından dilimleme sırasında ilgili yazıcı ön ayarını yapın." +msgid "both extruders" +msgstr "her iki ekstruder" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "Mevcut malzemenin sertliği (%s), %s(%s) sertliğini aşıyor. Lütfen nozul veya malzeme ayarlarını doğrulayın ve tekrar deneyin." +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] yüksek sıcaklıktaki bir ortamda yazdırmayı gerektirir. Lütfen kapıyı kapatın." @@ -9053,9 +9507,6 @@ msgstr "Mevcut donanım yazılımı maksimum 16 materyali desteklemektedir. Haz msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "Lütfen kullanmadan önce Wiki'ye bakın->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "Mevcut ürün yazılımı, dahili depolama birimine dosya aktarımını desteklemiyor." @@ -9239,6 +9690,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Tüm ayarları en son kaydedilen ön ayara sıfırlamak için tıklayın." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Sorunsuz timeplace için Prime Tower gereklidir. Prime tower olmayan modelde kusurlar olabilir. Prime tower'ı devre dışı bırakmak istediğinizden emin misiniz?" @@ -9320,9 +9774,6 @@ msgstr "Ayarlanan aralığa otomatik olarak ayarlansın mı?\n" msgid "Adjust" msgstr "Ayarla" -msgid "Ignore" -msgstr "Atla" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Deneysel özellik: Filament değişiklikleri sırasında, floşu en aza indirmek için filamanı daha büyük bir mesafeden geri çekmek ve kesmek. Flush’u önemli ölçüde azaltabilmesine rağmen, aynı zamanda nozül tıkanmaları veya diğer yazdırma komplikasyonları riskini de artırabilir." @@ -9826,6 +10277,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Seçilen ön ayarı %1% yaptığınızdan emin misiniz?" +msgid "Select printers" +msgstr "Yazıcıları seçin" + +msgid "Select profiles" +msgstr "Profilleri seçin" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10053,6 +10510,12 @@ msgstr "Değerleri soldan sağa aktarın" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Etkinleştirilirse, bu iletişim kutusu seçilen değerleri soldan sağa ön ayara aktarmak için kullanılabilir." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Dosya Ekle" @@ -10308,12 +10771,8 @@ msgstr "Püskürtme ucu bilgileri başarıyla senkronize edildi." msgid "Successfully synchronized nozzle and AMS number information." msgstr "Nozul ve AMS numarası bilgileri başarıyla senkronize edildi." -msgid "Continue to sync filaments" -msgstr "Filamentleri senkronize etmeye devam edin" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "İptal etmek" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "Filament rengi yazıcıdan başarıyla senkronize edildi." @@ -10421,6 +10880,9 @@ msgstr "Giriş yap" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[İşlem Gerekli]" @@ -10735,6 +11197,9 @@ msgstr "Yazıcı adı" msgid "Where to find your printer's IP and Access Code?" msgstr "Yazıcınızın IP'sini ve Erişim Kodunu nerede bulabilirsiniz?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Bağlan" @@ -10799,6 +11264,9 @@ msgstr "Kesim Modülü" msgid "Auto Fire Extinguishing System" msgstr "Otomatik Yangın Söndürme Sistemi" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10817,6 +11285,9 @@ msgstr "Güncelleme başarısız oldu" msgid "Update successful" msgstr "Güncelleme başarılı" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Güncellemek istediğinizden emin misiniz? Bu yaklaşık 10 dakika sürecektir. Yazıcı güncellenirken gücü kapatmayın." @@ -10925,6 +11396,9 @@ msgstr "Gruplama hatası:" msgid " can not be placed in the " msgstr "içine yerleştirilemez" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "İç Köprü" @@ -11638,7 +12112,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11652,7 +12126,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12096,9 +12570,6 @@ msgstr "" "Keskin açılar algılanmadan önce geometri azaltılacaktır. Bu parametre, azaltma için minimum sapma uzunluğunu belirtir.\n" "Devre dışı bırakmak için 0." -msgid "Select printers" -msgstr "Yazıcıları seçin" - msgid "upward compatible machine" msgstr "yukarı doğru uyumlu makine" @@ -12109,9 +12580,6 @@ msgstr "Durum" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Etkin bir yazıcı profilinin yapılandırma değerlerini kullanan bir boole ifadesi. Bu ifade doğru olarak değerlendirilirse bu profilin etkin yazıcı profiliyle uyumlu olduğu kabul edilir." -msgid "Select profiles" -msgstr "Profilleri seçin" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Etkin yazdırma profilinin yapılandırma değerlerini kullanan bir boole ifadesi. Bu ifade doğru olarak değerlendirilirse bu profilin etkin yazdırma profiliyle uyumlu olduğu kabul edilir." @@ -12378,6 +12846,42 @@ msgstr "Üst yüzey yoğunluğu" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Üst yüzey katmanının yoğunluğu. %100 değeri, tamamen sağlam ve pürüzsüz bir üst katman oluşturur. Bu değerin düşürülmesi, seçilen üst yüzey desenine göre dokulu bir üst yüzey elde edilmesini sağlar. %0 değeri ise yalnızca üst katmandaki duvarların oluşturulmasını sağlar. Estetik veya işlevsel amaçlar için tasarlanmıştır, aşırı ekstrüzyon gibi sorunları gidermek için değildir." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Alt yüzey deseni" @@ -12705,12 +13209,18 @@ msgstr "Yıkama İçin Otomatik" msgid "Auto For Match" msgstr "Otomatik Maç İçin" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "Yıkama sıcaklığı" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "Filament yıkanırken sıcaklık. 0, önerilen meme sıcaklık aralığının üst sınırını gösterir." +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "Yıkama hacimsel hızı" @@ -12978,6 +13488,12 @@ msgstr "Filament yazdırılabilir" msgid "The filament is printable in extruder." msgstr "Filament ekstruderde basılabilir." +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Yumuşama sıcaklığı" @@ -13040,12 +13556,12 @@ msgstr "Dolgu yoğunluğu" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "İç seyrek dolgunun yoğunluğu, %100 tüm seyrek dolguyu katı dolguya dönüştürür ve iç katı dolgu modeli kullanılacaktır." -msgid "Align infill direction to model" -msgstr "Dolgu yönünü modele hizalayın" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13566,6 +14082,15 @@ msgstr "Yatak şekline göre [0,1] aralığında en iyi otomatik düzenleme konu msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Makinede yardımcı parça soğutma fanı varsa bu seçeneği etkinleştirin. G-code komut: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13637,6 +14162,12 @@ msgstr "" "Yazıcı hava filtrelemeyi destekliyorsa bunu etkinleştirin\n" "G-code komut: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "G-code türü" @@ -14163,6 +14694,30 @@ msgstr "Minimum seyahat hızı" msgid "Minimum travel speed (M205 T)" msgstr "Minimum ilerleme hızı (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Ekstrüzyon için maksimum hızlanma" @@ -14710,6 +15265,9 @@ msgstr "Doğrudan Tahrik" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -14745,6 +15303,12 @@ msgstr "İleri itme hızı" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Filamentin nozüle yeniden yüklenme hızı. Sıfır, geri çekilme hızının aynı olduğu anlamına gelir." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Yazılımsal geri çekme" @@ -14776,6 +15340,10 @@ msgstr "Hizalı" msgid "Aligned back" msgstr "Arkaya hizalı" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Arka" + msgid "Random" msgstr "Rastgele" @@ -15049,6 +15617,12 @@ msgstr "Düzgün veya geleneksel mod seçilirse her baskı için bir hızlandır msgid "Traditional" msgstr "Geleneksel" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Sıcaklık değişimi" @@ -15136,6 +15710,18 @@ msgstr "Tüm ekstruderleri temizle" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Etkinleştirilirse, tüm baskı ekstruderleri baskının başlangıcında baskı yatağının ön kenarında temizlenecektir." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Dilim aralığı kapanma yarıçapı" @@ -15527,7 +16113,7 @@ msgstr "" "Etkinleştirilirse, bu parametre aynı zamanda istenen oda sıcaklığını yazdırma başlatma makronuza veya şuna benzer bir ısı emme makrosuna iletmek için kullanılabilecek Chamber_temperature adlı bir gcode değişkenini de ayarlar: PRINT_START (diğer değişkenler) CHAMBER_TEMP=[chamber_temperature]. Yazıcınız M141/M191 komutlarını desteklemiyorsa veya aktif oda ısıtıcısı takılı değilse yazdırma başlatma makrosunda ısı bekletme işlemini gerçekleştirmek istiyorsanız bu yararlı olabilir." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15581,6 +16167,45 @@ msgstr "Üst katman kalınlığı" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Üst kabuk katmanları tarafından hesaplanan kalınlık bu değerden daha ince ise dilimleme sırasında üst katı katmanların sayısı artırılır. Bu, katman yüksekliği küçük olduğunda kabuğun çok ince olmasını önleyebilir. 0, bu ayarın devre dışı olduğu ve üst kabuğun kalınlığının kesinlikle üst kabuk katmanları tarafından belirlendiği anlamına gelir." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Daha hızlı ve ekstrüzyonsuz seyahat hızı." @@ -15629,6 +16254,12 @@ msgstr "Temizleme çarpanı" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Gerçek temizleme hacimleri, tablodaki temizleme hacimleri ile temizleme çarpanının çarpımına eşittir." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Ana hacim" @@ -15636,6 +16267,18 @@ msgstr "Ana hacim" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Kule üzerindeki ana ekstruder malzeme hacmi." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Prime tower genişliği." @@ -15928,6 +16571,57 @@ msgstr "Minimum duvar genişliği" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Modelin ince özelliklerinin yerini alacak duvarın genişliği (Minimum özellik boyutuna göre). Minimum duvar genişliği özelliğin kalınlığından daha inceyse duvar, özelliğin kendisi kadar kalın olacaktır. Nozul çapına göre yüzde olarak ifade edilir." +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "Sızmayı önlemek için nozul, sıkıştırma tamamlandıktan sonra belirli bir süre boyunca ters hareket hareketi gerçekleştirecektir. Ayar, hareket süresini tanımlar." + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "Sızıntıyı önlemek için, nozul sıcaklığı tokmaklama sırasında soğutulacaktır. Bu nedenle, sıkıştırma süresi soğuma süresinden büyük olmalıdır. 0 devre dışı anlamına gelir." + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "Dar iç katı dolguyu tespit et" @@ -16679,12 +17373,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Kalibrasyon desteklenmiyor" -msgid "Error desc" -msgstr "Hata açıklaması" - -msgid "Extra info" -msgstr "Fazladan bilgi" - msgid "Flow Dynamics" msgstr "Akış Dinamiği" @@ -16892,6 +17580,12 @@ msgstr "Lütfen yazıcıya kaydetmek istediğiniz adı girin." msgid "The name cannot exceed 40 characters." msgstr "Ad 40 karakteri aşamaz." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Lütfen plakadaki en iyi çizgiyi bulun" @@ -16982,9 +17676,6 @@ msgstr "AMS ve püskürtme ucu bilgileri senkronize edilir" msgid "Nozzle Flow" msgstr "Nozul Akışı" -msgid "Nozzle Info" -msgstr "Nozul Bilgisi" - msgid "Filament position" msgstr "filament konumu" @@ -17059,6 +17750,10 @@ msgstr "Geçmiş sonucunu alma başarısı" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Geçmiş Akış Dinamiği Kalibrasyon kayıtlarını yenileme" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "İşlem" @@ -18818,6 +19513,12 @@ msgstr "Yazdırma Başarısız" msgid "Removed" msgstr "Kaldırıldı" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "Bana bir daha hatırlatma" @@ -18851,12 +19552,25 @@ msgstr "Öğretici Video" msgid "(Sync with printer)" msgstr "(Yazıcıyla senkronize edin)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "Bu gruplandırma yöntemine göre dilimleyeceğiz:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "İpucu: Filamentleri farklı püskürtme uçlarına yeniden atamak için sürükleyebilirsiniz." +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "Geçerli plaka için filaman gruplandırma yöntemi, dilimleme plakası düğmesindeki açılır seçenekle belirlenir." @@ -19089,9 +19803,6 @@ msgstr "Bu eylem geri alınamaz. Devam etmek?" msgid "Skipping objects." msgstr "Nesneleri atlama." -msgid "Select Filament" -msgstr "Filament Seçin" - msgid "Null Color" msgstr "Boş Renk" @@ -19610,6 +20321,19 @@ msgstr "" "Eğilmeyi önleyin\n" "ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?" +#~ msgid "Continue to sync filaments" +#~ msgstr "Filamentleri senkronize etmeye devam edin" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "İptal etmek" + +#~ msgid "Align infill direction to model" +#~ msgstr "Dolgu yönünü modele hizalayın" + +#~ msgid "Print" +#~ msgstr "Yazdır" + #~ msgid "in" #~ msgstr "in" diff --git a/localization/i18n/uk/OrcaSlicer_uk.po b/localization/i18n/uk/OrcaSlicer_uk.po index ab876dab5e..4fbe7445b3 100644 --- a/localization/i18n/uk/OrcaSlicer_uk.po +++ b/localization/i18n/uk/OrcaSlicer_uk.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: orcaslicerua\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2025-03-07 09:30+0200\n" "Last-Translator: \n" "Language-Team: Ukrainian\n" @@ -40,6 +40,24 @@ msgstr "TPU не підтримується AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -52,6 +70,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Філаменти CF/GF є жорсткими і крихкими, їх легко можна зламати або вони можуть застряти в AMS, будьте обережні під час використання." @@ -61,10 +82,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "Стандартний" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Невідомий" + +msgid "Hardened Steel" +msgstr "Закалена сталь" + +msgid "Stainless Steel" +msgstr "Нержавіюча сталь" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Попередження" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "Оновлення" + msgid "Current AMS humidity" msgstr "Поточна вологість AMS" @@ -95,6 +196,85 @@ msgstr "Версія:" msgid "Latest version" msgstr "Остання версія" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Порожній" + +msgid "Error" +msgstr "Помилка" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Оновити" + +msgid "Refreshing" +msgstr "" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "Скасувати" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "СН" + +msgid "Version" +msgstr "Версія" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Малювання Підтримок" @@ -167,6 +347,12 @@ msgstr "Заповнення" msgid "Gap Fill" msgstr "Заповнення прогалин" +msgid "Vertical" +msgstr "Вертикальний" + +msgid "Horizontal" +msgstr "Горизонтальний" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Малювання лише на вибраних гранях: \"%1%\"" @@ -262,12 +448,6 @@ msgstr "Трикутник" msgid "Height Range" msgstr "Діапазон висот" -msgid "Vertical" -msgstr "Вертикальний" - -msgid "Horizontal" -msgstr "Горизонтальний" - msgid "Remove painted color" msgstr "Видалити зафарбований колір" @@ -332,6 +512,7 @@ msgstr "Gizmo обертання" msgid "Optimize orientation" msgstr "Оптимізувати орієнтацію" +msgctxt "Verb" msgid "Scale" msgstr "Масштаб" @@ -376,6 +557,9 @@ msgstr "Коефіцієнти масштабування" msgid "Object operations" msgstr "Операції з об'єктами" +msgid "Scale" +msgstr "Масштаб" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Операції з об’ємом" @@ -427,6 +611,10 @@ msgstr "Скинути поточне обертання до значення msgid "Reset current rotation to real zeros." msgstr "Скинути поточне обертання до нульових значень." +msgctxt "Noun" +msgid "Scale" +msgstr "Масштаб" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Розмір" @@ -609,9 +797,6 @@ msgstr "Пропорція простору в залежності від ра msgid "Confirm connectors" msgstr "Підтвердити з'єднувачі" -msgid "Cancel" -msgstr "Скасувати" - msgid "Flip cut plane" msgstr "Перевернути площину зрізу" @@ -652,12 +837,12 @@ msgstr "Розрізати на частини" msgid "Reset cutting plane and remove connectors" msgstr "Скиньте площину різання та зніміть з'єднувачі" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Виконати розрізання" -msgid "Warning" -msgstr "Попередження" - msgid "Invalid connectors detected" msgstr "Виявлено неприпустимі з'єднувачі" @@ -692,6 +877,13 @@ msgstr "Площина зрізу з пазом невірна" msgid "Connector" msgstr "З'єднувач" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Вирізати площиною" @@ -739,9 +931,6 @@ msgstr "Спростити" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Спрощення наразі дозволено лише при виборі окремої деталі" -msgid "Error" -msgstr "Помилка" - msgid "Extra high" msgstr "Надвисокий" @@ -2004,6 +2193,9 @@ msgstr "" msgid "Loading user preset" msgstr "Завантаження користувацького налаштування" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2017,6 +2209,18 @@ msgstr "Виберіть мову" msgid "Language" msgstr "Мова" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2656,6 +2860,45 @@ msgstr "Натисніть , щоб змінити колір моделі" msgid "Click the icon to shift this object to the bed" msgstr "Натисніть значок, щоб перемістити цю модель на стіл" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Завантаження файлу" @@ -2665,6 +2908,9 @@ msgstr "Помилка!" msgid "Failed to get the model data in the current file." msgstr "Не вдалося отримати дані моделі в поточному файлі." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Базовий примітив" @@ -2677,6 +2923,12 @@ msgstr "Переключення в режим роботи з моделями msgid "Remove paint-on fuzzy skin" msgstr "Видалити намальовану текстурну оболонку" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Видалення діапазону висот шарів" + msgid "Delete connector from object which is a part of cut" msgstr "Видалити конектор з об'єкта, який є частиною розрізу" @@ -2707,12 +2959,24 @@ msgstr "Видалити всі з'єднання" msgid "Deleting the last solid part is not allowed." msgstr "Видалення останньої твердотільного частини не допускається." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Цільовий об’єкт містить лише одну частину і не може бути розділений." +msgid "Split to parts" +msgstr "Розділити на частини" + msgid "Assembly" msgstr "Збірка" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Інформація про вирізані з'єднання" @@ -2746,6 +3010,9 @@ msgstr "Діапазон висот шарів" msgid "Settings for height range" msgstr "Налаштування для діапазону висот шарів" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Шар" @@ -2770,6 +3037,9 @@ msgstr "Тип:" msgid "Choose part type" msgstr "Виберіть тип деталі" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Введіть нове ім'я" @@ -2801,6 +3071,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Додаткове налаштування процесу" @@ -2810,9 +3083,6 @@ msgstr "Видалити параметр" msgid "to" msgstr "в" -msgid "Remove height range" -msgstr "Видалення діапазону висот шарів" - msgid "Add height range" msgstr "Додавання діапазон висот шарів" @@ -3024,6 +3294,9 @@ msgstr "Виберіть слот AMS, а потім натисніть кноп msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3146,6 +3419,24 @@ msgstr "Підтвердити витіснення" msgid "Check filament location" msgstr "Перевірити розташування філаменту" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3199,6 +3490,62 @@ msgstr "Режим розробки" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Підтвердити" + +msgid "Extruder" +msgstr "Екструдер" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Ігнорувати" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3537,15 +3884,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Версія" - msgid "AMS Materials Setting" msgstr "Налаштування матеріалів AMS" -msgid "Confirm" -msgstr "Підтвердити" - msgid "Close" msgstr "Закрити" @@ -3566,12 +3907,12 @@ msgstr "мін" msgid "The input value should be greater than %1% and less than %2%" msgstr "Вхідне значення має бути більше %1% і менше %2%" -msgid "SN" -msgstr "СН" - msgid "Factors of Flow Dynamics Calibration" msgstr "Фактори Калібрування динамічного потоку" +msgid "Wiki Guide" +msgstr "" + msgid "PA Profile" msgstr "Профіль PA" @@ -3660,7 +4001,7 @@ msgstr "Калібрування завершено. Тепер знайдіть msgid "Save" msgstr "Зберегти" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Ззаду" @@ -3735,6 +4076,19 @@ msgstr "" msgid "Nozzle" msgstr "Сопло" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4443,9 +4797,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "Невідомий" - msgid "Update successful." msgstr "Оновлення успішне." @@ -4957,9 +5308,6 @@ msgstr "" msgid "Regroup filament" msgstr "Перегрупувати філамент" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "аж до" @@ -4996,8 +5344,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Швидкість Вентилятора (%)" -msgid "Temperature (°C)" -msgstr "Температура (°С)" +msgid "Temperature (℃)" +msgstr "Температура (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Об'ємна витрата (мм³/с)" @@ -5015,9 +5363,6 @@ msgstr "Зміни філаменту" msgid "Options" msgstr "Параметри" -msgid "Extruder" -msgstr "Екструдер" - msgid "Cost" msgstr "Витрата" @@ -5030,6 +5375,7 @@ msgstr "Зміна інструменту" msgid "Color change" msgstr "Зміна кольору" +msgctxt "Noun" msgid "Print" msgstr "Друк" @@ -5191,11 +5537,15 @@ msgstr "Уникайте області калібрування екструз msgid "Align to Y axis" msgstr "Розташувати вздовж осі Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Ззаду" + +msgctxt "Camera View" msgid "Left" msgstr "Ліво" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Право" @@ -5220,9 +5570,6 @@ msgstr "Впорядкувати об'єкти на вибраних пласт msgid "Split to objects" msgstr "Розділити на об'єкти" -msgid "Split to parts" -msgstr "Розділити на частини" - msgid "Assembly View" msgstr "Вигляд складання" @@ -5523,6 +5870,10 @@ msgstr "Друкувати пластину" msgid "Export G-code file" msgstr "Експорт файлу G-коду" +msgctxt "Verb" +msgid "Print" +msgstr "Друк" + msgid "Export plate sliced file" msgstr "Експортувати файл нарізки пластини" @@ -5696,15 +6047,6 @@ msgstr "Експорт поточної конфігурації до файлі msgid "Export" msgstr "Експорт" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Вихід" @@ -5821,6 +6163,15 @@ msgstr "Вид" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5943,6 +6294,9 @@ msgstr "Експорт результату" msgid "Select profile to load:" msgstr "Виберіть профіль для завантаження:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6110,9 +6464,6 @@ msgstr "Завантажте вибрані файли з принтера." msgid "Batch manage files." msgstr "Пакетне керування файлами." -msgid "Refresh" -msgstr "Оновити" - msgid "Reload file list from printer." msgstr "Перезавантажте список файлів з принтера." @@ -6425,6 +6776,9 @@ msgstr "Параметри друку" msgid "Safety Options" msgstr "" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Лампа" @@ -6458,6 +6812,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6509,9 +6869,6 @@ msgstr "Це діє лише під час друку" msgid "Silent" msgstr "Тихий" -msgid "Standard" -msgstr "Стандартний" - msgid "Sport" msgstr "Спортивний" @@ -6545,6 +6902,12 @@ msgstr "Додати фото" msgid "Delete Photo" msgstr "Видалити фото" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Підтвердити" @@ -6732,6 +7095,9 @@ msgstr "Як використовувати режим лише локально msgid "Don't show this dialog again" msgstr "Більше не показувати це діалогове вікно" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "3D-миша відключена." @@ -6995,25 +7361,16 @@ msgstr "Потік" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "Закалена сталь" - -msgid "Stainless Steel" -msgstr "Нержавіюча сталь" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "Латунь" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" +msgid "No wiki link available for this printer." msgstr "" msgid "Unavailable while heating maintenance function is on." @@ -7138,6 +7495,15 @@ msgstr "Змінити діаметр" msgid "Configuration incompatible" msgstr "Несумісність конфігурації" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Поради" + msgid "Sync printer information" msgstr "Синхронізувати інформацію принтера" @@ -7164,6 +7530,9 @@ msgstr "Натисніть, щоб редагувати профіль" msgid "Project Filaments" msgstr "Філаменти проєкта" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Об'єми промивки" @@ -7394,9 +7763,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "Поради" - msgid "The file does not contain any geometry data." msgstr "Файл не містить геометричних даних." @@ -7449,9 +7815,21 @@ msgstr "" "Ця дія розірве обрізану кореспонденцію.\n" "Після цього узгодженість моделі не може бути гарантована." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Вибраний об'єкт не може бути поділений." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7478,6 +7856,9 @@ msgstr "Виберіть новий файл" msgid "File for the replacement wasn't selected" msgstr "Не вибраний файл для заміни" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7524,6 +7905,9 @@ msgstr "Не вдається перезавантажити:" msgid "Error during reload" msgstr "Помилка під час перезавантаження" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Є попередження після нарізки моделей:" @@ -8278,6 +8662,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8293,16 +8686,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8584,6 +8968,9 @@ msgstr "Несумісні пресети" msgid "My Printer" msgstr "" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8603,6 +8990,9 @@ msgstr "Додати/видалити пресети" msgid "Edit preset" msgstr "Змінити попереднє встановлення" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "Не вказано" @@ -8634,9 +9024,6 @@ msgstr "Вибрати/Вилучити принтери (системні пр msgid "Create printer" msgstr "Створити принтер" -msgid "Empty" -msgstr "Порожній" - msgid "Incompatible" msgstr "Несумісний" @@ -8862,11 +9249,41 @@ msgstr "відправлення завершено" msgid "Error code" msgstr "Код помилки" -msgid "High Flow" +msgid "Error desc" +msgstr "Опис помилки" + +msgid "Extra info" +msgstr "Додаткова інформація" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, c-format, boost-format @@ -8931,7 +9348,37 @@ msgstr "" msgid "nozzle" msgstr "сопло" -msgid "both extruders" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8945,10 +9392,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -9059,9 +9513,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -9245,6 +9696,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Натисніть, щоб скинути всі налаштування до останньої збереженої попередньої установки." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Для плавного таймлапсу потребується Підготовча вежа. Без Підготовчої вежі на моделі можуть виникати дефекти. Ви впевнені, що хочете вимкнути Підготовчу вежу?" @@ -9322,9 +9776,6 @@ msgstr "Автоматично налаштувати на встановлен msgid "Adjust" msgstr "Налаштувати" -msgid "Ignore" -msgstr "Ігнорувати" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Експериментальна функція: Втягування та відрізання філаменту на більшій відстані під час зміни філаменту для мінімізації промивання. Хоча це може помітно зменшити промивання, це також може підвищити ризик засмічення сопла або інших ускладнень друку." @@ -9840,6 +10291,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Ви впевнені, що %1% вибраної установки?" +msgid "Select printers" +msgstr "" + +msgid "Select profiles" +msgstr "" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10067,6 +10524,12 @@ msgstr "Перенесення значень зліва направо" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Якщо увімкнено, цей діалог можна використовувати для перенесення вибраних значень зліва направо." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Додати файл" @@ -10314,13 +10777,9 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" +msgid "Do you want to continue to sync filaments?" msgstr "" -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Скасувати" - msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10427,6 +10886,9 @@ msgstr "Логін" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10741,6 +11203,9 @@ msgstr "Назва принтера" msgid "Where to find your printer's IP and Access Code?" msgstr "Де знайти IP-адресу та код доступу вашого принтера?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Підключити" @@ -10805,6 +11270,9 @@ msgstr "" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10823,6 +11291,9 @@ msgstr "Оновлення не вдалося" msgid "Update successful" msgstr "Успішне оновлення" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Ви впевнені, що хочете оновитися? Це займе близько 10 хвилин. Не вимикайте живлення під час оновлення принтера." @@ -10933,6 +11404,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Внутрішній міст" @@ -11648,7 +12122,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11662,7 +12136,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -12079,9 +12553,6 @@ msgstr "" "Геометрія буде оброблена перед детектуванням гострих кутів. Цей параметр вказує мінімальну довжину відхилення для обробки.\n" "0 для вимкнення" -msgid "Select printers" -msgstr "" - msgid "upward compatible machine" msgstr "висхідна сумісна машина" @@ -12092,9 +12563,6 @@ msgstr "" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Логічний вираз, що використовує значення конфігурації активного профілю принтера. Якщо цей вираз оцінюється як Правда, цей профіль вважається сумісним з активним профілем принтера." -msgid "Select profiles" -msgstr "" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Логічний вираз, що використовує значення конфігурації активного профілю друку. Якщо цей вираз оцінюється як Правда, цей профіль вважається сумісним з активним профілем друку." @@ -12363,6 +12831,42 @@ msgstr "" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Шаблон нижньої поверхні" @@ -12692,12 +13196,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12960,6 +13470,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Температура розм'якшення" @@ -13022,12 +13538,12 @@ msgstr "Щільність часткового заповнення" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Щільність внутрішнього часткового заповнення, 100% перетворює все часткове заповнення на суцільне заповнення, і буде застосовано шаблон внутрішнього суцільного заповнення" -msgid "Align infill direction to model" +msgid "Align directions to model" msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13538,6 +14054,15 @@ msgstr "Найкраще автоматичне розташування об’ msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Увімкніть цю опцію, якщо принтер має вентилятор охолодження допоміжної частини. Команда G-коду: M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" @@ -13610,6 +14135,12 @@ msgstr "" "Увімкніть цей параметр, якщо принтер підтримує фільтрацію повітря\n" "Команда G-коду: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "Тип G-коду" @@ -14139,6 +14670,30 @@ msgstr "Мінімальна швидкість руху" msgid "Minimum travel speed (M205 T)" msgstr "Мінімальна швидкість руху (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Максимальне прискорення для екструдування" @@ -14687,6 +15242,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Боуден" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -14722,6 +15280,12 @@ msgstr "Швидкість компенсуючого ретракту" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Використовувати ретракт прошивки" @@ -14753,6 +15317,10 @@ msgstr "Вирівняне" msgid "Aligned back" msgstr "" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Ззаду" + msgid "Random" msgstr "Випадкове" @@ -15026,6 +15594,12 @@ msgstr "Якщо вибрано плавний або традиційний р msgid "Traditional" msgstr "Традиційний" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Зміна температури" @@ -15117,6 +15691,18 @@ msgstr "Підготовка всіх друкуючих екструдерів" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Якщо увімкнено, усі друкуючі екструдери будуть отестовані на передньому краї друкарського столу перед початком друку." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Радіус закриття пробілів під час нарізування" @@ -15503,7 +16089,7 @@ msgstr "" "Це може бути корисним, якщо ваш принтер не підтримує команди M141/M191 або якщо ви хочете керувати прогрівом камери у макросі запуску друку за відсутності активного нагрівача камери." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15558,6 +16144,45 @@ msgstr "Товщина верхньої оболонки" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Кількість верхніх суцільних шарів збільшується при розрізанні, якщо товщина, обчислена шарами верхньої оболонки, тонша за це значення. Це дозволяє уникнути занадто тонкої оболонки при невеликій висоті шару. 0 означає, що це налаштування вимкнено і товщина верхньої оболонки повністюобмежена верхніми шарами оболонки" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Швидкість переміщення, яка є швидше і без екструзії" @@ -15606,6 +16231,12 @@ msgstr "Множник промивки" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Фактичні об'єми промивки дорівнюють множнику промивки, помноженому на обсяг промивки в таблиці." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Об'єм підготовки" @@ -15613,6 +16244,18 @@ msgstr "Об'єм підготовки" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Об'єм матеріалу для підготовки екструдера на вежі." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Ширина підготовчої вежі" @@ -15898,6 +16541,57 @@ msgstr "Мінімальна товщина стінки" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Ширина периметра, яка замінить тонкі елементи (відповідно до Мінімальним розміром елемента) моделі. Якщо мінімальна ширина периметра менше товщини елемента, то товщина периметра дорівнюватиме товщині самого елемента. Він виражається у відсотках від діаметра сопла" +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Виявлення вузького внутрішнього суцільного заповнення" @@ -16663,12 +17357,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Калібрування не підтримується" -msgid "Error desc" -msgstr "Опис помилки" - -msgid "Extra info" -msgstr "Додаткова інформація" - msgid "Flow Dynamics" msgstr "Динаміка потоку" @@ -16870,6 +17558,12 @@ msgstr "Будь ласка, введіть ім’я, яке ви хочете msgid "The name cannot exceed 40 characters." msgstr "Ім’я не може перевищувати 40 символів." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Будь ласка, знайдіть найкращу лінію на вашій пластині" @@ -16960,9 +17654,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "позиція філаменту" @@ -17037,6 +17728,10 @@ msgstr "Успішно отримано історичний результат" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Оновлення історичних записів калібрування динаміки потоку" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "Дія" @@ -18762,6 +19457,12 @@ msgstr "Не вдалося надрукувати" msgid "Removed" msgstr "Видалено" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -18795,12 +19496,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -19033,9 +19747,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "" - msgid "Null Color" msgstr "" @@ -19554,6 +20265,13 @@ msgstr "" "Уникнення деформації\n" "Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури гарячого ліжка може зменшити ймовірність деформації?" +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Скасувати" + +#~ msgid "Print" +#~ msgstr "Друк" + #~ msgid "in" #~ msgstr "в" @@ -20265,9 +20983,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Не можу запустити це без SD-карти." -#~ msgid "Update" -#~ msgstr "Оновлення" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Чутливість паузи" diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/OrcaSlicer_vi.po index 42be9867cf..f0fe2f3613 100644 --- a/localization/i18n/vi/OrcaSlicer_vi.po +++ b/localization/i18n/vi/OrcaSlicer_vi.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2025-10-02 17:43+0700\n" "Last-Translator: \n" "Language-Team: hainguyen.ts13@gmail.com\n" @@ -36,6 +36,24 @@ msgstr "TPU không được hỗ trợ bởi AMS." msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "" @@ -48,6 +66,9 @@ msgstr "" msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "Filament CF/GF cứng và giòn, dễ gãy hoặc bị kẹt trong AMS, vui lòng dùng thận trọng." @@ -57,10 +78,90 @@ msgstr "" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "" + +msgid "Standard" +msgstr "Tiêu chuẩn" + +msgid "TPU High Flow" +msgstr "" + +msgid "Unknown" +msgstr "Không rõ" + +msgid "Hardened Steel" +msgstr "Thép cứng" + +msgid "Stainless Steel" +msgstr "Thép không gỉ" + +msgid "Tungsten Carbide" +msgstr "" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "" + +msgid "Warning" +msgstr "Cảnh báo" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "" + +msgid "I confirm all" +msgstr "" + +msgid "Re-read all" +msgstr "" + +msgid "Reading the hotends, please wait." +msgstr "" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "" + +msgid "Update" +msgstr "Cập nhật" + msgid "Current AMS humidity" msgstr "Độ ẩm AMS hiện tại" @@ -91,6 +192,85 @@ msgstr "Phiên bản:" msgid "Latest version" msgstr "Phiên bản mới nhất" +msgid "Row A" +msgstr "" + +msgid "Row B" +msgstr "" + +msgid "Toolhead" +msgstr "" + +msgid "Empty" +msgstr "Trống" + +msgid "Error" +msgstr "Lỗi" + +msgid "Induction Hotend Rack" +msgstr "" + +msgid "Hotends Info" +msgstr "" + +msgid "Read All" +msgstr "" + +msgid "Reading " +msgstr "" + +msgid "Please wait" +msgstr "" + +msgid "Running..." +msgstr "" + +msgid "Raised" +msgstr "" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "" + +msgid "Abnormal Hotend" +msgstr "" + +msgid "Refresh" +msgstr "Làm mới" + +msgid "Refreshing" +msgstr "" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "" + +msgid "Cancel" +msgstr "Hủy" + +msgid "Jump to the upgrade page" +msgstr "" + +msgid "SN" +msgstr "" + +msgid "Version" +msgstr "Phiên bản" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "" + +msgid "Hotend Rack" +msgstr "" + +msgid "ToolHead" +msgstr "" + +msgid "Nozzle information needs to be read" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "Vẽ support" @@ -163,6 +343,12 @@ msgstr "Tô" msgid "Gap Fill" msgstr "Lấp khe" +msgid "Vertical" +msgstr "Dọc" + +msgid "Horizontal" +msgstr "Ngang" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "Chỉ cho phép vẽ trên mặt được chọn bởi: \"%1%\"" @@ -258,12 +444,6 @@ msgstr "Tam giác" msgid "Height Range" msgstr "Phạm vi chiều cao" -msgid "Vertical" -msgstr "Dọc" - -msgid "Horizontal" -msgstr "Ngang" - msgid "Remove painted color" msgstr "Xóa màu đã vẽ" @@ -328,6 +508,7 @@ msgstr "Gizmo - Xoay" msgid "Optimize orientation" msgstr "Tối ưu định hướng" +msgctxt "Verb" msgid "Scale" msgstr "Tỷ lệ" @@ -372,6 +553,9 @@ msgstr "Tỷ lệ co giãn" msgid "Object operations" msgstr "Thao tác vật thể" +msgid "Scale" +msgstr "Tỷ lệ" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "Thao tác thể tích" @@ -423,6 +607,10 @@ msgstr "Đặt lại xoay hiện tại về giá trị khi mở công cụ xoay. msgid "Reset current rotation to real zeros." msgstr "Đặt lại xoay hiện tại về số không thực." +msgctxt "Noun" +msgid "Scale" +msgstr "Tỷ lệ" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "Kích thước" @@ -605,9 +793,6 @@ msgstr "Tỷ lệ khoảng cách liên quan đến bán kính" msgid "Confirm connectors" msgstr "Xác nhận connector" -msgid "Cancel" -msgstr "Hủy" - msgid "Flip cut plane" msgstr "Lật mặt cắt" @@ -648,12 +833,12 @@ msgstr "Cắt thành phần" msgid "Reset cutting plane and remove connectors" msgstr "Đặt lại mặt cắt và xóa connector" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "Thực hiện cắt" -msgid "Warning" -msgstr "Cảnh báo" - msgid "Invalid connectors detected" msgstr "Phát hiện connector không hợp lệ" @@ -682,6 +867,13 @@ msgstr "Mặt cắt có rãnh không hợp lệ" msgid "Connector" msgstr "" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "Cắt bằng mặt phẳng" @@ -729,9 +921,6 @@ msgstr "Đơn giản hóa" msgid "Simplification is currently only allowed when a single part is selected" msgstr "Đơn giản hóa hiện chỉ cho phép khi một phần duy nhất được chọn" -msgid "Error" -msgstr "Lỗi" - msgid "Extra high" msgstr "Rất cao" @@ -1997,6 +2186,9 @@ msgstr "" msgid "Loading user preset" msgstr "Đang tải preset người dùng" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "" @@ -2010,6 +2202,18 @@ msgstr "Chọn ngôn ngữ" msgid "Language" msgstr "Ngôn ngữ" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2639,6 +2843,45 @@ msgstr "Nhấn biểu tượng để chỉnh sửa vẽ màu của vật thể" msgid "Click the icon to shift this object to the bed" msgstr "Nhấn biểu tượng để đưa vật thể này xuống đế" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "Đang tải file" @@ -2648,6 +2891,9 @@ msgstr "Lỗi!" msgid "Failed to get the model data in the current file." msgstr "Không thể lấy dữ liệu model trong file hiện tại." +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "Chung" @@ -2660,6 +2906,12 @@ msgstr "Chuyển sang chế độ cài đặt từng vật thể để chỉnh s msgid "Remove paint-on fuzzy skin" msgstr "Xóa fuzzy skin vẽ" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "Xóa phạm vi chiều cao" + msgid "Delete connector from object which is a part of cut" msgstr "Xóa connector khỏi vật thể là một phần của cắt" @@ -2690,12 +2942,24 @@ msgstr "Xóa tất cả connector" msgid "Deleting the last solid part is not allowed." msgstr "Không được phép xóa phần rắn cuối cùng." +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "Vật thể đích chỉ chứa một phần và không thể tách." +msgid "Split to parts" +msgstr "Tách thành phần" + msgid "Assembly" msgstr "Lắp ráp" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "Thông tin connector cắt" @@ -2729,6 +2993,9 @@ msgstr "Phạm vi chiều cao" msgid "Settings for height range" msgstr "Cài đặt cho phạm vi chiều cao" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "Lớp" @@ -2751,6 +3018,9 @@ msgstr "Loại:" msgid "Choose part type" msgstr "Chọn loại phần" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "Nhập tên mới" @@ -2776,6 +3046,9 @@ msgstr "" msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "Preset process bổ sung" @@ -2785,9 +3058,6 @@ msgstr "Xóa tham số" msgid "to" msgstr "đến" -msgid "Remove height range" -msgstr "Xóa phạm vi chiều cao" - msgid "Add height range" msgstr "Thêm phạm vi chiều cao" @@ -2999,6 +3269,9 @@ msgstr "Chọn một khe AMS rồi nhấn nút \"Nạp\" hoặc \"Tháo\" để msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "" @@ -3121,6 +3394,24 @@ msgstr "Xác nhận đã đùn" msgid "Check filament location" msgstr "Kiểm tra vị trí filament" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "" @@ -3174,6 +3465,62 @@ msgstr "Chế độ phát triển" msgid "Launch troubleshoot center" msgstr "" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "" + +msgid "Confirm" +msgstr "Xác nhận" + +msgid "Extruder" +msgstr "" + +msgid "Nozzle Selection" +msgstr "" + +msgid "Available Nozzles" +msgstr "" + +msgid "Nozzle Info" +msgstr "" + +msgid "Sync Nozzle status" +msgstr "" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "" + +msgid "Ignore" +msgstr "Bỏ qua" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3507,15 +3854,9 @@ msgstr "" msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "" -msgid "Version" -msgstr "Phiên bản" - msgid "AMS Materials Setting" msgstr "Cài đặt vật liệu AMS" -msgid "Confirm" -msgstr "Xác nhận" - msgid "Close" msgstr "Đóng" @@ -3536,12 +3877,12 @@ msgstr "tối thiểu" msgid "The input value should be greater than %1% and less than %2%" msgstr "Giá trị nhập vào phải lớn hơn %1% và nhỏ hơn %2%" -msgid "SN" -msgstr "" - msgid "Factors of Flow Dynamics Calibration" msgstr "Các hệ số của hiệu chỉnh flow động" +msgid "Wiki Guide" +msgstr "" + msgid "PA Profile" msgstr "" @@ -3630,7 +3971,7 @@ msgstr "Hiệu chỉnh hoàn tất. Vui lòng tìm đường đùn đồng đề msgid "Save" msgstr "Lưu" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "Sau" @@ -3705,6 +4046,19 @@ msgstr "" msgid "Nozzle" msgstr "Đầu phun" +msgid "Select Filament && Hotends" +msgstr "" + +msgid "Select Filament" +msgstr "" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "" @@ -4414,9 +4768,6 @@ msgstr "" msgid "Calibrating the detection position of nozzle clumping" msgstr "" -msgid "Unknown" -msgstr "Không rõ" - msgid "Update successful." msgstr "Cập nhật thành công." @@ -4928,9 +5279,6 @@ msgstr "" msgid "Regroup filament" msgstr "" -msgid "Wiki Guide" -msgstr "" - msgid "up to" msgstr "lên đến" @@ -4967,8 +5315,8 @@ msgstr "Jerk (mm/s)" msgid "Fan speed (%)" msgstr "Tốc độ quạt (%)" -msgid "Temperature (°C)" -msgstr "Nhiệt độ (°C)" +msgid "Temperature (℃)" +msgstr "Nhiệt độ (℃)" msgid "Volumetric flow rate (mm³/s)" msgstr "Tốc độ flow thể tích (mm³/s)" @@ -4986,9 +5334,6 @@ msgstr "Thay filament" msgid "Options" msgstr "Tùy chọn" -msgid "Extruder" -msgstr "" - msgid "Cost" msgstr "Chi phí" @@ -5001,6 +5346,7 @@ msgstr "" msgid "Color change" msgstr "Đổi màu" +msgctxt "Noun" msgid "Print" msgstr "In" @@ -5162,11 +5508,15 @@ msgstr "Tránh vùng hiệu chỉnh đùn" msgid "Align to Y axis" msgstr "Căn theo trục Y" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "Sau" + +msgctxt "Camera View" msgid "Left" msgstr "Trái" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "Phải" @@ -5191,9 +5541,6 @@ msgstr "Sắp xếp vật thể trên các plate đã chọn" msgid "Split to objects" msgstr "Tách thành vật thể" -msgid "Split to parts" -msgstr "Tách thành phần" - msgid "Assembly View" msgstr "Chế độ xem lắp ráp" @@ -5490,6 +5837,10 @@ msgstr "In plate" msgid "Export G-code file" msgstr "Xuất file G-code" +msgctxt "Verb" +msgid "Print" +msgstr "In" + msgid "Export plate sliced file" msgstr "Xuất file plate đã slice" @@ -5663,15 +6014,6 @@ msgstr "Xuất cấu hình hiện tại ra file" msgid "Export" msgstr "Xuất" -msgid "Sync Presets" -msgstr "" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "" - -msgid "You must be logged in to sync presets from cloud." -msgstr "" - msgid "Quit" msgstr "Thoát" @@ -5788,6 +6130,15 @@ msgstr "Xem" msgid "Preset Bundle" msgstr "" +msgid "Sync Presets" +msgstr "" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "" + +msgid "You must be logged in to sync presets from cloud." +msgstr "" + msgid "Syncing presets from cloud…" msgstr "" @@ -5907,6 +6258,9 @@ msgstr "Kết quả xuất" msgid "Select profile to load:" msgstr "Chọn hồ sơ để tải:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6070,9 +6424,6 @@ msgstr "Tải xuống file đã chọn từ máy in." msgid "Batch manage files." msgstr "Quản lý file hàng loạt." -msgid "Refresh" -msgstr "Làm mới" - msgid "Reload file list from printer." msgstr "Tải lại danh sách file từ máy in." @@ -6382,6 +6733,9 @@ msgstr "Tùy chọn in" msgid "Safety Options" msgstr "" +msgid "Hotends" +msgstr "" + msgid "Lamp" msgstr "Đèn" @@ -6415,6 +6769,12 @@ msgstr "" msgid "Current extruder is busy changing filament." msgstr "" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "" @@ -6465,9 +6825,6 @@ msgstr "Chỉ có hiệu lực trong khi in" msgid "Silent" msgstr "Im lặng" -msgid "Standard" -msgstr "Tiêu chuẩn" - msgid "Sport" msgstr "Thể thao" @@ -6501,6 +6858,12 @@ msgstr "Thêm ảnh" msgid "Delete Photo" msgstr "Xóa ảnh" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "Gửi" @@ -6688,6 +7051,9 @@ msgstr "Cách sử dụng chế độ chỉ LAN" msgid "Don't show this dialog again" msgstr "Không hiển thị hộp thoại này nữa" +msgid "Please refer to Wiki before use->" +msgstr "" + msgid "3D Mouse disconnected." msgstr "Chuột 3D đã ngắt kết nối." @@ -6938,25 +7304,16 @@ msgstr "Lưu lượng" msgid "Please change the nozzle settings on the printer." msgstr "" -msgid "Hardened Steel" -msgstr "Thép cứng" - -msgid "Stainless Steel" -msgstr "Thép không gỉ" - -msgid "Tungsten Carbide" -msgstr "" - msgid "Brass" msgstr "Đồng thau" msgid "High flow" msgstr "" -msgid "No wiki link available for this printer." +msgid "TPU High flow" msgstr "" -msgid "Refreshing" +msgid "No wiki link available for this printer." msgstr "" msgid "Unavailable while heating maintenance function is on." @@ -7081,6 +7438,15 @@ msgstr "" msgid "Configuration incompatible" msgstr "Cấu hình không tương thích" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "Mẹo" + msgid "Sync printer information" msgstr "" @@ -7107,6 +7473,9 @@ msgstr "Nhấp để chỉnh sửa preset" msgid "Project Filaments" msgstr "" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "Khối lượng xả" @@ -7334,9 +7703,6 @@ msgstr "" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "" -msgid "Tips" -msgstr "Mẹo" - msgid "The file does not contain any geometry data." msgstr "File không chứa bất kỳ dữ liệu hình học nào." @@ -7387,9 +7753,21 @@ msgstr "" "Hành động này sẽ phá vỡ sự tương ứng cắt.\n" "Sau đó tính nhất quán của model không thể được đảm bảo." +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "Đối tượng đã chọn không thể được tách." +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "" @@ -7416,6 +7794,9 @@ msgstr "Chọn file mới" msgid "File for the replacement wasn't selected" msgstr "Chưa chọn file để thay thế" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "" @@ -7462,6 +7843,9 @@ msgstr "Không thể tải lại:" msgid "Error during reload" msgstr "Lỗi trong quá trình tải lại" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "Có cảnh báo sau khi slice model:" @@ -8216,6 +8600,15 @@ msgstr "" msgid "Graphics" msgstr "" +msgid "Smooth normals" +msgstr "" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "" @@ -8231,16 +8624,7 @@ msgstr "" msgid "Shadows" msgstr "" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "" - -msgid "Smooth normals" -msgstr "" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" msgid "Anti-aliasing" @@ -8519,6 +8903,9 @@ msgstr "Preset không tương thích" msgid "My Printer" msgstr "" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "" @@ -8538,6 +8925,9 @@ msgstr "Thêm/Xóa preset" msgid "Edit preset" msgstr "Chỉnh sửa preset" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "" @@ -8569,9 +8959,6 @@ msgstr "Chọn/Xóa máy in (preset hệ thống)" msgid "Create printer" msgstr "Tạo máy in" -msgid "Empty" -msgstr "Trống" - msgid "Incompatible" msgstr "Không tương thích" @@ -8797,11 +9184,41 @@ msgstr "gửi hoàn tất" msgid "Error code" msgstr "Mã lỗi" -msgid "High Flow" +msgid "Error desc" +msgstr "Mô tả lỗi" + +msgid "Extra info" +msgstr "Thông tin bổ sung" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." msgstr "" #, c-format, boost-format @@ -8866,7 +9283,37 @@ msgstr "" msgid "nozzle" msgstr "" -msgid "both extruders" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." msgstr "" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." @@ -8880,10 +9327,17 @@ msgstr "" msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "" +msgid "both extruders" +msgstr "" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "" @@ -8994,9 +9448,6 @@ msgstr "" msgid "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." msgstr "" -msgid "Please refer to Wiki before use->" -msgstr "" - msgid "Current firmware does not support file transfer to internal storage." msgstr "" @@ -9180,6 +9631,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "Nhấp để đặt lại tất cả cài đặt về preset đã lưu cuối cùng." +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "Cần có prime tower để timelapse mượt. Có thể có khuyết điểm trên model nếu không có prime tower. Bạn có chắc chắn muốn tắt prime tower?" @@ -9256,9 +9710,6 @@ msgstr "Điều chỉnh về phạm vi đặt tự động?\n" msgid "Adjust" msgstr "Điều chỉnh" -msgid "Ignore" -msgstr "Bỏ qua" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "Tính năng thử nghiệm: Rút và cắt filament ở khoảng cách lớn hơn trong quá trình thay filament để giảm thiểu xả. Mặc dù có thể giảm đáng kể lượng xả, nó cũng có thể làm tăng nguy cơ tắc đầu phun hoặc các vấn đề in khác." @@ -9757,6 +10208,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "Bạn có chắc chắn %1% preset đã chọn?" +msgid "Select printers" +msgstr "Chọn máy in" + +msgid "Select profiles" +msgstr "Chọn hồ sơ" + #, c-format, boost-format msgid "" " - %s:\n" @@ -9984,6 +10441,12 @@ msgstr "Chuyển giá trị từ trái sang phải" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "Nếu được bật, hộp thoại này có thể được sử dụng để chuyển giá trị đã chọn từ trái sang preset bên phải." +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "Thêm file" @@ -10231,13 +10694,9 @@ msgstr "" msgid "Successfully synchronized nozzle and AMS number information." msgstr "" -msgid "Continue to sync filaments" +msgid "Do you want to continue to sync filaments?" msgstr "" -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "Hủy" - msgid "Successfully synchronized filament color from printer." msgstr "" @@ -10344,6 +10803,9 @@ msgstr "Đăng nhập" msgid "Login failed. Please try again." msgstr "" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "" @@ -10658,6 +11120,9 @@ msgstr "Tên máy in" msgid "Where to find your printer's IP and Access Code?" msgstr "Tìm IP và mã truy cập của máy in ở đâu?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "Kết nối" @@ -10722,6 +11187,9 @@ msgstr "Module cắt" msgid "Auto Fire Extinguishing System" msgstr "" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10740,6 +11208,9 @@ msgstr "Cập nhật thất bại" msgid "Update successful" msgstr "Cập nhật thành công" +msgid "Hotends on Rack" +msgstr "" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "Bạn có chắc chắn muốn cập nhật? Điều này sẽ mất khoảng 10 phút. Không tắt nguồn trong khi máy in đang cập nhật." @@ -10848,6 +11319,9 @@ msgstr "" msgid " can not be placed in the " msgstr "" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "Cầu bên trong" @@ -11561,7 +12035,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11575,7 +12049,7 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." @@ -11992,9 +12466,6 @@ msgstr "" "Hình học sẽ được giảm trước khi phát hiện góc sắc. Tham số này chỉ ra độ dài tối thiểu của độ lệch cho việc giảm.\n" "0 để vô hiệu hóa." -msgid "Select printers" -msgstr "Chọn máy in" - msgid "upward compatible machine" msgstr "máy tương thích ngược" @@ -12005,9 +12476,6 @@ msgstr "Điều kiện" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "Một biểu thức boolean sử dụng giá trị cấu hình của hồ sơ máy in đang hoạt động. Nếu biểu thức này đánh giá là đúng, hồ sơ này được coi là tương thích với hồ sơ máy in đang hoạt động." -msgid "Select profiles" -msgstr "Chọn hồ sơ" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "Một biểu thức boolean sử dụng giá trị cấu hình của hồ sơ in đang hoạt động. Nếu biểu thức này đánh giá là đúng, hồ sơ này được coi là tương thích với hồ sơ in đang hoạt động." @@ -12274,6 +12742,42 @@ msgstr "Mật độ bề mặt trên" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "Mật độ lớp bề mặt trên. Giá trị 100% tạo ra lớp trên hoàn toàn đặc, mịn . Giảm giá trị này dẫn đến bề mặt trên có kết cấu, theo mẫu bề mặt trên được chọn. Giá trị 0% sẽ dẫn đến chỉ thành trên lớp trên được tạo. Dành cho mục đích thẩm mỹ hoặc chức năng , không phải để sửa các vấn đề như đùn dư." +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "Mẫu bề mặt dưới" @@ -12602,12 +13106,18 @@ msgstr "" msgid "Auto For Match" msgstr "" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "" @@ -12872,6 +13382,12 @@ msgstr "" msgid "The filament is printable in extruder." msgstr "" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "Nhiệt độ làm mềm" @@ -12934,12 +13450,12 @@ msgstr "Mật độ infill thưa" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "Mật độ của infill thưa bên trong, 100% biến tất cả infill thưa thành infill đặc và mẫu infill đặc bên trong sẽ được sử dụng." -msgid "Align infill direction to model" -msgstr "Căn chỉnh hướng infill với model" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" msgid "Insert solid layers" @@ -13458,6 +13974,15 @@ msgstr "Vị trí sắp xếp tự động tốt nhất trong phạm vi [0,1] th msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "Bật tùy chọn này nếu máy có quạt làm mát phần phụ. Lệnh G-code : M106 P2 S(0-255)." +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13529,6 +14054,12 @@ msgstr "" "Bật điều này nếu máy in hỗ trợ lọc không khí\n" "Lệnh G-code: M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "" + +msgid "Enable this if printer support cooling filter" +msgstr "" + msgid "G-code flavor" msgstr "Kiểu G-code" @@ -14054,6 +14585,30 @@ msgstr "Tốc độ di chuyển tối thiểu" msgid "Minimum travel speed (M205 T)" msgstr "Tốc độ di chuyển tối thiểu (M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "Gia tốc tối đa để đùn" @@ -14602,6 +15157,9 @@ msgstr "Direct Drive" msgid "Bowden" msgstr "Bowden" +msgid "Hybrid" +msgstr "" + msgid "Enable filament dynamic map" msgstr "" @@ -14637,6 +15195,12 @@ msgstr "Tốc độ bỏ rút" msgid "Speed for reloading filament into the nozzle. Zero means same speed of retraction." msgstr "Tốc độ để nạp lại filament vào đầu phun. Không có nghĩa là cùng tốc độ rút." +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "Sử dụng rút firmware" @@ -14668,6 +15232,10 @@ msgstr "Căn chỉnh" msgid "Aligned back" msgstr "Căn chỉnh sau" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "Sau" + msgid "Random" msgstr "Ngẫu nhiên" @@ -14941,6 +15509,12 @@ msgstr "Nếu chế độ mịn hoặc truyền thống được chọn, video t msgid "Traditional" msgstr "Truyền thống" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "Thay đổi nhiệt độ" @@ -15028,6 +15602,18 @@ msgstr "Nạp tất cả extruder in" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "Nếu được bật, tất cả extruder in sẽ được nạp ở mép trước của bàn in lúc bắt đầu in." +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "Bán kính đóng khe slice" @@ -15414,7 +16000,7 @@ msgstr "" "Nếu được bật, tham số này cũng đặt biến G-code có tên chamber_temperature, có thể được sử dụng để truyền nhiệt độ buồng mong muốn cho macro bắt đầu in của bạn, hoặc macro ngâm nhiệt như thế này: PRINT_START (các biến khác) CHAMBER_TEMP=[chamber_temperature]. Điều này có thể hữu ích nếu máy in của bạn không hỗ trợ lệnh M141/M191, hoặc nếu bạn muốn xử lý ngâm nhiệt trong macro bắt đầu in nếu không có bộ sưởi buồng hoạt động được cài đặt." msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15469,6 +16055,45 @@ msgstr "Độ dày vỏ trên" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "Số lượng lớp đặc trên được tăng lên khi slice nếu độ dày được tính bởi lớp vỏ trên mỏng hơn giá trị này. Điều này có thể tránh vỏ quá mỏng khi chiều cao lớp nhỏ. 0 có nghĩa là cài đặt này bị tắt và độ dày vỏ trên được xác định tuyệt đối bởi lớp vỏ trên." +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "Tốc độ di chuyển nhanh hơn và không có đùn." @@ -15517,6 +16142,12 @@ msgstr "Hệ số xả" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "Khối lượng xả thực tế bằng hệ số xả nhân với khối lượng xả trong bảng." +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "Khối lượng nạp" @@ -15524,6 +16155,18 @@ msgstr "Khối lượng nạp" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "Khối lượng vật liệu để nạp extruder trên tower." +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "Độ rộng của prime tower." @@ -15816,6 +16459,57 @@ msgstr "Độ rộng thành tối thiểu" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "Độ rộng thành sẽ thay thế tính năng mỏng (theo Kích thước tính năng tối thiểu) của model. Nếu Độ rộng thành tối thiểu mỏng hơn độ dày của tính năng, thành sẽ trở nên dày như tính năng đó. Nó được biểu thị dưới dạng phần trăm trên đường kính đầu phun." +msgid "Hotend change time" +msgstr "" + +msgid "Time to change hotend." +msgstr "" + +msgid "Hotend change" +msgstr "" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "" + +msgid "Extruder change" +msgstr "" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "" + +msgid "length when change hotend" +msgstr "" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Detect narrow internal solid infills" msgstr "Phát hiện infill đặc bên trong hẹp" @@ -16579,12 +17273,6 @@ msgstr "" msgid "Calibration not supported" msgstr "Hiệu chỉnh không được hỗ trợ" -msgid "Error desc" -msgstr "Mô tả lỗi" - -msgid "Extra info" -msgstr "Thông tin bổ sung" - msgid "Flow Dynamics" msgstr "Động lực lưu lượng" @@ -16789,6 +17477,12 @@ msgstr "Vui lòng nhập tên bạn muốn lưu vào máy in." msgid "The name cannot exceed 40 characters." msgstr "Tên không thể vượt quá 40 ký tự." +msgid "Nozzle ID" +msgstr "" + +msgid "Standard Flow" +msgstr "" + msgid "Please find the best line on your plate" msgstr "Vui lòng tìm đường tốt nhất trên bàn của bạn" @@ -16879,9 +17573,6 @@ msgstr "" msgid "Nozzle Flow" msgstr "" -msgid "Nozzle Info" -msgstr "" - msgid "Filament position" msgstr "vị trí filament" @@ -16956,6 +17647,10 @@ msgstr "Lấy kết quả lịch sử thành công" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "Đang làm mới các bản ghi hiệu chỉnh động lực lưu lượng lịch sử" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "" + msgid "Action" msgstr "Hành động" @@ -18683,6 +19378,12 @@ msgstr "In thất bại" msgid "Removed" msgstr "Đã xóa" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "" @@ -18716,12 +19417,25 @@ msgstr "" msgid "(Sync with printer)" msgstr "" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "" @@ -18954,9 +19668,6 @@ msgstr "" msgid "Skipping objects." msgstr "" -msgid "Select Filament" -msgstr "" - msgid "Null Color" msgstr "" @@ -19475,6 +20186,16 @@ msgstr "" "Tránh cong vênh\n" "Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?" +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "Hủy" + +#~ msgid "Align infill direction to model" +#~ msgstr "Căn chỉnh hướng infill với model" + +#~ msgid "Print" +#~ msgstr "In" + #~ msgid "in" #~ msgstr "in" @@ -20289,9 +21010,6 @@ msgstr "" #~ msgid "Can't start this without SD card." #~ msgstr "Không thể bắt đầu mà không có thẻ SD." -#~ msgid "Update" -#~ msgstr "Cập nhật" - #~ msgid "Sensitivity of pausing is" #~ msgstr "Độ nhạy của tạm dừng là" diff --git a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po index eccc5752a3..0209b27104 100644 --- a/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po +++ b/localization/i18n/zh_CN/OrcaSlicer_zh_CN.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: Slic3rPE\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2026-06-11 12:37-0300\n" "Last-Translator: Handle \n" "Language-Team: \n" @@ -38,6 +38,24 @@ msgstr "AMS不支持TPU耗材。" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS不支持Bambu Lab PET-CF耗材。" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "打印TPU前请先执行冷拉以避免堵塞。您可以使用打印机上的冷拉维护功能。" @@ -50,6 +68,9 @@ msgstr "受潮的PVA会软化,并且可能粘在挤出机内,请在使用前 msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "泛光PLA的粗糙表面可能会加速AMS的磨损,尤其是AMS Lite的内部组件。" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "CF/GF耗材丝又硬又脆,在AMS中很容易断裂或卡住,请谨慎使用。" @@ -59,10 +80,90 @@ msgstr "PPS-CF材质较脆,用在工具头上方的弯曲PTFE管中可能会 msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF材质较脆,用在工具头上方的弯曲PTFE管中可能会断裂。" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s 不被 %s 挤出机支持。" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "高流量" + +msgid "Standard" +msgstr "标准" + +msgid "TPU High Flow" +msgstr "TPU高流量" + +msgid "Unknown" +msgstr "未定义" + +msgid "Hardened Steel" +msgstr "硬化钢" + +msgid "Stainless Steel" +msgstr "不锈钢" + +msgid "Tungsten Carbide" +msgstr "碳化钨" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "工具头和热端架可能会运动,请勿将手伸入机箱。" + +msgid "Warning" +msgstr "警告" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "热端信息可能不准确。是否重新读取热端?(断电期间热端信息可能会发生变化)。" + +msgid "I confirm all" +msgstr "确认无误" + +msgid "Re-read all" +msgstr "重新读取全部" + +msgid "Reading the hotends, please wait." +msgstr "正在读取热端信息,请稍候。" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "在热端升级过程中,工具头会移动。请勿将手伸入机箱内。" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "当前AMS湿度" @@ -93,6 +194,85 @@ msgstr "版本:" msgid "Latest version" msgstr "最新版本" +msgid "Row A" +msgstr "A排" + +msgid "Row B" +msgstr "B排" + +msgid "Toolhead" +msgstr "工具头" + +msgid "Empty" +msgstr "空" + +msgid "Error" +msgstr "错误" + +msgid "Induction Hotend Rack" +msgstr "感应热端架" + +msgid "Hotends Info" +msgstr "热端信息" + +msgid "Read All" +msgstr "读取全部" + +msgid "Reading " +msgstr "读取中 " + +msgid "Please wait" +msgstr "请稍候" + +msgid "Running..." +msgstr "运行中..." + +msgid "Raised" +msgstr "已升起" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "热端状态异常,当前不可用。请前往“设备 -> 升级”升级固件。" + +msgid "Abnormal Hotend" +msgstr "热端异常" + +msgid "Refresh" +msgstr "刷新" + +msgid "Refreshing" +msgstr "清爽" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "热端状态异常,目前不可用。请升级固件后重试。" + +msgid "Cancel" +msgstr "取消" + +msgid "Jump to the upgrade page" +msgstr "跳转至升级页面" + +msgid "SN" +msgstr "序列号" + +msgid "Version" +msgstr "版本" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "使用时间: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "当前盘存在动态分配喷嘴,不支持修改。" + +msgid "Hotend Rack" +msgstr "热端挂架" + +msgid "ToolHead" +msgstr "工具头" + +msgid "Nozzle information needs to be read" +msgstr "需要读取喷嘴信息" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "支撑绘制" @@ -165,6 +345,12 @@ msgstr "填充" msgid "Gap Fill" msgstr "缝隙填充" +msgid "Vertical" +msgstr "垂直" + +msgid "Horizontal" +msgstr "水平" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "绘制仅对由%1%选中的面片生效" @@ -260,12 +446,6 @@ msgstr "三角形" msgid "Height Range" msgstr "高度范围" -msgid "Vertical" -msgstr "垂直" - -msgid "Horizontal" -msgstr "水平" - msgid "Remove painted color" msgstr "移除已绘制的颜色" @@ -330,6 +510,7 @@ msgstr "Gizmo-旋转" msgid "Optimize orientation" msgstr "优化朝向" +msgctxt "Verb" msgid "Scale" msgstr "缩放" @@ -374,6 +555,9 @@ msgstr "缩放比例" msgid "Object operations" msgstr "对象操作" +msgid "Scale" +msgstr "缩放" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "零件操作" @@ -425,6 +609,10 @@ msgstr "重置当前旋转为打开旋转工具时的值" msgid "Reset current rotation to real zeros." msgstr "重置当前旋转为真实零位" +msgctxt "Noun" +msgid "Scale" +msgstr "缩放" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "大小" @@ -607,9 +795,6 @@ msgstr "与半径相关的间隔比例" msgid "Confirm connectors" msgstr "确认" -msgid "Cancel" -msgstr "取消" - msgid "Flip cut plane" msgstr "翻转剖切面" @@ -650,12 +835,12 @@ msgstr "切割为零件" msgid "Reset cutting plane and remove connectors" msgstr "重置切割平面并移除连接器" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "执行切割" -msgid "Warning" -msgstr "警告" - msgid "Invalid connectors detected" msgstr "检测到无效连接件" @@ -684,6 +869,13 @@ msgstr "槽所在的切割平面无效" msgid "Connector" msgstr "连接件" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "按平面切割" @@ -731,9 +923,6 @@ msgstr "简化" msgid "Simplification is currently only allowed when a single part is selected" msgstr "仅支持对单个零件做简化" -msgid "Error" -msgstr "错误" - msgid "Extra high" msgstr "非常高" @@ -2009,6 +2198,9 @@ msgstr "预设包 %s 访问未授权。" msgid "Loading user preset" msgstr "正在加载用户预设" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s 已被移除。" @@ -2022,6 +2214,18 @@ msgstr "选择语言" msgid "Language" msgstr "语言" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2655,6 +2859,45 @@ msgstr "点击此图标可编辑这个对象的颜色绘制" msgid "Click the icon to shift this object to the bed" msgstr "点击这个图标可将对象移动到热床上" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "载入文件中" @@ -2664,6 +2907,9 @@ msgstr "错误!" msgid "Failed to get the model data in the current file." msgstr "无法获取当前文件中的模型数据。" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "通用" @@ -2676,6 +2922,12 @@ msgstr "切换到对象设置模式,以编辑所选对象的工艺参数" msgid "Remove paint-on fuzzy skin" msgstr "移除手绘绒毛表面" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "移除高度范围" + msgid "Delete connector from object which is a part of cut" msgstr "删除的连接件属于切割对象的一部分" @@ -2705,12 +2957,24 @@ msgstr "删除所有连接件" msgid "Deleting the last solid part is not allowed." msgstr "不允许删除对象的最后一个实体零件。" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "目标对象只包含一个零件,无法分割" +msgid "Split to parts" +msgstr "拆分为零件" + msgid "Assembly" msgstr "组合体" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "切割连接件信息" @@ -2744,6 +3008,9 @@ msgstr "高度范围" msgid "Settings for height range" msgstr "高度范围设置" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "层" @@ -2766,6 +3033,9 @@ msgstr "类型:" msgid "Choose part type" msgstr "选择零件类型" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "输入新名称" @@ -2791,6 +3061,9 @@ msgstr "\"%s\" 在此次细分后将超过 100 万个面,这可能会增加切 msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "\"%s\" 零件的网格包含错误,请先修复。" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "附加工艺预设" @@ -2800,9 +3073,6 @@ msgstr "删除参数" msgid "to" msgstr "到" -msgid "Remove height range" -msgstr "移除高度范围" - msgid "Add height range" msgstr "添加高度范围" @@ -3013,6 +3283,9 @@ msgstr "选择一个AMS槽位,然后点击“进料”或“退料”按钮以 msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "因耗材类型未知,所以需要执行此操作。请指定目标耗材的信息。" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "在打印过程中更改风扇速度可能影响打印质量,请谨慎选择。" @@ -3135,6 +3408,24 @@ msgstr "确认挤出" msgid "Check filament location" msgstr "检查耗材丝位置" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "最高温度不可超过 " @@ -3187,6 +3478,62 @@ msgstr "开发者模式" msgid "Launch troubleshoot center" msgstr "启动故障排查中心" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "请设置喷嘴数量" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "错误:无法将两个喷嘴数量都设置为零。" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "错误:喷嘴数量不可以超过%d。" + +msgid "Confirm" +msgstr "确定" + +msgid "Extruder" +msgstr "挤出机" + +msgid "Nozzle Selection" +msgstr "喷嘴选择" + +msgid "Available Nozzles" +msgstr "可用喷嘴" + +msgid "Nozzle Info" +msgstr "喷嘴信息" + +msgid "Sync Nozzle status" +msgstr "同步喷嘴状态" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "注意:不支持在打印中混用不同直径的喷嘴。如果所选尺寸仅存在于一个挤出机上,将强制使用单挤出机打印。" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "刷新 %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "检测到未知喷嘴。请刷新以更新信息(未刷新的喷嘴将在切片时被排除)。请核对喷嘴直径和流量是否与显示值一致。" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "检测到未知喷嘴。请刷新以更新信息(未刷新的喷嘴将在切片时被排除)。" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "请核对喷嘴直径和流量是否与显示值一致。" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "您的打印机安装了不同的喷嘴。请选择一个喷嘴进行本次打印。" + +msgid "Ignore" +msgstr "忽略" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3518,15 +3865,9 @@ msgstr "OrcaSlicer 也始于同样的精神,汲取了 PrusaSlicer、BambuStudi msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "如今,OrcaSlicer 是 3D 打印社区中使用最广泛、开发最活跃的开源切片软件。它的许多创新已被其他切片软件采用,成为推动整个行业发展的力量。" -msgid "Version" -msgstr "版本" - msgid "AMS Materials Setting" msgstr "AMS 材料设置" -msgid "Confirm" -msgstr "确定" - msgid "Close" msgstr "关闭" @@ -3545,12 +3886,12 @@ msgstr "最小" msgid "The input value should be greater than %1% and less than %2%" msgstr "输入的范围应当在 %1% 和 %2% 之间" -msgid "SN" -msgstr "序列号" - msgid "Factors of Flow Dynamics Calibration" msgstr "动态流量校准系数" +msgid "Wiki Guide" +msgstr "维基指南" + msgid "PA Profile" msgstr "PA 配置文件" @@ -3639,7 +3980,7 @@ msgstr "校准完成。如下图中的示例,请在您的热床上找到最均 msgid "Save" msgstr "保存" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "背面" @@ -3723,6 +4064,19 @@ msgstr "右喷嘴" msgid "Nozzle" msgstr "喷嘴" +msgid "Select Filament && Hotends" +msgstr "选择材料预设和喷头" + +msgid "Select Filament" +msgstr "选择耗材" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "使用当前喷嘴打印可能会产生额外 %0.2f 克废料。" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "注意:耗材类型(%s)与切片文件中的耗材类型(%s)不匹配。如果您想使用此插槽,您可以安装 %s 而不是 %s ,并在“设备”页面上更改插槽信息。" @@ -4427,9 +4781,6 @@ msgstr "测量面" msgid "Calibrating the detection position of nozzle clumping" msgstr "校准喷嘴结块检测位置" -msgid "Unknown" -msgstr "未定义" - msgid "Update successful." msgstr "更新成功。" @@ -4941,9 +5292,6 @@ msgstr "设置为最佳" msgid "Regroup filament" msgstr "重新组合耗材丝" -msgid "Wiki Guide" -msgstr "维基指南" - msgid "up to" msgstr "达到" @@ -4980,7 +5328,7 @@ msgstr "抖动 (mm/s)" msgid "Fan speed (%)" msgstr "风扇速度(%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "温度(℃)" msgid "Volumetric flow rate (mm³/s)" @@ -4999,9 +5347,6 @@ msgstr "材料切换" msgid "Options" msgstr "选项" -msgid "Extruder" -msgstr "挤出机" - msgid "Cost" msgstr "成本" @@ -5014,6 +5359,7 @@ msgstr "工具更换" msgid "Color change" msgstr "颜色更换" +msgctxt "Noun" msgid "Print" msgstr "打印" @@ -5178,11 +5524,15 @@ msgstr "避开挤出校准区域" msgid "Align to Y axis" msgstr "对齐到Y轴" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "背面" + +msgctxt "Camera View" msgid "Left" msgstr "左" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "右" @@ -5207,9 +5557,6 @@ msgstr "单盘整理" msgid "Split to objects" msgstr "拆分为对象" -msgid "Split to parts" -msgstr "拆分为零件" - msgid "Assembly View" msgstr "装配体视图" @@ -5510,6 +5857,10 @@ msgstr "打印单盘" msgid "Export G-code file" msgstr "导出G-code文件" +msgctxt "Verb" +msgid "Print" +msgstr "打印" + msgid "Export plate sliced file" msgstr "导出单盘切片文件" @@ -5683,15 +6034,6 @@ msgstr "导出当前选择的预设" msgid "Export" msgstr "导出" -msgid "Sync Presets" -msgstr "同步预设" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "从 OrcaCloud 拉取并应用最新的预设" - -msgid "You must be logged in to sync presets from cloud." -msgstr "您必须登录后才能从云端同步预设。" - msgid "Quit" msgstr "退出程序" @@ -5808,6 +6150,15 @@ msgstr "视图" msgid "Preset Bundle" msgstr "预设包" +msgid "Sync Presets" +msgstr "同步预设" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "从 OrcaCloud 拉取并应用最新的预设" + +msgid "You must be logged in to sync presets from cloud." +msgstr "您必须登录后才能从云端同步预设。" + msgid "Syncing presets from cloud…" msgstr "正在从云端同步预设…" @@ -5927,6 +6278,9 @@ msgstr "导出结果" msgid "Select profile to load:" msgstr "选择要加载的配置:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6092,9 +6446,6 @@ msgstr "从打印机中下载选择的文件" msgid "Batch manage files." msgstr "批量管理文件" -msgid "Refresh" -msgstr "刷新" - msgid "Reload file list from printer." msgstr "从打印机重新加载文件列表。" @@ -6404,6 +6755,9 @@ msgstr "打印选项" msgid "Safety Options" msgstr "安全选项" +msgid "Hotends" +msgstr "热端" + msgid "Lamp" msgstr "LED灯" @@ -6437,6 +6791,12 @@ msgstr "打印暂停时,仅外部插槽支持耗材装载和卸载。" msgid "Current extruder is busy changing filament." msgstr "当前挤出机正忙于更换耗材丝。" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "当前插槽已被加载。" @@ -6487,9 +6847,6 @@ msgstr "仅在打印过程中生效" msgid "Silent" msgstr "静音" -msgid "Standard" -msgstr "标准" - msgid "Sport" msgstr "运动" @@ -6523,6 +6880,12 @@ msgstr "添加照片" msgid "Delete Photo" msgstr "删除照片" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "提交" @@ -6704,6 +7067,9 @@ msgstr "如何使用仅局域网模式" msgid "Don't show this dialog again" msgstr "不再显示此对话框?" +msgid "Please refer to Wiki before use->" +msgstr "使用前请参考 Wiki->" + msgid "3D Mouse disconnected." msgstr "3D鼠标断连。" @@ -6952,27 +7318,18 @@ msgstr "流动" msgid "Please change the nozzle settings on the printer." msgstr "请更改打印机上的喷嘴设置。" -msgid "Hardened Steel" -msgstr "硬化钢" - -msgid "Stainless Steel" -msgstr "不锈钢" - -msgid "Tungsten Carbide" -msgstr "碳化钨" - msgid "Brass" msgstr "黄铜" msgid "High flow" msgstr "高流量" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "没有适用于此打印机的 wiki 链接。" -msgid "Refreshing" -msgstr "清爽" - msgid "Unavailable while heating maintenance function is on." msgstr "加热维护功能开启时不可用。" @@ -7095,6 +7452,15 @@ msgstr "开关直径" msgid "Configuration incompatible" msgstr "配置不兼容" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "提示" + msgid "Sync printer information" msgstr "同步打印机信息" @@ -7123,6 +7489,9 @@ msgstr "点击编辑配置" msgid "Project Filaments" msgstr "项目耗材丝" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "冲刷体积" @@ -7347,9 +7716,6 @@ msgstr "连接的打印机是 %s。它必须与打印预设的项目相匹配。 msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "您想要同步打印机信息并自动切换预设吗?" -msgid "Tips" -msgstr "提示" - msgid "The file does not contain any geometry data." msgstr "此文件不包含任何几何数据。" @@ -7397,9 +7763,21 @@ msgid "" "After that, model consistency can't be guaranteed." msgstr "您正尝试删除切割对象的一部分,这将破坏切割对应关系,删除之后,将无法再保证模型的一致性。" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "选中的模型不可分裂。" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "禁用自动落板以保留 Z 轴定位?\n" @@ -7426,6 +7804,9 @@ msgstr "选择新文件" msgid "File for the replacement wasn't selected" msgstr "未选择替换文件" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "选择要替换的文件夹" @@ -7472,6 +7853,9 @@ msgstr "无法重新加载:" msgid "Error during reload" msgstr "重新加载时发生错误" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "模型切片警告:" @@ -8234,6 +8618,15 @@ msgstr "加载文件后清除我对同步打印机预设的选择。" msgid "Graphics" msgstr "图形" +msgid "Smooth normals" +msgstr "平滑法线" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Phong 着色" @@ -8249,20 +8642,8 @@ msgstr "在写实渲染中应用 SSAO。" msgid "Shadows" msgstr "阴影" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "在写实渲染中渲染投射到打印板上的阴影。" - -msgid "Smooth normals" -msgstr "平滑法线" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"在写实渲染中应用平滑法线。\n" -"\n" -"需要手动重新加载场景才能生效(在 3D 视图中右键单击 →“重新加载全部”)。" msgid "Anti-aliasing" msgstr "抗锯齿" @@ -8558,6 +8939,9 @@ msgstr "不兼容的预设" msgid "My Printer" msgstr "我的打印机" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "左耗材" @@ -8577,6 +8961,9 @@ msgstr "添加/删除配置" msgid "Edit preset" msgstr "编辑预设" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "未指定" @@ -8608,9 +8995,6 @@ msgstr "选择/移除打印机(系统预设)" msgid "Create printer" msgstr "创建打印机" -msgid "Empty" -msgstr "空" - msgid "Incompatible" msgstr "不兼容的预设" @@ -8842,12 +9226,42 @@ msgstr "发送完成" msgid "Error code" msgstr "错误代码" -msgid "High Flow" -msgstr "高流量" +msgid "Error desc" +msgstr "错误描述" + +msgid "Extra info" +msgstr "额外信息" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s(%s)的喷嘴流量设置与切片文件(%s)不匹配。请确保安装的喷嘴与打印机中的设置相符,然后在切片时设置相应的打印机预设。" +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8911,8 +9325,38 @@ msgstr "成本 %dg 耗材和 %d 的变化超过最佳分组。" msgid "nozzle" msgstr "喷嘴" -msgid "both extruders" -msgstr "两台挤出机" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s(%s)的喷嘴流量设置与切片文件(%s)不匹配。请确保安装的喷嘴与打印机中的设置相符,然后在切片时设置相应的打印机预设。" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "提示:如果您最近更换了打印机喷嘴,请进入“设备 -> 打印机部件”更改喷嘴设置。" @@ -8925,10 +9369,17 @@ msgstr "当前打印机的%s 直径(%.1fmm)与切片文件(%.1fmm)不匹配。 msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "当前喷嘴直径 (%.1fmm) 与切片文件 (%.1fmm) 不匹配。请确保安装的喷嘴与打印机中的设置相符,然后在切片时设置相应的打印机预设。" +msgid "both extruders" +msgstr "两台挤出机" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "当前材料的硬度(%s)超过%s(%s)的硬度。请验证喷嘴或材料设置,然后重试。" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] 需要在高温环境下打印,请关好门。" @@ -9039,9 +9490,6 @@ msgstr "当前固件最多支持 16 种材质。您可以在准备页面将材 msgid "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." msgstr "外部耗材的类型未知,或与切片文件中的耗材类型不匹配。请确认您已在外部料盘中安装了正确的耗材。" -msgid "Please refer to Wiki before use->" -msgstr "使用前请参考 Wiki->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "当前固件不支持文件传输到内部存储器。" @@ -9223,6 +9671,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "点击以将所有设置还原到最后一次保存的版本。" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "切换喷嘴需要擦料塔,否则打印件上可能会有瑕疵。您确定要关闭擦料塔吗?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "平滑模式的延时摄影需要擦料塔,否则打印件上可能会有瑕疵。您确定要关闭擦料塔吗?" @@ -9306,9 +9757,6 @@ msgstr "是否自动调整到范围内?\n" msgid "Adjust" msgstr "调整" -msgid "Ignore" -msgstr "忽略" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "实验性选项。在更换耗材丝时,将耗材丝回抽一段距离后再切断以最小化冲刷。虽然这可以显著减少冲刷,但也可能增加喷嘴堵塞或其他打印问题的风险。" @@ -9810,6 +10258,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "确定要%1%所选预设吗?" +msgid "Select printers" +msgstr "选择打印机" + +msgid "Select profiles" +msgstr "选择配置文件" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10058,6 +10512,12 @@ msgstr "从左到右的转移值" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "如果启用,此对话框可用于将选定的值从左侧预设传输到右侧预设。" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "添加文件" @@ -10311,12 +10771,8 @@ msgstr "成功同步喷嘴信息。" msgid "Successfully synchronized nozzle and AMS number information." msgstr "已成功同步喷嘴和 AMS 编号信息。" -msgid "Continue to sync filaments" -msgstr "继续同步耗材丝" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "取消" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "已成功同步打印机的耗材丝颜色。" @@ -10425,6 +10881,9 @@ msgstr "登录" msgid "Login failed. Please try again." msgstr "登录失败。请重试。" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[需要操作] " @@ -10742,6 +11201,9 @@ msgstr "打印机名称" msgid "Where to find your printer's IP and Access Code?" msgstr "在哪里可以找到打印机的IP和访问码?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "连接" @@ -10806,6 +11268,9 @@ msgstr "切割模块" msgid "Auto Fire Extinguishing System" msgstr "自动灭火系统" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "测试版" @@ -10824,6 +11289,9 @@ msgstr "更新失败" msgid "Update successful" msgstr "更新成功" +msgid "Hotends on Rack" +msgstr "热端&挂架" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "确定要更新吗?更新需要大约10分钟,在此期间请勿关闭电源。" @@ -10933,6 +11401,9 @@ msgstr "分组错误:" msgid " can not be placed in the " msgstr "不能放置在" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "内部搭桥" @@ -11644,19 +12115,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"外部桥接角度覆盖。\n" -"如果保持为零,每个具体桥接的桥接角度都会自动计算。\n" -"否则将按以下方式使用所提供的角度:\n" -" - 绝对坐标\n" -" - 绝对坐标 + 模型旋转:如果启用了“对齐填充方向到模型”\n" -" - 最佳自动角度 + 此值:如果启用了“相对桥接角度”\n" -"\n" -"使用 180° 表示绝对角度为零。" msgid "Internal bridge infill direction" msgstr "内部桥接填充方向" @@ -11666,19 +12129,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"内部桥接角度覆盖。\n" -"如果保持为零,每个具体桥接的桥接角度都会自动计算。\n" -"否则将按以下方式使用所提供的角度:\n" -" - 绝对坐标\n" -" - 绝对坐标 + 模型旋转:如果启用了“对齐填充方向到模型”\n" -" - 最佳自动角度 + 此值:如果启用了“相对桥接角度”\n" -"\n" -"使用 180° 表示绝对角度为零。" msgid "Relative bridge angle" msgstr "相对桥接角度" @@ -12144,9 +12599,6 @@ msgstr "" "在检测尖锐角度之前,几何形状将被简化。此参数表示简化的最小偏差长度。\n" "设为0以停用" -msgid "Select printers" -msgstr "选择打印机" - msgid "upward compatible machine" msgstr "向上兼容的机器" @@ -12157,9 +12609,6 @@ msgstr "条件" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "使用活动打印机配置文件的配置值的布尔表达式。如果此表达式计算为 true,则此配置文件将被视为与活动打印机配置文件兼容。" -msgid "Select profiles" -msgstr "选择配置文件" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "使用活动打印配置文件的配置值的布尔表达式。如果此表达式计算为 true,则此配置文件将被视为与活动打印配置文件兼容。" @@ -12437,6 +12886,42 @@ msgstr "" "100% 的值会创建一个完全实心、平滑的顶面。降低此值会根据所选的顶面图案生成有纹理的顶面。0% 的值将只生成顶层的墙。\n" "此选项仅为美观或功能性目的,而不是为了解决过量挤出等问题。" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "底面图案" @@ -12762,12 +13247,18 @@ msgstr "自动冲洗" msgid "Auto For Match" msgstr "自动匹配" +msgid "Nozzle Manual" +msgstr "" + msgid "Flush temperature" msgstr "冲洗温度" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "冲洗耗材丝时的温度。 0 表示推荐喷嘴温度范围的上限。" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "冲洗体积流量" @@ -13046,6 +13537,12 @@ msgstr "可打印耗材" msgid "The filament is printable in extruder." msgstr "此耗材可通过挤出机打印" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "软化温度" @@ -13110,15 +13607,13 @@ msgstr "稀疏填充密度" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "内部稀疏填充的密度,100%会将所有稀疏填充变为实心填充,并将使用内部实心填充图案。" -msgid "Align infill direction to model" -msgstr "对齐填充方向到模型" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"使填充、桥接、熨烫和表面填充的方向跟随模型在打印板上的朝向。\n" -"启用后,这些方向会随模型一起旋转,以保持最佳的强度特性。" msgid "Insert solid layers" msgstr "插入实心层" @@ -13660,6 +14155,15 @@ msgstr "最佳自动排列位置在[0,1]范围内,相对于打印床形状。" msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "如果打印机有辅助风扇,可以开启此选项。G-code指令:M106 P2 S(0-255)" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13731,6 +14235,12 @@ msgstr "" "如果打印机支持空气过滤/排气风扇,可以开启此选项\n" "G-code指令:M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "开启冷却过滤" + +msgid "Enable this if printer support cooling filter" +msgstr "开启该功能后,当腔温过高时,会自动关闭过滤以提高冷却效果" + msgid "G-code flavor" msgstr "G-code风格" @@ -14262,6 +14772,30 @@ msgstr "最小空驶速度" msgid "Minimum travel speed (M205 T)" msgstr "最小空驶速度(M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "挤出最大加速度" @@ -14828,6 +15362,9 @@ msgstr "直驱(近程)" msgid "Bowden" msgstr "远程挤出机" +msgid "Hybrid" +msgstr "混合" + msgid "Enable filament dynamic map" msgstr "启用耗材动态映射" @@ -14865,6 +15402,12 @@ msgstr "" "向喷嘴重新装填耗材的速度。\n" "设为 0 则使用与回抽相同的速度。" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "使用固件回抽" @@ -14896,6 +15439,10 @@ msgstr "对齐" msgid "Aligned back" msgstr "背部对齐" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "背面" + msgid "Random" msgstr "随机" @@ -15175,6 +15722,12 @@ msgstr "如果启用平滑模式或者传统模式,将在每次打印时生成 msgid "Traditional" msgstr "传统模式" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "软化温度" @@ -15262,6 +15815,18 @@ msgstr "所有挤出机画线" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "如果启用,所有挤出机将在打印开始时在床前画线" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "切片间隙闭合半径" @@ -15650,7 +16215,7 @@ msgid "" msgstr "对于 ABS、ASA、PC 和 PA 等高温材料,较高的腔室温度有助于抑制或减少翘曲,并有可能提高层间粘合强度。但同时,较高的腔室温度会降低 ABS 和 ASA 的空气过滤效率。 对于 PLA、PETG、TPU、PVA 等低温材料,应禁用此选项(设置为 0),因为腔室温度应较低,以避免热断时材料软化导致挤出机堵塞。 如果启用,此参数还会设置一个名为 chamber_temple 的 G-code 变量,该变量可用于将所需的腔室温度传递给打印启动宏,或热浸宏,如下所示:PRINT_START(其他变量)CHAMBER_TEMP=[cham​​ber_Temperature]。如果您的打印机不支持 M141/M191 命令,或者如果您希望在未安装活动室加热器的情况下在打印启动宏中处理热浸,则这可能很有用。" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15704,6 +16269,45 @@ msgstr "顶部壳体厚度" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "如果由顶部壳体层数算出的厚度小于这个数值,那么切片时将自动增加顶部壳体层数。这能够避免当层高很小时,顶部壳体过薄。0 表示关闭这个设置,同时顶部壳体的厚度完全由顶部壳体层数决定" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "空驶的速度。空驶是无挤出量的快速移动。" @@ -15752,6 +16356,12 @@ msgstr "冲刷量乘数" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "实际冲刷量等于冲刷量乘数乘以表格单元中的冲刷量" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "清理量" @@ -15759,6 +16369,18 @@ msgstr "清理量" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "擦拭塔上的清理量" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "擦拭塔宽度" @@ -16055,6 +16677,57 @@ msgstr "最窄墙宽度" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "用于替换模型上的细小特征(根据最小特征尺寸决定)的墙线宽。如果最小墙宽度小于最小特征宽度,则墙将变得和特征本身一样厚。本设置以喷嘴直径的百分比表示。" +msgid "Hotend change time" +msgstr "热端更换时间" + +msgid "Time to change hotend." +msgstr "热端更换时间。" + +msgid "Hotend change" +msgstr "热端更换" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "更换热端时,建议从原热端中挤出一定长度的耗材丝。这有助于最大限度地减少喷嘴漏料。" + +msgid "Extruder change" +msgstr "挤出机更换" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "为了防止溢料,预冲刷完成后,喷嘴会进行一段时间的反向空驶。该设置用于定义空驶时间。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "为了防止溢料,预冲刷时会降低喷嘴温度。因此,预冲刷时间必须大于冷却时间。0 表示禁用。" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "换出挤出机前的最大预冲刷体积速度,-1 表示使用最大体积速度。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "为防止溢料,预冲刷过程中喷嘴温度会降低。注意:仅触发冷却指令并启动风扇,不保证达到目标温度。0 表示禁用。" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "热端更换前的最大预冲刷体积速度,其中 -1 表示使用最大体积速度。" + +msgid "length when change hotend" +msgstr "换热端时回抽量" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "当修改此回抽数值时,将用于热端内在更换热端前回抽的耗材量。" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "换热端所需的擦料塔上的清理量。" + +msgid "Preheat temperature delta" +msgstr "" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "" + msgid "Detect narrow internal solid infills" msgstr "识别狭窄的内部实心填充" @@ -16808,12 +17481,6 @@ msgstr "" msgid "Calibration not supported" msgstr "不支持校准" -msgid "Error desc" -msgstr "错误描述" - -msgid "Extra info" -msgstr "额外信息" - msgid "Flow Dynamics" msgstr "动态流量" @@ -17020,6 +17687,12 @@ msgstr "请输入要保存到打印机的名称。" msgid "The name cannot exceed 40 characters." msgstr "名称不能超过40个字符。" +msgid "Nozzle ID" +msgstr "喷嘴 ID" + +msgid "Standard Flow" +msgstr "标准流量" + msgid "Please find the best line on your plate" msgstr "请在您的打印板上找到最佳线条" @@ -17110,9 +17783,6 @@ msgstr "AMS 和喷嘴信息同步" msgid "Nozzle Flow" msgstr "喷嘴流量" -msgid "Nozzle Info" -msgstr "喷嘴信息" - msgid "Filament position" msgstr "耗材丝位置" @@ -17187,6 +17857,10 @@ msgstr "成功获取历史结果" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "刷新历史流量动态校准记录" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "注意:%s上的热端编号与刀架绑定。当热端移动至新刀架时,其编号会自动更新。" + msgid "Action" msgstr "操作" @@ -18941,6 +19615,12 @@ msgstr "打印失败" msgid "Removed" msgstr "移除" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "不再提醒" @@ -18974,12 +19654,25 @@ msgstr "视频指南" msgid "(Sync with printer)" msgstr "(与打印机同步)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "我们将按照这种分组方法进行切片:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "提示:您可以拖动耗材以将它们重新分配到不同的喷嘴。" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "当前盘的耗材分组方法由切片盘按钮上的下拉选项确定。" @@ -19211,9 +19904,6 @@ msgstr "此操作无法撤消。继续?" msgid "Skipping objects." msgstr "跳过对象。" -msgid "Select Filament" -msgstr "选择耗材" - msgid "Null Color" msgstr "空颜色" @@ -19737,6 +20427,77 @@ msgstr "" "避免翘曲\n" "您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "在写实渲染中渲染投射到打印板上的阴影。" + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "在写实渲染中应用平滑法线。\n" +#~ "\n" +#~ "需要手动重新加载场景才能生效(在 3D 视图中右键单击 →“重新加载全部”)。" + +#~ msgid "Continue to sync filaments" +#~ msgstr "继续同步耗材丝" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "取消" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "外部桥接角度覆盖。\n" +#~ "如果保持为零,每个具体桥接的桥接角度都会自动计算。\n" +#~ "否则将按以下方式使用所提供的角度:\n" +#~ " - 绝对坐标\n" +#~ " - 绝对坐标 + 模型旋转:如果启用了“对齐填充方向到模型”\n" +#~ " - 最佳自动角度 + 此值:如果启用了“相对桥接角度”\n" +#~ "\n" +#~ "使用 180° 表示绝对角度为零。" + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "内部桥接角度覆盖。\n" +#~ "如果保持为零,每个具体桥接的桥接角度都会自动计算。\n" +#~ "否则将按以下方式使用所提供的角度:\n" +#~ " - 绝对坐标\n" +#~ " - 绝对坐标 + 模型旋转:如果启用了“对齐填充方向到模型”\n" +#~ " - 最佳自动角度 + 此值:如果启用了“相对桥接角度”\n" +#~ "\n" +#~ "使用 180° 表示绝对角度为零。" + +#~ msgid "Align infill direction to model" +#~ msgstr "对齐填充方向到模型" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "使填充、桥接、熨烫和表面填充的方向跟随模型在打印板上的朝向。\n" +#~ "启用后,这些方向会随模型一起旋转,以保持最佳的强度特性。" + +#~ msgid "Print" +#~ msgstr "打印" + #~ msgid "in" #~ msgstr "在" diff --git a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po index 1c8f7b256a..dbca75c52d 100644 --- a/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po +++ b/localization/i18n/zh_TW/OrcaSlicer_zh_TW.po @@ -9,7 +9,7 @@ msgid "" msgstr "" "Project-Id-Version: Orca Slicer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-07-07 10:05-0300\n" +"POT-Creation-Date: 2026-07-13 16:24-0300\n" "PO-Revision-Date: 2025-11-28 13:48-0600\n" "Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n" "Language-Team: \n" @@ -41,6 +41,24 @@ msgstr "AMS 不支援 TPU 線材。" msgid "AMS does not support 'Bambu Lab PET-CF'." msgstr "AMS 不支援「Bambu Lab PET-CF」。" +msgid "The current filament doesn't support the E3D high-flow nozzle and can't be used." +msgstr "" + +msgid "The current filament doesn't support the TPU high-flow nozzle and can't be used." +msgstr "" + +msgid "Auto dynamic flow calibration is not supported for TPU filament." +msgstr "" + +msgid "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." +msgstr "" + +msgid "How to feed TPU filament." +msgstr "" + +msgid "How to feed TPU filament on X2D." +msgstr "" + msgid "Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer." msgstr "列印 TPU 前請先進行冷抽以避免堵塞,您可以在列印設備上使用冷抽維護功能。" @@ -53,6 +71,9 @@ msgstr "潮濕的 PVA 會變軟並可能卡在擠出機中,請在使用前乾 msgid "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." msgstr "PLA Glow 的粗糙表面可能加速 AMS 系統的磨損,尤其是 AMS Lite 的內部零件。" +msgid "PLA Glow may wear the AMS first stage feeder. Use an external spool instead." +msgstr "" + msgid "CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution." msgstr "含 CF/GF 線材又硬又脆,在 AMS 中很容易斷裂或卡住,請謹慎使用。" @@ -62,10 +83,90 @@ msgstr "PPS-CF 較脆,可能在工具頭上方的彎曲 PTFE 管中斷裂。" msgid "PPA-CF is brittle and could break in bended PTFE tube above Toolhead." msgstr "PPA-CF 較脆,可能在工具頭上方的彎曲 PTFE 管中斷裂。" +msgid "Default settings may affect print quality. Adjust as needed for best results." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue." +msgstr "" + #, c-format, boost-format msgid "%s is not supported by %s extruder." msgstr "%s 不受 %s 擠出機支援。" +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!" +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution." +msgstr "" + +#, c-format, boost-format +msgid "There may be print quality issues when printing '%s' with %s extruder. Use with caution." +msgstr "" + +msgid "High Flow" +msgstr "高流量" + +msgid "Standard" +msgstr "標準模式(100%)" + +msgid "TPU High Flow" +msgstr "TPU高流量" + +msgid "Unknown" +msgstr "未定義" + +msgid "Hardened Steel" +msgstr "硬化鋼" + +msgid "Stainless Steel" +msgstr "不鏽鋼" + +msgid "Tungsten Carbide" +msgstr "碳化鎢" + +msgid "The toolhead and hotend rack may move. Please keep your hands away from the chamber." +msgstr "工具頭和熱端架可能會運動,請勿將手伸入機箱。" + +msgid "Warning" +msgstr "警告" + +msgid "Hotend information may be inaccurate. Would you like to re-read the hotend? (Hotend information may change during power-off)." +msgstr "熱端資訊可能不準確。是否重新讀取熱端?(斷電期間熱端資訊可能會發生變化)。" + +msgid "I confirm all" +msgstr "確認無誤" + +msgid "Re-read all" +msgstr "重新讀取全部" + +msgid "Reading the hotends, please wait." +msgstr "正在讀取熱端資訊,請稍候。" + +msgid "During the hotend upgrade, the toolhead will move. Don't reach into the chamber." +msgstr "在熱端升級過程中,工具頭會移動。請勿將手伸入機箱內。" + +msgid "Update" +msgstr "" + msgid "Current AMS humidity" msgstr "目前 AMS 濕度" @@ -96,6 +197,85 @@ msgstr "版本:" msgid "Latest version" msgstr "最新版本" +msgid "Row A" +msgstr "A排" + +msgid "Row B" +msgstr "B排" + +msgid "Toolhead" +msgstr "工具頭" + +msgid "Empty" +msgstr "空" + +msgid "Error" +msgstr "錯誤" + +msgid "Induction Hotend Rack" +msgstr "感應熱端架" + +msgid "Hotends Info" +msgstr "熱端資訊" + +msgid "Read All" +msgstr "讀取全部" + +msgid "Reading " +msgstr "讀取中 " + +msgid "Please wait" +msgstr "請稍候" + +msgid "Running..." +msgstr "執行中..." + +msgid "Raised" +msgstr "已升起" + +msgid "The hotend is in an abnormal state and currently unavailable. Please go to 'Device -> Upgrade' to upgrade firmware." +msgstr "熱端狀態異常,當前不可用。請前往“裝置 -> 升級”升級韌體。" + +msgid "Abnormal Hotend" +msgstr "熱端異常" + +msgid "Refresh" +msgstr "刷新" + +msgid "Refreshing" +msgstr "重新整理中" + +msgid "Hotend status abnormal, unavailable at present. Please upgrade the firmware and try again." +msgstr "熱端狀態異常,目前不可用。請升級韌體後重試。" + +msgid "Cancel" +msgstr "取消" + +msgid "Jump to the upgrade page" +msgstr "跳轉至升級頁面" + +msgid "SN" +msgstr "序號" + +msgid "Version" +msgstr "版本" + +#, c-format, boost-format +msgid "Used Time: %s" +msgstr "使用時間: %s" + +msgid "Dynamic nozzles are allocated on the current plate. Picking hotend is not supported." +msgstr "當前盤存在動態分配噴嘴,不支援修改。" + +msgid "Hotend Rack" +msgstr "熱端掛架" + +msgid "ToolHead" +msgstr "工具頭" + +msgid "Nozzle information needs to be read" +msgstr "需要讀取噴嘴資訊" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Support Painting" msgstr "支撐筆刷" @@ -168,6 +348,12 @@ msgstr "填充" msgid "Gap Fill" msgstr "縫隙填充" +msgid "Vertical" +msgstr "垂直" + +msgid "Horizontal" +msgstr "水平" + #, boost-format msgid "Allows painting only on facets selected by: \"%1%\"" msgstr "僅允許在由以下條件選擇的平面上進行繪製:「%1%」" @@ -263,12 +449,6 @@ msgstr "三角形" msgid "Height Range" msgstr "高度範圍" -msgid "Vertical" -msgstr "垂直" - -msgid "Horizontal" -msgstr "水平" - msgid "Remove painted color" msgstr "移除已繪製的顏色" @@ -333,6 +513,7 @@ msgstr "Gizmo-旋轉" msgid "Optimize orientation" msgstr "最佳化方向" +msgctxt "Verb" msgid "Scale" msgstr "縮放" @@ -377,6 +558,9 @@ msgstr "縮放比例" msgid "Object operations" msgstr "物件操作" +msgid "Scale" +msgstr "縮放" + # TODO: Review, changed by lang refactor. PR 14254 msgid "Volume operations" msgstr "零件操作" @@ -428,6 +612,10 @@ msgstr "重設旋轉角度為開啟旋轉工具時的狀態。" msgid "Reset current rotation to real zeros." msgstr "將旋轉角度歸零" +msgctxt "Noun" +msgid "Scale" +msgstr "縮放" + #. TRN - Input label. Be short as possible msgid "Size" msgstr "尺寸" @@ -610,9 +798,6 @@ msgstr "與半徑相關的空間佔比" msgid "Confirm connectors" msgstr "確認" -msgid "Cancel" -msgstr "取消" - msgid "Flip cut plane" msgstr "翻轉切割面" @@ -653,12 +838,12 @@ msgstr "切割為零件" msgid "Reset cutting plane and remove connectors" msgstr "重設切割面且移除連接件" +msgid "Reset Cut" +msgstr "" + msgid "Perform cut" msgstr "執行切割" -msgid "Warning" -msgstr "警告" - msgid "Invalid connectors detected" msgstr "偵測到無效連接件" @@ -687,6 +872,13 @@ msgstr "帶有凹槽的切割平面無效" msgid "Connector" msgstr "連接件" +#, boost-format +msgid "" +"Objects(%1%) have duplicated connectors. Some connectors may be missing in slicing result.\n" +"Please report to PrusaSlicer team in which scenario this issue happened.\n" +"Thank you." +msgstr "" + msgid "Cut by Plane" msgstr "用平面分割" @@ -734,9 +926,6 @@ msgstr "簡化" msgid "Simplification is currently only allowed when a single part is selected" msgstr "僅支援對單一零件做簡化" -msgid "Error" -msgstr "錯誤" - msgid "Extra high" msgstr "非常高" @@ -2011,6 +2200,9 @@ msgstr "設定檔組 %s 的存取未經授權。" msgid "Loading user preset" msgstr "正在載入使用者預設" +msgid "There is an update available. Open the preset bundle dialog to update it." +msgstr "" + #, c-format, boost-format msgid "%s has been removed." msgstr "%s 已移除。" @@ -2024,6 +2216,18 @@ msgstr "選擇語言" msgid "Language" msgstr "語言" +#, c-format, boost-format +msgid "Switching Orca Slicer to language %s failed." +msgstr "" + +msgid "" +"\n" +"You may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n" +msgstr "" + +msgid "Orca Slicer - Switching language failed" +msgstr "" + msgid "*" msgstr "*" @@ -2656,6 +2860,45 @@ msgstr "滑鼠左鍵點擊此圖示可編輯這個物件的顏色繪製" msgid "Click the icon to shift this object to the bed" msgstr "滑鼠左鍵點擊這個圖示可將物件移動到列印板上" +msgid "Rename Object" +msgstr "" + +msgid "Rename Part" +msgstr "" + +msgid "Paste settings" +msgstr "" + +msgid "Shift objects to bed" +msgstr "" + +msgid "Object order changed" +msgstr "" + +msgid "Layer setting added" +msgstr "" + +msgid "Part setting added" +msgstr "" + +msgid "Object setting added" +msgstr "" + +msgid "Height range settings added" +msgstr "" + +msgid "Part settings added" +msgstr "" + +msgid "Object settings added" +msgstr "" + +msgid "Load Part" +msgstr "" + +msgid "Load Modifier" +msgstr "" + msgid "Loading file" msgstr "載入檔案中" @@ -2665,6 +2908,9 @@ msgstr "錯誤!" msgid "Failed to get the model data in the current file." msgstr "取得目前檔案中的模型資料失敗。" +msgid "Add primitive" +msgstr "" + msgid "Generic" msgstr "一般" @@ -2677,6 +2923,12 @@ msgstr "切換到物件設定模式編輯所選物件的列印參數。" msgid "Remove paint-on fuzzy skin" msgstr "移除塗刷的絨毛效果" +msgid "Delete Settings" +msgstr "" + +msgid "Remove height range" +msgstr "移除高度範圍" + msgid "Delete connector from object which is a part of cut" msgstr "刪除的連接件屬於切割物件的一部分" @@ -2710,12 +2962,24 @@ msgstr "刪除所有連接件" msgid "Deleting the last solid part is not allowed." msgstr "不允許刪除物件的最後一個實體零件。" +msgid "Delete part" +msgstr "" + msgid "The target object contains only one part and can not be split." msgstr "目標物件只有一個部件,無法進行拆分。" +msgid "Split to parts" +msgstr "拆分為零件" + msgid "Assembly" msgstr "組合體" +msgid "Merge parts to an object" +msgstr "" + +msgid "Add layers" +msgstr "" + msgid "Cut Connectors information" msgstr "切割連接件資訊" @@ -2749,6 +3013,9 @@ msgstr "高度範圍" msgid "Settings for height range" msgstr "高度範圍設定" +msgid "Delete selected" +msgstr "" + msgid "Layer" msgstr "層" @@ -2771,6 +3038,9 @@ msgstr "類型:" msgid "Choose part type" msgstr "選擇零件類型" +msgid "Instances to Separated Objects" +msgstr "" + msgid "Enter new name" msgstr "輸入新名稱" @@ -2796,6 +3066,9 @@ msgstr "「%s」進行此細分後將超過 100 萬個面,這可能會增加 msgid "\"%s\" part's mesh contains errors. Please repair it first." msgstr "「%s」零件的網格包含錯誤,請先修復。" +msgid "Change Filaments" +msgstr "" + msgid "Additional process preset" msgstr "附加列印參數預設" @@ -2805,9 +3078,6 @@ msgstr "刪除參數" msgid "to" msgstr "到" -msgid "Remove height range" -msgstr "移除高度範圍" - msgid "Add height range" msgstr "新增高度範圍" @@ -3018,6 +3288,9 @@ msgstr "選擇一個 AMS 槽,然後按下『上料』或『退料』按鈕來 msgid "Filament type is unknown which is required to perform this action. Please set target filament's informations." msgstr "線材類型未知,無法執行此操作。請設定目標線材的資訊。" +msgid "AMS has not been initialized. Please initialize it before use." +msgstr "" + msgid "Changing fan speed during printing may affect print quality, please choose carefully." msgstr "列印過程中更改風扇速度可能會影響列印品質,請謹慎選擇。" @@ -3140,6 +3413,24 @@ msgstr "確認擠出" msgid "Check filament location" msgstr "檢查線材位置" +msgid "Switch" +msgstr "" + +msgid "hotend" +msgstr "" + +msgid "Wait for AMS cooling" +msgstr "" + +msgid "Switch current filament at Filament Track Switch" +msgstr "" + +msgid "Pull back current filament at Filament Track Switch" +msgstr "" + +msgid "Switch track at Filament Track Switch" +msgstr "" + msgid "The maximum temperature cannot exceed " msgstr "最高溫度不能超過 " @@ -3192,6 +3483,62 @@ msgstr "開發者模式" msgid "Launch troubleshoot center" msgstr "啟動疑難排解中心" +msgid "Set nozzle count" +msgstr "" + +msgid "Please set nozzle count" +msgstr "請設定噴嘴數量" + +msgid "Error: Can not set both nozzle count to zero." +msgstr "錯誤:無法將兩個噴嘴數量都設定為零。" + +#, c-format, boost-format +msgid "Error: Nozzle count can not exceed %d." +msgstr "錯誤:噴嘴數量不可以超過%d。" + +msgid "Confirm" +msgstr "確認" + +msgid "Extruder" +msgstr "擠出機" + +msgid "Nozzle Selection" +msgstr "噴嘴選擇" + +msgid "Available Nozzles" +msgstr "可用噴嘴" + +msgid "Nozzle Info" +msgstr "噴嘴資訊" + +msgid "Sync Nozzle status" +msgstr "同步噴嘴狀態" + +msgid "Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced." +msgstr "注意:不支援在列印中混用不同直徑的噴嘴。如果所選尺寸僅存在於一個擠出機上,將強制使用單擠出機列印。" + +#, c-format, boost-format +msgid "Refresh %d/%d..." +msgstr "重新整理 %d/%d..." + +msgid "Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values." +msgstr "檢測到未知噴嘴。請重新整理以更新資訊(未重新整理的噴嘴將在切片時被排除)。請核對噴嘴直徑和流量是否與顯示值一致。" + +msgid "Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing)." +msgstr "檢測到未知噴嘴。請重新整理以更新資訊(未重新整理的噴嘴將在切片時被排除)。" + +msgid "Please confirm whether the required nozzle diameter and flow rate match the currently displayed values." +msgstr "請核對噴嘴直徑和流量是否與顯示值一致。" + +msgid "Your printer has different nozzles installed. Please select a nozzle for this print." +msgstr "您的印表機安裝了不同的噴嘴。請選擇一個噴嘴進行本次列印。" + +msgid "Ignore" +msgstr "忽略" + +msgid "Done." +msgstr "" + msgid "" "All the selected objects are on a locked plate.\n" "Cannot auto-arrange these objects." @@ -3524,15 +3871,9 @@ msgstr "OrcaSlicer 也源於同樣的精神,汲取了 PrusaSlicer、BambuStudi msgid "Today, OrcaSlicer is the most widely used and actively developed open-source slicer in the 3D printing community. Many of its innovations have been adopted by other slicers, making it a driving force for the entire industry." msgstr "如今,OrcaSlicer 是 3D 列印社群中使用最廣泛、開發最活躍的開源切片軟體。它的許多創新已被其他切片軟體採用,使其成為推動整個產業的動力。" -msgid "Version" -msgstr "版本" - msgid "AMS Materials Setting" msgstr "AMS 線材設定" -msgid "Confirm" -msgstr "確認" - msgid "Close" msgstr "關閉" @@ -3554,12 +3895,12 @@ msgstr "最小" msgid "The input value should be greater than %1% and less than %2%" msgstr "輸入的範圍在 %1% 和 %2% 之間" -msgid "SN" -msgstr "序號" - msgid "Factors of Flow Dynamics Calibration" msgstr "動態流量係數校正" +msgid "Wiki Guide" +msgstr "Wiki 指南" + msgid "PA Profile" msgstr "PA 設定檔" @@ -3650,7 +3991,7 @@ msgstr "校正完成。如下圖中的範例,請在您的熱床上找到最均 msgid "Save" msgstr "儲存" -# TODO: Review, changed by lang refactor. PR 14254 +msgctxt "Navigation" msgid "Back" msgstr "背面" @@ -3734,6 +4075,19 @@ msgstr "右噴嘴" msgid "Nozzle" msgstr "噴嘴" +msgid "Select Filament && Hotends" +msgstr "選擇材料預設和噴頭" + +msgid "Select Filament" +msgstr "選擇線材" + +#, c-format, boost-format +msgid "Printing with the current nozzle may produce an extra %0.2f g of waste." +msgstr "使用當前噴嘴列印可能會產生額外 %0.2f 克廢料。" + +msgid "External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it." +msgstr "" + #, c-format, boost-format msgid "Note: the filament type(%s) does not match with the filament type(%s) in the slicing file. If you want to use this slot, you can install %s instead of %s and change slot information on the 'Device' page." msgstr "備註:線材類型(%s)與切片檔案中的線材類型(%s)不匹配。如果您想使用此槽位,可以安裝 %s 而不是 %s,並在『設備』頁面上更改槽位資訊。" @@ -4469,9 +4823,6 @@ msgstr "測量表面" msgid "Calibrating the detection position of nozzle clumping" msgstr "校正噴嘴堵塞檢測位置" -msgid "Unknown" -msgstr "未定義" - msgid "Update successful." msgstr "更新成功。" @@ -4983,9 +5334,6 @@ msgstr "設為最佳" msgid "Regroup filament" msgstr "重新分組線材" -msgid "Wiki Guide" -msgstr "Wiki 指南" - msgid "up to" msgstr "達到" @@ -5022,7 +5370,7 @@ msgstr "急衝速度 (mm/s)" msgid "Fan speed (%)" msgstr "風扇速度(%)" -msgid "Temperature (°C)" +msgid "Temperature (℃)" msgstr "溫度(℃)" msgid "Volumetric flow rate (mm³/s)" @@ -5041,9 +5389,6 @@ msgstr "線材切換" msgid "Options" msgstr "選項" -msgid "Extruder" -msgstr "擠出機" - msgid "Cost" msgstr "成本" @@ -5056,6 +5401,7 @@ msgstr "取代工具" msgid "Color change" msgstr "顏色更換" +msgctxt "Noun" msgid "Print" msgstr "列印" @@ -5220,11 +5566,15 @@ msgstr "避開擠出校正區域" msgid "Align to Y axis" msgstr "與 Y 軸對齊" -msgctxt "Camera" +msgctxt "Camera View" +msgid "Back" +msgstr "背面" + +msgctxt "Camera View" msgid "Left" msgstr "左" -msgctxt "Camera" +msgctxt "Camera View" msgid "Right" msgstr "右" @@ -5249,9 +5599,6 @@ msgstr "在選定的列印板上排列物件" msgid "Split to objects" msgstr "拆分為物件" -msgid "Split to parts" -msgstr "拆分為零件" - msgid "Assembly View" msgstr "組裝視角" @@ -5553,6 +5900,10 @@ msgstr "列印單一列印板" msgid "Export G-code file" msgstr "匯出 G-code 檔案" +msgctxt "Verb" +msgid "Print" +msgstr "列印" + msgid "Export plate sliced file" msgstr "匯出單一列印板切片檔案" @@ -5726,15 +6077,6 @@ msgstr "匯出目前選擇的設定檔" msgid "Export" msgstr "匯出" -msgid "Sync Presets" -msgstr "同步預設" - -msgid "Pull and apply the latest presets from OrcaCloud" -msgstr "從 OrcaCloud 拉取並套用最新的預設" - -msgid "You must be logged in to sync presets from cloud." -msgstr "您必須登入才能從雲端同步預設。" - msgid "Quit" msgstr "結束" @@ -5851,6 +6193,15 @@ msgstr "視角" msgid "Preset Bundle" msgstr "設定檔組" +msgid "Sync Presets" +msgstr "同步預設" + +msgid "Pull and apply the latest presets from OrcaCloud" +msgstr "從 OrcaCloud 拉取並套用最新的預設" + +msgid "You must be logged in to sync presets from cloud." +msgstr "您必須登入才能從雲端同步預設。" + msgid "Syncing presets from cloud…" msgstr "正在從雲端同步預設…" @@ -5970,6 +6321,9 @@ msgstr "匯出結果" msgid "Select profile to load:" msgstr "選擇要載入的設定檔:" +msgid "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament" +msgstr "" + #, c-format, boost-format msgid "There is %d config imported. (Only non-system and compatible configs)" msgid_plural "There are %d configs imported. (Only non-system and compatible configs)" @@ -6140,9 +6494,6 @@ msgstr "從列印設備中下載選中的檔案。" msgid "Batch manage files." msgstr "批次管理檔案。" -msgid "Refresh" -msgstr "刷新" - msgid "Reload file list from printer." msgstr "從列印設備重新載入檔案清單。" @@ -6452,6 +6803,9 @@ msgstr "列印選項" msgid "Safety Options" msgstr "安全選項" +msgid "Hotends" +msgstr "熱端" + msgid "Lamp" msgstr "LED 燈" @@ -6485,6 +6839,12 @@ msgstr "列印暫停時,只支援外部槽位的線材進退料。" msgid "Current extruder is busy changing filament." msgstr "擠出機正在進行換料操作。" +msgid "\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup on printer." +msgstr "" + msgid "Current slot has already been loaded." msgstr "目前槽位已載入線材。" @@ -6535,9 +6895,6 @@ msgstr "僅在列印過程中生效" msgid "Silent" msgstr "靜音模式(50%)" -msgid "Standard" -msgstr "標準模式(100%)" - msgid "Sport" msgstr "運動模式(125%)" @@ -6571,6 +6928,12 @@ msgstr "新增照片" msgid "Delete Photo" msgstr "刪除照片" +msgid "Select Images" +msgstr "" + +msgid "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg" +msgstr "" + msgid "Submit" msgstr "送出" @@ -6754,6 +7117,9 @@ msgstr "如何啟用 LAN 模式" msgid "Don't show this dialog again" msgstr "不要再顯示此提示" +msgid "Please refer to Wiki before use->" +msgstr "使用前請參考 Wiki ->" + msgid "3D Mouse disconnected." msgstr "3D 滑鼠已中斷連接。" @@ -7004,27 +7370,18 @@ msgstr "流量" msgid "Please change the nozzle settings on the printer." msgstr "請在列印設備上變更噴嘴設定。" -msgid "Hardened Steel" -msgstr "硬化鋼" - -msgid "Stainless Steel" -msgstr "不鏽鋼" - -msgid "Tungsten Carbide" -msgstr "碳化鎢" - msgid "Brass" msgstr "黃銅" msgid "High flow" msgstr "高流量" +msgid "TPU High flow" +msgstr "" + msgid "No wiki link available for this printer." msgstr "此列印設備沒有可用的 wiki 連結。" -msgid "Refreshing" -msgstr "重新整理中" - msgid "Unavailable while heating maintenance function is on." msgstr "加熱維護功能啟用時無法使用。" @@ -7147,6 +7504,15 @@ msgstr "切換直徑" msgid "Configuration incompatible" msgstr "設定檔不相容" +msgid "Filament switcher detected. All AMS filaments are now available for both extruders. The slicer will auto-assign for optimal printing. " +msgstr "" + +msgid "A filament switcher is detected but not calibrated and thus currently unavailable. Please calibrate it on the printer and synchronize before use. " +msgstr "" + +msgid "Tips" +msgstr "提示" + msgid "Sync printer information" msgstr "同步列印設備資訊" @@ -7175,6 +7541,9 @@ msgstr "點擊編輯預設檔設定" msgid "Project Filaments" msgstr "專案線材" +msgid "Purge mode" +msgstr "" + msgid "Flushing volumes" msgstr "廢料體積" @@ -7399,9 +7768,6 @@ msgstr "連接的列印設備是 %s。列印時必須與專案預設相符。\n" msgid "Do you want to sync the printer information and automatically switch the preset?" msgstr "您是否要同步列印設備資訊並自動切換預設?" -msgid "Tips" -msgstr "提示" - msgid "The file does not contain any geometry data." msgstr "此檔案不包含任何幾何資料。" @@ -7452,9 +7818,21 @@ msgstr "" "此操作將破壞切割對應關係。\n" "模型的一致性可能無法保證。" +msgid "Delete Object" +msgstr "" + +msgid "Delete All Objects" +msgstr "" + +msgid "Reset Project" +msgstr "" + msgid "The selected object couldn't be split." msgstr "選中的模型不可分割。" +msgid "Split to Objects" +msgstr "" + msgid "Disable Auto-Drop to preserve Z positioning?\n" msgstr "停用自動落板以保留 Z 定位?\n" @@ -7481,6 +7859,9 @@ msgstr "選擇新檔案" msgid "File for the replacement wasn't selected" msgstr "未選擇替換檔案" +msgid "Replace with 3D file" +msgstr "" + msgid "Select folder to replace from" msgstr "選擇要替換的資料夾" @@ -7527,6 +7908,9 @@ msgstr "無法重新載入:" msgid "Error during reload" msgstr "重新載入時出現錯誤" +msgid "Reload all" +msgstr "" + msgid "There are warnings after slicing models:" msgstr "模型切片警告:" @@ -8296,6 +8680,15 @@ msgstr "清除我在載入檔案後同步列印設備預設的選擇。" msgid "Graphics" msgstr "圖形" +msgid "Smooth normals" +msgstr "平滑法線" + +msgid "" +"Applies smooth normals to the model.\n" +"\n" +"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgstr "" + msgid "Phong shading" msgstr "Phong 著色" @@ -8311,20 +8704,8 @@ msgstr "在寫實渲染中套用 SSAO。" msgid "Shadows" msgstr "陰影" -msgid "Renders cast shadows on the plate in realistic view." -msgstr "在擬真檢視中於列印板上算繪投射陰影。" - -msgid "Smooth normals" -msgstr "平滑法線" - -msgid "" -"Applies smooth normals to the realistic view.\n" -"\n" -"Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +msgid "Renders cast shadows on the plate, other objects, and each object onto itself in realistic view." msgstr "" -"將平滑法線套用至擬真檢視。\n" -"\n" -"需要手動重新載入場景才能生效(在 3D 檢視中按一下滑鼠右鍵 →「重新載入所有物件」)。" msgid "Anti-aliasing" msgstr "抗鋸齒" @@ -8620,6 +9001,9 @@ msgstr "不相容的預設" msgid "My Printer" msgstr "我的列印設備" +msgid "AMS filaments" +msgstr "" + msgid "Left filaments" msgstr "左側線材" @@ -8639,6 +9023,9 @@ msgstr "新增/刪除 預設" msgid "Edit preset" msgstr "編輯預設" +msgid "Change extruder color" +msgstr "" + msgid "Unspecified" msgstr "未指定" @@ -8670,9 +9057,6 @@ msgstr "選擇/移除列印設備(系統預設)" msgid "Create printer" msgstr "建立列印設備" -msgid "Empty" -msgstr "空" - msgid "Incompatible" msgstr "不相容的預設" @@ -8904,12 +9288,42 @@ msgstr "傳送完成" msgid "Error code" msgstr "錯誤代碼" -msgid "High Flow" -msgstr "高流量" +msgid "Error desc" +msgstr "錯誤描述" + +msgid "Extra info" +msgstr "額外資訊" + +msgid "The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues." +msgstr "" + +msgid "This print requires a Filament Track Switch. Please install it first." +msgstr "" + +msgid "The Filament Track Switch has not been setup. Please setup it first." +msgstr "" #, c-format, boost-format -msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." -msgstr "%s 的噴嘴流量設定(%s)與切片檔案(%s)不符。請確保已安裝的噴嘴與列印設備中的設定相符,然後在切片時設定相應的列印設備預設。" +msgid "Failed to send nozzle auto-mapping request to printer { code: %d }. Please try to refresh the printer information. If it still does not recover, you can try to rebind the printer and check the network connection." +msgstr "" + +msgid "The printer is calculating nozzle mapping." +msgstr "" + +msgid "Please wait a moment..." +msgstr "" + +#, c-format, boost-format +msgid "Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information." +msgstr "" + +#, c-format, boost-format +msgid "The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information." +msgstr "" + +#, c-format, boost-format +msgid "The current nozzle mapping may produce an extra %0.2f g of waste." +msgstr "" #, c-format, boost-format msgid "Filament %s does not match the filament in AMS slot %s. Please update the printer firmware to support AMS slot assignment." @@ -8973,8 +9387,38 @@ msgstr "比最佳分組多消耗 %dg 線材和 %d 次切換。" msgid "nozzle" msgstr "噴嘴" -msgid "both extruders" -msgstr "兩個擠出機" +#, c-format, boost-format +msgid "Refreshing information of hotends(%d/%d)." +msgstr "" + +msgid "There are not enough available hotends currently." +msgstr "" + +msgid "Please complete the hotend rack setup and try again." +msgstr "" + +msgid "Please refresh the nozzle information and try again." +msgstr "" + +msgid "Please re-slice to avoid filament waste." +msgstr "" + +msgid "The reported hotend information may be unreliable." +msgstr "" + +#, c-format, boost-format +msgid "The printer has no nozzle matching the slicing file (%s)." +msgstr "" + +msgid "Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing." +msgstr "" + +msgid "The toolhead and hotend rack are full. Please remove at least one hotend before printing." +msgstr "" + +#, c-format, boost-format +msgid "The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset while slicing." +msgstr "%s 的噴嘴流量設定(%s)與切片檔案(%s)不符。請確保已安裝的噴嘴與列印設備中的設定相符,然後在切片時設定相應的列印設備預設。" msgid "Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting." msgstr "提示:如果您最近更換了列印設備的噴嘴,請前往『裝置 -> 列印設備零件』變更您的噴嘴設定。" @@ -8987,10 +9431,17 @@ msgstr "目前列印設備的 %s 直徑(%.1fmm)與切片檔案(%.1fmm) msgid "The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). Please make sure the nozzle installed matches with settings in printer, then set the corresponding printer preset when slicing." msgstr "目前噴嘴直徑(%.1fmm)與切片檔案(%.1fmm)不符。請確保已安裝的噴嘴與列印設備中的設定相符,然後在切片時設定相應的列印設備預設。" +msgid "both extruders" +msgstr "兩個擠出機" + #, c-format, boost-format msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). Please verify the nozzle or material settings and try again." msgstr "目前材料(%s)的硬度超過 %s(%s)的硬度。請驗證噴嘴或材料設定並重試。" +#, c-format, boost-format +msgid "The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, leading to material leakage and unstable flow. Please exercise caution when using it." +msgstr "" + #, c-format, boost-format msgid "[ %s ] requires printing in a high-temperature environment. Please close the door." msgstr "[ %s ] 需要在高溫環境中列印。請關閉機門。" @@ -9101,9 +9552,6 @@ msgstr "當前韌體最多支援 16 種線材。您可以在準備頁面將材 msgid "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." msgstr "外部線材的類型未知,或與切片檔案中的線材類型不符。請確認您已在外部料盤中安裝正確的線材。" -msgid "Please refer to Wiki before use->" -msgstr "使用前請參考 Wiki ->" - msgid "Current firmware does not support file transfer to internal storage." msgstr "目前韌體不支援檔案傳輸至內部儲存空間。" @@ -9287,6 +9735,9 @@ msgstr "" msgid "Click to reset all settings to the last saved preset." msgstr "點擊以將所有設定還原到最後一次儲存的版本。" +msgid "Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?" +msgstr "切換噴嘴需要擦料塔,否則列印件上可能會有瑕疵。您確定要關閉擦料塔嗎?" + # TODO: Review, changed by lang refactor. PR 14254 msgid "A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower?" msgstr "平滑模式的縮時錄影需要換料塔,否則列印物件上可能會有瑕疵。您是否要關閉換料塔?" @@ -9368,9 +9819,6 @@ msgstr "是否自動調整至設定範圍?\n" msgid "Adjust" msgstr "調整" -msgid "Ignore" -msgstr "忽略" - msgid "Experimental feature: Retracting and cutting off the filament at a greater distance during filament changes to minimize flush. Although it can notably reduce flush, it may also elevate the risk of nozzle clogs or other printing complications." msgstr "實驗性功能:在換線過程中以更大的距離收回並切斷線材,以減少沖洗量。儘管這可以顯著減少沖洗,但也可能增加噴嘴堵塞或其他列印問題的風險。" @@ -9872,6 +10320,12 @@ msgstr "" msgid "Are you sure you want to %1% the selected preset?" msgstr "確認要 %1% 所選預設嗎?" +msgid "Select printers" +msgstr "選擇列印設備" + +msgid "Select profiles" +msgstr "選擇設定檔" + #, c-format, boost-format msgid "" " - %s:\n" @@ -10120,6 +10574,12 @@ msgstr "將數值從左邊轉移到右邊" msgid "If enabled, this dialog can be used for transfer selected values from left to right preset." msgstr "如果啟用,則此視窗可用於將選定的數值從左邊轉移到右邊的預設值。" +msgid "One of the presets does not exist" +msgstr "" + +msgid "Compared presets has different printer technology" +msgstr "" + msgid "Add File" msgstr "新增檔案" @@ -10375,12 +10835,8 @@ msgstr "成功同步噴嘴資訊。" msgid "Successfully synchronized nozzle and AMS number information." msgstr "成功同步噴嘴和 AMS 數量資訊。" -msgid "Continue to sync filaments" -msgstr "繼續同步線材" - -msgctxt "Sync_Nozzle_AMS" -msgid "Cancel" -msgstr "取消" +msgid "Do you want to continue to sync filaments?" +msgstr "" msgid "Successfully synchronized filament color from printer." msgstr "成功從列印設備同步線材顏色。" @@ -10489,6 +10945,9 @@ msgstr "登入" msgid "Login failed. Please try again." msgstr "登入失敗。請再試一次。" +msgid "parse json failed" +msgstr "" + msgid "[Action Required] " msgstr "[需要操作] " @@ -10803,6 +11262,9 @@ msgstr "列印設備名稱" msgid "Where to find your printer's IP and Access Code?" msgstr "在哪裡可以找到列印設備的 IP 和訪問代碼?" +msgid "How to trouble shooting" +msgstr "" + msgid "Connect" msgstr "連接" @@ -10867,6 +11329,9 @@ msgstr "切割模組" msgid "Auto Fire Extinguishing System" msgstr "自動滅火系統" +msgid "Filament Track Switch" +msgstr "" + msgid "Beta" msgstr "Beta" @@ -10885,6 +11350,9 @@ msgstr "更新失敗" msgid "Update successful" msgstr "更新成功" +msgid "Hotends on Rack" +msgstr "熱端&掛架" + msgid "Are you sure you want to update? This will take about 10 minutes. Do not turn off the power while the printer is updating." msgstr "確認要更新嗎?更新需要大約10分鐘,更新期間請勿關閉電源。" @@ -10994,6 +11462,9 @@ msgstr "分組錯誤:" msgid " can not be placed in the " msgstr "無法放置於" +msgid "Group error in manual mode. Please check nozzle count or regroup." +msgstr "" + msgid "Internal Bridge" msgstr "內部橋接" @@ -11711,19 +12182,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"外部橋接角度覆蓋。\n" -"若保持為零,將為每個特定橋接自動計算橋接角度。\n" -"否則將依下列方式使用所提供的角度:\n" -" - 絕對座標\n" -" - 絕對座標 + 模型旋轉:若已啟用「對齊填充方向至模型」\n" -" - 最佳自動角度 + 此數值:若已啟用「相對橋接角度」\n" -"\n" -"若要設定絕對角度為零,請使用 180°。" msgid "Internal bridge infill direction" msgstr "內部橋接結構的填充方向" @@ -11733,19 +12196,11 @@ msgid "" "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" -" - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +" - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" "\n" "Use 180° for zero absolute angle." msgstr "" -"內部橋接角度覆寫。\n" -"若保持為零,將為每個特定橋接自動計算橋接角度。\n" -"否則將依照下列方式使用所提供的角度:\n" -" - 絕對座標\n" -" - 絕對座標 + 模型旋轉:若啟用「將填充方向對齊模型」\n" -" - 最佳自動角度 + 此值:若啟用「相對橋接角度」\n" -"\n" -"使用 180° 表示零絕對角度。" msgid "Relative bridge angle" msgstr "相對橋接角度" @@ -12214,9 +12669,6 @@ msgstr "" "在偵測尖銳角度之前,幾何形狀將被簡化。此參數表示簡化的最小偏差長度。\n" "設為 0 以停用" -msgid "Select printers" -msgstr "選擇列印設備" - msgid "upward compatible machine" msgstr "向上相容的設備" @@ -12227,9 +12679,6 @@ msgstr "條件" msgid "A Boolean expression using the configuration values of an active printer profile. If this expression evaluates to true, this profile is considered compatible with the active printer profile." msgstr "使用啟用的列印設備設定值來進行布林運算的表達式。如果此表達式的結果為 true,則該設定檔將被視為與目前啟用的列印設備設定檔相容。" -msgid "Select profiles" -msgstr "選擇設定檔" - # TODO: Review, changed by lang refactor. PR 14254 msgid "A Boolean expression using the configuration values of an active print profile. If this expression evaluates to true, this profile is considered compatible with the active print profile." msgstr "使用啟用的列印設定檔值來進行布林運算的表達式。如果此表達式的結果為 true,則該設定檔將被視為與目前啟用的列印設定檔相容。" @@ -12504,6 +12953,42 @@ msgstr "頂面密度" msgid "Density of top surface layer. A value of 100% creates a fully solid, smooth top layer. Reducing this value results in a textured top surface, according to the chosen top surface pattern. A value of 0% will result in only the walls on the top layer being created. Intended for aesthetic or functional purposes, not to fix issues such as over-extrusion." msgstr "頂面層的密度。100% 將建立完全實心且平滑的頂層。降低此數值會根據所選的頂面圖案產生紋理表面。0% 則只會建立頂層的牆體。此功能旨在實現美觀或功能需求,而非修正過擠等問題" +msgid "Top surface expansion" +msgstr "" + +msgid "" +"Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" +"Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane.Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top.The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection." +msgstr "" + +msgid "Top expansion wall margin" +msgstr "" + +msgid "" +"Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" +"This can cause contraction marks (such as the hull line) on the outer walls.\n" +"By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark." +msgstr "" + +msgid "Top expansion direction" +msgstr "" + +msgid "" +"Direction in which the top surface expansion grows.\n" +" - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" +" - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" +" - Inward and Outward does both." +msgstr "" + +msgid "Inward and Outward" +msgstr "" + +msgid "Inward" +msgstr "" + +msgid "Outward" +msgstr "" + msgid "Bottom surface pattern" msgstr "底面圖案" @@ -12830,12 +13315,18 @@ msgstr "自動清理" msgid "Auto For Match" msgstr "自動匹配" +msgid "Nozzle Manual" +msgstr "噴嘴手動" + msgid "Flush temperature" msgstr "清理溫度" msgid "Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range." msgstr "清理線材時的溫度。0 表示推薦噴嘴溫度範圍的上限。" +msgid "Flush temperature used in fast purge mode." +msgstr "" + msgid "Flush volumetric speed" msgstr "清理體積流量" @@ -13102,6 +13593,12 @@ msgstr "線材可列印" msgid "The filament is printable in extruder." msgstr "該線材可在擠出機中列印。" +msgid "Filament-extruder compatibility" +msgstr "" + +msgid "A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). 0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved." +msgstr "" + msgid "Softening temperature" msgstr "線材軟化溫度" @@ -13164,15 +13661,13 @@ msgstr "稀疏填充密度" msgid "Density of internal sparse infill, 100% turns all sparse infill into solid infill and internal solid infill pattern will be used." msgstr "設定內部稀疏填充的密度,當密度為 100% 時,所有稀疏填充將變為實心填充,並套用內部實心填充的圖案" -msgid "Align infill direction to model" -msgstr "對齊填充方向至模型" +msgid "Align directions to model" +msgstr "" msgid "" -"Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" -"When enabled, directions rotate with the model to maintain optimal strength characteristics." +"Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" +"When enabled, these directions rotate together with the model so the printed features keep their intended orientation relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed." msgstr "" -"使填充、橋接、熨燙與表面填充的方向對齊,以跟隨模型在列印板上的方向。\n" -"啟用後,方向會隨模型一同旋轉,以維持最佳的強度特性。" msgid "Insert solid layers" msgstr "插入實心層" @@ -13708,6 +14203,15 @@ msgstr "針對列印版的形狀,範圍 [0,1] 內的最佳自動擺放位置 msgid "Enable this option if machine has auxiliary part cooling fan. G-code command: M106 P2 S(0-255)." msgstr "如果設備有輔助物件冷卻風扇,請啟用此選項。 G-code 指令:M106 P2 S(0-255)。" +msgid "Fan direction" +msgstr "" + +msgid "Cooling fan direction of the printer" +msgstr "" + +msgid "Both" +msgstr "" + msgid "" "Start the fan this number of seconds earlier than its target start time (you can use fractional seconds). It assumes infinite acceleration for this time estimation, and will only take into account G1 and G0 moves (arc fitting is unsupported).\n" "It won't move fan commands from custom G-code (they act as a sort of 'barrier').\n" @@ -13784,6 +14288,12 @@ msgstr "" "如果列印設備支援空氣過濾,請啟用此選項\n" "G-code 指令:M106 P3 S(0-255)" +msgid "Use cooling filter" +msgstr "開啟冷卻過濾" + +msgid "Enable this if printer support cooling filter" +msgstr "開啟該功能後,當腔溫過高時,會自動關閉過濾以提高冷卻效果" + msgid "G-code flavor" msgstr "G-code 風格" @@ -14317,6 +14827,30 @@ msgstr "最小空駛速度" msgid "Minimum travel speed (M205 T)" msgstr "最小空駛速度(M205 T)" +msgid "Maximum force of the Y axis" +msgstr "" + +msgid "The allowed maximum output force of Y axis" +msgstr "" + +msgid "N" +msgstr "" + +msgid "Bed mass of the Y axis" +msgstr "" + +msgid "The machine bed mass load of Y axis" +msgstr "" + +msgid "g" +msgstr "" + +msgid "The allowed max printed mass" +msgstr "" + +msgid "The allowed max printed mass on a plate" +msgstr "" + msgid "Maximum acceleration for extruding" msgstr "擠出最大加速度" @@ -14889,6 +15423,9 @@ msgstr "直驅(近程)" msgid "Bowden" msgstr "遠程擠出機" +msgid "Hybrid" +msgstr "混合" + msgid "Enable filament dynamic map" msgstr "啟用線材動態映射" @@ -14926,6 +15463,12 @@ msgstr "" "向噴嘴重新裝填線材的速度。\n" "設為 0 則使用與回抽相同的速度。" +msgid "Deretraction speed (extruder change)" +msgstr "" + +msgid "Speed for reloading filament into the nozzle when switching extruder." +msgstr "" + msgid "Use firmware retraction" msgstr "使用韌體回抽" @@ -14957,6 +15500,10 @@ msgstr "對齊" msgid "Aligned back" msgstr "背部對齊" +# TODO: Review, changed by lang refactor. PR 14254 +msgid "Back" +msgstr "背面" + msgid "Random" msgstr "隨機" @@ -15225,6 +15772,12 @@ msgstr "選擇平滑模式或傳統模式時,列印過程將產生縮時影片 msgid "Traditional" msgstr "傳統模式" +msgid "Farthest point timelapse" +msgstr "" + +msgid "When enabled, the timelapse snapshot is taken at the farthest point from camera instead of traveling to the wipe tower or excess chute. Only effective in traditional timelapse mode on non-I3 printers." +msgstr "" + msgid "Temperature variation" msgstr "軟化溫度" @@ -15312,6 +15865,18 @@ msgstr "所有擠出機畫線" msgid "If enabled, all printing extruders will be primed at the front edge of the print bed at the start of the print." msgstr "如果啟用,所有擠出機將在列印開始時在列印板前方畫線。" +msgid "Toolchange ordering" +msgstr "" + +msgid "" +"Determines the order of tool changes on each layer.\n" +"- Default: Starts with the last used extruder to minimize tool changes.\n" +"- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." +msgstr "" + +msgid "Cyclic" +msgstr "" + msgid "Slice gap closing radius" msgstr "切片間隙閉合半徑" @@ -15698,7 +16263,7 @@ msgid "" msgstr "對於 ABS、ASA、PC 和 PA 等高溫材料,較高的機箱溫度能有效抑制或減少翹曲,並可能提升層間結合強度。然而,較高的機箱溫度也會降低 ABS 和 ASA 的空氣過濾效率。對於 PLA、PETG、TPU、PVA 和其他低溫材料,建議將此選項停用(設為 0),因機箱溫度應保持較低,以避免因材料在熱端軟化而導致擠出機堵塞。啟用此選項後,會設置一個名為 chamber_temperature 的 G-code 變數,可用於將所需的機箱溫度傳遞給列印開始宏,或像以下的熱浸泡宏(預熱):PRINT_START (其他變數) CHAMBER_TEMP=[chamber_temperature]。這對於不支援 M141/M191 指令的列印設備,或者希望在列印開始宏中處理熱浸泡(預熱)但未安裝主動機箱加熱器的情況下非常實用。" msgid "" -"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n" +"This is the chamber temperature at which printing should start, while the chamber continues heating toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n" "\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n" "\n" @@ -15752,6 +16317,45 @@ msgstr "頂部外殼厚度" msgid "The number of top solid layers is increased when slicing if the thickness calculated by top shell layers is thinner than this value. This can avoid having too thin a shell when layer height is small. 0 means that this setting is disabled and thickness of top shell is determined simply by the number of top shell layers." msgstr "當切片時,如果通過頂部殼層計算的厚度小於設定值,將自動增加頂部實心層的數量,以避免層高較小時頂部殼層過薄。若設為 0,則停用此功能,頂部殼層厚度完全由設定的頂部殼層數決定" +msgid "Anisotropic surfaces" +msgstr "" + +msgid "" +"Anisotropic patterns on the top and bottom surfaces.\n" +"Co-directional printing mode will be applied. For certain patterns, omni-directional filling provides color dispersion when using multi-colored or silk plastics.\n" +"This option disable the gap fill.\n" +"This option can increase a printing time." +msgstr "" + +msgid "Separated infills" +msgstr "" + +msgid "" +"Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts (or distinct 3D objects) each get their own.\n" +"Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" +"Affects line and grid patterns and rotation-template infills.\n" +"Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected." +msgstr "" + +msgid "Center surface pattern on" +msgstr "" + +msgid "" +"Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, Octagram Spiral) is placed.\n" +" - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" +" - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; parts detached from the rest each get their own.\n" +" - Each Assembly: uses a single shared center for the whole object or assembly." +msgstr "" + +msgid "Each Surface" +msgstr "" + +msgid "Each Model" +msgstr "" + +msgid "Each Assembly" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the speed at which traveling is done." msgstr "空駛的速度。空駛是無擠出量的快速移動" @@ -15800,6 +16404,12 @@ msgstr "沖刷量乘數" msgid "The actual flushing volumes is equal to the flush multiplier value multiplied by the flushing volumes in the table." msgstr "實際沖刷量等於沖刷量乘數乘以表格單元中的沖刷量。" +msgid "Flush multiplier (Fast mode)" +msgstr "" + +msgid "The flush multiplier used in fast purge mode." +msgstr "" + msgid "Prime volume" msgstr "清理量" @@ -15807,6 +16417,18 @@ msgstr "清理量" msgid "This is the volume of material to prime the extruder with on the tower." msgstr "換料塔上的清理量。" +msgid "Prime volume mode" +msgstr "" + +msgid "Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers." +msgstr "" + +msgid "Saving" +msgstr "" + +msgid "Fast" +msgstr "" + # TODO: Review, changed by lang refactor. PR 14254 msgid "This is the width of prime towers." msgstr "換料塔寬度" @@ -16099,6 +16721,57 @@ msgstr "牆最小線寬" msgid "Width of the wall that will replace thin features (according to the Minimum feature size) of the model. If the Minimum wall width is thinner than the thickness of the feature, the wall will become as thick as the feature itself. It's expressed as a percentage over nozzle diameter." msgstr "設定替代模型中細薄特徵(依據最小特徵尺寸)的牆體寬度。若最小牆寬小於特徵厚度,牆體將與特徵的厚度一致。此值以噴嘴直徑的百分比表示" +msgid "Hotend change time" +msgstr "熱端更換時間" + +msgid "Time to change hotend." +msgstr "熱端更換時間。" + +msgid "Hotend change" +msgstr "熱端更換" + +msgid "When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing." +msgstr "更換熱端時,建議從原熱端中擠出一定長度的耗材絲。這有助於最大限度地減少噴嘴漏料。" + +msgid "Extruder change" +msgstr "擠出機更換" + +msgid "To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after the ramming is complete. The setting define the travel time." +msgstr "為了防止溢料,預沖刷完成後,噴嘴會進行一段時間的反向空駛。該設定用於定義空駛時間。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled." +msgstr "為了防止溢料,預沖刷時會降低噴嘴溫度。因此,預沖刷時間必須大於冷卻時間。0 表示禁用。" + +msgid "The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed." +msgstr "換出擠出機前的最大預沖刷體積速度,-1 表示使用最大體積速度。" + +msgid "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled." +msgstr "為防止溢料,預沖刷過程中噴嘴溫度會降低。注意:僅觸發冷卻指令並啟動風扇,不保證達到目標溫度。0 表示禁用。" + +msgid "The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed." +msgstr "熱端更換前的最大預沖刷體積速度,其中 -1 表示使用最大體積速度。" + +msgid "length when change hotend" +msgstr "換熱端時回抽量" + +msgid "When this retraction value is modified, it will be used as the amount of filament retracted inside the hotend before changing hotends." +msgstr "當修改此回抽數值時,將用於熱端內在更換熱端前回抽的耗材量。" + +msgid "Support fast purge mode" +msgstr "" + +msgid "Whether this printer supports fast purge mode with optimized temperature and multiplier." +msgstr "" + +msgid "The volume of material required to prime the extruder for a hotend change on the tower." +msgstr "換熱端所需的擦料塔上的清理量。" + +msgid "Preheat temperature delta" +msgstr "預熱溫度差" + +msgid "Temperature delta applied during pre-heating before tool change." +msgstr "工具切換前預熱期間套用的溫度差。" + msgid "Detect narrow internal solid infills" msgstr "識別狹窄內部實心填充" @@ -16852,12 +17525,6 @@ msgstr "" msgid "Calibration not supported" msgstr "不支援校正" -msgid "Error desc" -msgstr "錯誤描述" - -msgid "Extra info" -msgstr "額外資訊" - msgid "Flow Dynamics" msgstr "動態流量" @@ -17062,6 +17729,12 @@ msgstr "請輸入要儲存到列印設備的名稱。" msgid "The name cannot exceed 40 characters." msgstr "名稱不能超過40個字元。" +msgid "Nozzle ID" +msgstr "噴嘴 ID" + +msgid "Standard Flow" +msgstr "標準流量" + msgid "Please find the best line on your plate" msgstr "請在您的列印板上找到最佳線條" @@ -17152,9 +17825,6 @@ msgstr "AMS 和噴嘴資訊同步" msgid "Nozzle Flow" msgstr "噴嘴流量" -msgid "Nozzle Info" -msgstr "噴嘴資訊" - msgid "Filament position" msgstr "線材位置" @@ -17229,6 +17899,10 @@ msgstr "成功取得歷史結果" msgid "Refreshing the previous Flow Dynamics Calibration records" msgstr "重整歷史流量動態校正記錄" +#, c-format, boost-format +msgid "Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically." +msgstr "注意:%s上的熱端編號與刀架繫結。當熱端移動至新刀架時,其編號會自動更新。" + msgid "Action" msgstr "操作" @@ -18991,6 +19665,12 @@ msgstr "列印失敗" msgid "Removed" msgstr "已移除" +msgid "Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings" +msgstr "" + +msgid "Fila Saving" +msgstr "" + msgid "Don't remind me again" msgstr "不要再提醒我" @@ -19024,12 +19704,25 @@ msgstr "影片指南" msgid "(Sync with printer)" msgstr "(與列印設備同步)" +#, c-format, boost-format +msgid "Error: %s extruder has no available %s nozzle, current group result is invalid." +msgstr "" + msgid "We will slice according to this grouping method:" msgstr "我們將按照這種分組方法進行切片:" msgid "Tip: You can drag the filaments to reassign them to different nozzles." msgstr "提示:您可以拖動線材以將它們重新分配到不同的噴嘴。" +msgid "Please adjust your grouping or click " +msgstr "" + +msgid " to set nozzle count" +msgstr "" + +msgid "Set the physical nozzle count..." +msgstr "" + msgid "The filament grouping method for current plate is determined by the dropdown option at the slicing plate button." msgstr "當前板的線材分組方法由切片板按鈕上的下拉選項確定。" @@ -19261,9 +19954,6 @@ msgstr "此操作無法撤消。繼續?" msgid "Skipping objects." msgstr "跳過物件。" -msgid "Select Filament" -msgstr "選擇線材" - msgid "Null Color" msgstr "空顏色" @@ -19808,6 +20498,77 @@ msgstr "" "您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度\n" "可以降低翹曲的機率。" +#~ msgid "Renders cast shadows on the plate in realistic view." +#~ msgstr "在擬真檢視中於列印板上算繪投射陰影。" + +#~ msgid "" +#~ "Applies smooth normals to the realistic view.\n" +#~ "\n" +#~ "Requires manual scene reload to take effect (right-click on 3D view → \"Reload All\")." +#~ msgstr "" +#~ "將平滑法線套用至擬真檢視。\n" +#~ "\n" +#~ "需要手動重新載入場景才能生效(在 3D 檢視中按一下滑鼠右鍵 →「重新載入所有物件」)。" + +#~ msgid "Continue to sync filaments" +#~ msgstr "繼續同步線材" + +#~ msgctxt "Sync_Nozzle_AMS" +#~ msgid "Cancel" +#~ msgstr "取消" + +#, no-c-format, no-boost-format +#~ msgid "" +#~ "External Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "外部橋接角度覆蓋。\n" +#~ "若保持為零,將為每個特定橋接自動計算橋接角度。\n" +#~ "否則將依下列方式使用所提供的角度:\n" +#~ " - 絕對座標\n" +#~ " - 絕對座標 + 模型旋轉:若已啟用「對齊填充方向至模型」\n" +#~ " - 最佳自動角度 + 此數值:若已啟用「相對橋接角度」\n" +#~ "\n" +#~ "若要設定絕對角度為零,請使用 180°。" + +#~ msgid "" +#~ "Internal Bridging angle override.\n" +#~ "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" +#~ "Otherwise the provided angle will be used according to:\n" +#~ " - The absolute coordinates\n" +#~ " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" +#~ " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n" +#~ "\n" +#~ "Use 180° for zero absolute angle." +#~ msgstr "" +#~ "內部橋接角度覆寫。\n" +#~ "若保持為零,將為每個特定橋接自動計算橋接角度。\n" +#~ "否則將依照下列方式使用所提供的角度:\n" +#~ " - 絕對座標\n" +#~ " - 絕對座標 + 模型旋轉:若啟用「將填充方向對齊模型」\n" +#~ " - 最佳自動角度 + 此值:若啟用「相對橋接角度」\n" +#~ "\n" +#~ "使用 180° 表示零絕對角度。" + +#~ msgid "Align infill direction to model" +#~ msgstr "對齊填充方向至模型" + +#~ msgid "" +#~ "Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" +#~ "When enabled, directions rotate with the model to maintain optimal strength characteristics." +#~ msgstr "" +#~ "使填充、橋接、熨燙與表面填充的方向對齊,以跟隨模型在列印板上的方向。\n" +#~ "啟用後,方向會隨模型一同旋轉,以維持最佳的強度特性。" + +#~ msgid "Print" +#~ msgstr "列印" + #~ msgid "in" #~ msgstr "在" diff --git a/resources/fonts/HarmonyOS_Sans_SC_Bold.ttf b/resources/fonts/HarmonyOS_Sans_SC_Bold.ttf index 4e2fa07f88..f5a6b6ff63 100644 Binary files a/resources/fonts/HarmonyOS_Sans_SC_Bold.ttf and b/resources/fonts/HarmonyOS_Sans_SC_Bold.ttf differ diff --git a/resources/fonts/HarmonyOS_Sans_SC_Regular.ttf b/resources/fonts/HarmonyOS_Sans_SC_Regular.ttf index af95249830..a3a2a1231c 100644 Binary files a/resources/fonts/HarmonyOS_Sans_SC_Regular.ttf and b/resources/fonts/HarmonyOS_Sans_SC_Regular.ttf differ diff --git a/resources/images/Big_Nozzle_HH_01_04.png b/resources/images/Big_Nozzle_HH_01_04.png new file mode 100644 index 0000000000..483d6b9f84 Binary files /dev/null and b/resources/images/Big_Nozzle_HH_01_04.png differ diff --git a/resources/images/Big_Nozzle_HH_01_06.png b/resources/images/Big_Nozzle_HH_01_06.png new file mode 100644 index 0000000000..39707f41ec Binary files /dev/null and b/resources/images/Big_Nozzle_HH_01_06.png differ diff --git a/resources/images/Big_Nozzle_HH_01_08.png b/resources/images/Big_Nozzle_HH_01_08.png new file mode 100644 index 0000000000..caf120fbd2 Binary files /dev/null and b/resources/images/Big_Nozzle_HH_01_08.png differ diff --git a/resources/images/Big_Nozzle_HS_01_02.png b/resources/images/Big_Nozzle_HS_01_02.png new file mode 100644 index 0000000000..92302a72c7 Binary files /dev/null and b/resources/images/Big_Nozzle_HS_01_02.png differ diff --git a/resources/images/Big_Nozzle_HS_01_04.png b/resources/images/Big_Nozzle_HS_01_04.png new file mode 100644 index 0000000000..49aab4f2b4 Binary files /dev/null and b/resources/images/Big_Nozzle_HS_01_04.png differ diff --git a/resources/images/Big_Nozzle_HS_01_06.png b/resources/images/Big_Nozzle_HS_01_06.png new file mode 100644 index 0000000000..8d29a6ba97 Binary files /dev/null and b/resources/images/Big_Nozzle_HS_01_06.png differ diff --git a/resources/images/Big_Nozzle_HS_01_08.png b/resources/images/Big_Nozzle_HS_01_08.png new file mode 100644 index 0000000000..f08d328ccb Binary files /dev/null and b/resources/images/Big_Nozzle_HS_01_08.png differ diff --git a/resources/images/Nozzle_HH_01_04.png b/resources/images/Nozzle_HH_01_04.png new file mode 100644 index 0000000000..f5087dfcc7 Binary files /dev/null and b/resources/images/Nozzle_HH_01_04.png differ diff --git a/resources/images/Nozzle_HH_01_06.png b/resources/images/Nozzle_HH_01_06.png new file mode 100644 index 0000000000..5af573798a Binary files /dev/null and b/resources/images/Nozzle_HH_01_06.png differ diff --git a/resources/images/Nozzle_HH_01_08.png b/resources/images/Nozzle_HH_01_08.png new file mode 100644 index 0000000000..cc9feaa268 Binary files /dev/null and b/resources/images/Nozzle_HH_01_08.png differ diff --git a/resources/images/Nozzle_HS_01_02.png b/resources/images/Nozzle_HS_01_02.png new file mode 100644 index 0000000000..97c80f2aab Binary files /dev/null and b/resources/images/Nozzle_HS_01_02.png differ diff --git a/resources/images/Nozzle_HS_01_04.png b/resources/images/Nozzle_HS_01_04.png new file mode 100644 index 0000000000..650b8cbdbc Binary files /dev/null and b/resources/images/Nozzle_HS_01_04.png differ diff --git a/resources/images/Nozzle_HS_01_06.png b/resources/images/Nozzle_HS_01_06.png new file mode 100644 index 0000000000..f7e2e03640 Binary files /dev/null and b/resources/images/Nozzle_HS_01_06.png differ diff --git a/resources/images/Nozzle_HS_01_08.png b/resources/images/Nozzle_HS_01_08.png new file mode 100644 index 0000000000..f76a59a183 Binary files /dev/null and b/resources/images/Nozzle_HS_01_08.png differ diff --git a/resources/images/advanced_option3.svg b/resources/images/advanced_option3.svg index d60800be11..20ba7ba0c7 100644 --- a/resources/images/advanced_option3.svg +++ b/resources/images/advanced_option3.svg @@ -1,3 +1,3 @@ - + diff --git a/resources/images/advanced_option4.svg b/resources/images/advanced_option4.svg index c4bf14ed8f..9b3aedbf0a 100644 --- a/resources/images/advanced_option4.svg +++ b/resources/images/advanced_option4.svg @@ -1,3 +1,3 @@ - + diff --git a/resources/images/completed_2.svg b/resources/images/completed_2.svg new file mode 100644 index 0000000000..99b723b387 --- /dev/null +++ b/resources/images/completed_2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/dev_ams_dry_ctr_disable.svg b/resources/images/dev_ams_dry_ctr_disable.svg new file mode 100644 index 0000000000..f2212204e9 --- /dev/null +++ b/resources/images/dev_ams_dry_ctr_disable.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/resources/images/dev_ams_dry_ctr_enable.svg b/resources/images/dev_ams_dry_ctr_enable.svg new file mode 100644 index 0000000000..31eb482d17 --- /dev/null +++ b/resources/images/dev_ams_dry_ctr_enable.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/dev_ams_dry_ctr_filament_in_chamber.png b/resources/images/dev_ams_dry_ctr_filament_in_chamber.png new file mode 100644 index 0000000000..1b36643c42 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_filament_in_chamber.png differ diff --git a/resources/images/dev_ams_dry_ctr_heating_icon.svg b/resources/images/dev_ams_dry_ctr_heating_icon.svg new file mode 100644 index 0000000000..614b0c9a92 --- /dev/null +++ b/resources/images/dev_ams_dry_ctr_heating_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/dev_ams_dry_ctr_n3f_cooling.png b/resources/images/dev_ams_dry_ctr_n3f_cooling.png new file mode 100644 index 0000000000..6a43425da5 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3f_cooling.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3f_dehumidifying.png b/resources/images/dev_ams_dry_ctr_n3f_dehumidifying.png new file mode 100644 index 0000000000..92064da370 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3f_dehumidifying.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3f_error.png b/resources/images/dev_ams_dry_ctr_n3f_error.png new file mode 100644 index 0000000000..e0e49df9d1 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3f_error.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3f_heating.png b/resources/images/dev_ams_dry_ctr_n3f_heating.png new file mode 100644 index 0000000000..7c48397b63 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3f_heating.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3s_cooling.png b/resources/images/dev_ams_dry_ctr_n3s_cooling.png new file mode 100644 index 0000000000..f663c57c5f Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3s_cooling.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3s_dehumidifying.png b/resources/images/dev_ams_dry_ctr_n3s_dehumidifying.png new file mode 100644 index 0000000000..5926a6cb54 Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3s_dehumidifying.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3s_error.png b/resources/images/dev_ams_dry_ctr_n3s_error.png new file mode 100644 index 0000000000..0b3df1c3fe Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3s_error.png differ diff --git a/resources/images/dev_ams_dry_ctr_n3s_heating.png b/resources/images/dev_ams_dry_ctr_n3s_heating.png new file mode 100644 index 0000000000..3613a3aefc Binary files /dev/null and b/resources/images/dev_ams_dry_ctr_n3s_heating.png differ diff --git a/resources/images/dev_rack_home.svg b/resources/images/dev_rack_home.svg new file mode 100644 index 0000000000..76b59944de --- /dev/null +++ b/resources/images/dev_rack_home.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/dev_rack_nozzle_empty.svg b/resources/images/dev_rack_nozzle_empty.svg new file mode 100644 index 0000000000..2c2f53fec3 --- /dev/null +++ b/resources/images/dev_rack_nozzle_empty.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/resources/images/dev_rack_nozzle_error.svg b/resources/images/dev_rack_nozzle_error.svg new file mode 100644 index 0000000000..d477987c63 --- /dev/null +++ b/resources/images/dev_rack_nozzle_error.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/images/dev_rack_nozzle_error_icon.svg b/resources/images/dev_rack_nozzle_error_icon.svg new file mode 100644 index 0000000000..b1c9ebeec0 --- /dev/null +++ b/resources/images/dev_rack_nozzle_error_icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/dev_rack_nozzle_normal.svg b/resources/images/dev_rack_nozzle_normal.svg new file mode 100644 index 0000000000..43e196b699 --- /dev/null +++ b/resources/images/dev_rack_nozzle_normal.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/resources/images/dev_rack_nozzle_print_job.svg b/resources/images/dev_rack_nozzle_print_job.svg new file mode 100644 index 0000000000..204b17f516 --- /dev/null +++ b/resources/images/dev_rack_nozzle_print_job.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/resources/images/dev_rack_nozzle_selected.svg b/resources/images/dev_rack_nozzle_selected.svg new file mode 100644 index 0000000000..19f0bd66cc --- /dev/null +++ b/resources/images/dev_rack_nozzle_selected.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/dev_rack_nozzle_unknown.svg b/resources/images/dev_rack_nozzle_unknown.svg new file mode 100644 index 0000000000..d477987c63 --- /dev/null +++ b/resources/images/dev_rack_nozzle_unknown.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/resources/images/dev_rack_row_up.svg b/resources/images/dev_rack_row_up.svg new file mode 100644 index 0000000000..ee678db27a --- /dev/null +++ b/resources/images/dev_rack_row_up.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/dev_rack_toolhead_empty.svg b/resources/images/dev_rack_toolhead_empty.svg new file mode 100644 index 0000000000..2ee15d30d5 --- /dev/null +++ b/resources/images/dev_rack_toolhead_empty.svg @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/dev_rack_toolhead_normal.svg b/resources/images/dev_rack_toolhead_normal.svg new file mode 100644 index 0000000000..f0c3483a32 --- /dev/null +++ b/resources/images/dev_rack_toolhead_normal.svg @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/error.svg b/resources/images/error.svg new file mode 100644 index 0000000000..b9a251866e --- /dev/null +++ b/resources/images/error.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/images/extruder_badge_both_selected.svg b/resources/images/extruder_badge_both_selected.svg new file mode 100644 index 0000000000..02c8eca9a6 --- /dev/null +++ b/resources/images/extruder_badge_both_selected.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_both_selected_dark.svg b/resources/images/extruder_badge_both_selected_dark.svg new file mode 100644 index 0000000000..b04cfb27d0 --- /dev/null +++ b/resources/images/extruder_badge_both_selected_dark.svg @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected.svg b/resources/images/extruder_badge_left_selected.svg new file mode 100644 index 0000000000..a12b164c07 --- /dev/null +++ b/resources/images/extruder_badge_left_selected.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected_dark.svg b/resources/images/extruder_badge_left_selected_dark.svg new file mode 100644 index 0000000000..afab5c4417 --- /dev/null +++ b/resources/images/extruder_badge_left_selected_dark.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected_single.svg b/resources/images/extruder_badge_left_selected_single.svg new file mode 100644 index 0000000000..e0cd3299a8 --- /dev/null +++ b/resources/images/extruder_badge_left_selected_single.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_left_selected_single_dark.svg b/resources/images/extruder_badge_left_selected_single_dark.svg new file mode 100644 index 0000000000..12ba53d2b7 --- /dev/null +++ b/resources/images/extruder_badge_left_selected_single_dark.svg @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected.svg b/resources/images/extruder_badge_none_selected.svg new file mode 100644 index 0000000000..b15e9f2e15 --- /dev/null +++ b/resources/images/extruder_badge_none_selected.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected_dark.svg b/resources/images/extruder_badge_none_selected_dark.svg new file mode 100644 index 0000000000..00c7e7fe8c --- /dev/null +++ b/resources/images/extruder_badge_none_selected_dark.svg @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected_single.svg b/resources/images/extruder_badge_none_selected_single.svg new file mode 100644 index 0000000000..08d93b71a8 --- /dev/null +++ b/resources/images/extruder_badge_none_selected_single.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_none_selected_single_dark.svg b/resources/images/extruder_badge_none_selected_single_dark.svg new file mode 100644 index 0000000000..f0079099db --- /dev/null +++ b/resources/images/extruder_badge_none_selected_single_dark.svg @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_right_selected.svg b/resources/images/extruder_badge_right_selected.svg new file mode 100644 index 0000000000..d5c4d2aa73 --- /dev/null +++ b/resources/images/extruder_badge_right_selected.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/extruder_badge_right_selected_dark.svg b/resources/images/extruder_badge_right_selected_dark.svg new file mode 100644 index 0000000000..cd08bdde9b --- /dev/null +++ b/resources/images/extruder_badge_right_selected_dark.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/fd_calibration_auto_multi_extruders_o1c_left.png b/resources/images/fd_calibration_auto_multi_extruders_o1c_left.png new file mode 100644 index 0000000000..896d0eec8f Binary files /dev/null and b/resources/images/fd_calibration_auto_multi_extruders_o1c_left.png differ diff --git a/resources/images/fd_calibration_auto_multi_extruders_o1c_right.png b/resources/images/fd_calibration_auto_multi_extruders_o1c_right.png new file mode 100644 index 0000000000..8037c1d3d4 Binary files /dev/null and b/resources/images/fd_calibration_auto_multi_extruders_o1c_right.png differ diff --git a/resources/images/fila_switch.svg b/resources/images/fila_switch.svg new file mode 100644 index 0000000000..f9a1ed93d4 --- /dev/null +++ b/resources/images/fila_switch.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/fila_switch_error.svg b/resources/images/fila_switch_error.svg new file mode 100644 index 0000000000..e2be18ce39 --- /dev/null +++ b/resources/images/fila_switch_error.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/filament_load_o1c_series_ext0.png b/resources/images/filament_load_o1c_series_ext0.png new file mode 100644 index 0000000000..0642efb987 Binary files /dev/null and b/resources/images/filament_load_o1c_series_ext0.png differ diff --git a/resources/images/filament_load_o1c_series_ext1.png b/resources/images/filament_load_o1c_series_ext1.png new file mode 100644 index 0000000000..02fc001153 Binary files /dev/null and b/resources/images/filament_load_o1c_series_ext1.png differ diff --git a/resources/images/filament_track_switch.png b/resources/images/filament_track_switch.png new file mode 100644 index 0000000000..fe64bc442e Binary files /dev/null and b/resources/images/filament_track_switch.png differ diff --git a/resources/images/hotend_thumbnail.svg b/resources/images/hotend_thumbnail.svg new file mode 100644 index 0000000000..eb6af6bdeb --- /dev/null +++ b/resources/images/hotend_thumbnail.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/resources/images/leaf.svg b/resources/images/leaf.svg new file mode 100644 index 0000000000..48a3acf795 --- /dev/null +++ b/resources/images/leaf.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/images/nozzle_rack.png b/resources/images/nozzle_rack.png new file mode 100644 index 0000000000..007466af08 Binary files /dev/null and b/resources/images/nozzle_rack.png differ diff --git a/resources/images/param_z_contouring.svg b/resources/images/param_z_contouring.svg new file mode 100644 index 0000000000..38fc8f1a00 --- /dev/null +++ b/resources/images/param_z_contouring.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/images/printer_preview_N9.png b/resources/images/printer_preview_N9.png new file mode 100644 index 0000000000..513fa6fdaa Binary files /dev/null and b/resources/images/printer_preview_N9.png differ diff --git a/resources/images/printer_preview_O1C.png b/resources/images/printer_preview_O1C.png new file mode 100644 index 0000000000..b0d073423c Binary files /dev/null and b/resources/images/printer_preview_O1C.png differ diff --git a/resources/images/printer_preview_O1C2.png b/resources/images/printer_preview_O1C2.png new file mode 100644 index 0000000000..b0d073423c Binary files /dev/null and b/resources/images/printer_preview_O1C2.png differ diff --git a/resources/images/printer_thumbnail_o1c.png b/resources/images/printer_thumbnail_o1c.png new file mode 100644 index 0000000000..6d17d89278 Binary files /dev/null and b/resources/images/printer_thumbnail_o1c.png differ diff --git a/resources/images/printer_thumbnail_o1c_dark.png b/resources/images/printer_thumbnail_o1c_dark.png new file mode 100644 index 0000000000..6d17d89278 Binary files /dev/null and b/resources/images/printer_thumbnail_o1c_dark.png differ diff --git a/resources/images/printer_thumbnail_o1c_png.png b/resources/images/printer_thumbnail_o1c_png.png new file mode 100644 index 0000000000..6d17d89278 Binary files /dev/null and b/resources/images/printer_thumbnail_o1c_png.png differ diff --git a/resources/images/refresh_nozzle.svg b/resources/images/refresh_nozzle.svg new file mode 100644 index 0000000000..dcff81bcaa --- /dev/null +++ b/resources/images/refresh_nozzle.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/refresh_nozzle_1.svg b/resources/images/refresh_nozzle_1.svg new file mode 100644 index 0000000000..aa85d1e888 --- /dev/null +++ b/resources/images/refresh_nozzle_1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/refresh_nozzle_2.svg b/resources/images/refresh_nozzle_2.svg new file mode 100644 index 0000000000..5209c851b0 --- /dev/null +++ b/resources/images/refresh_nozzle_2.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/refresh_nozzle_3.svg b/resources/images/refresh_nozzle_3.svg new file mode 100644 index 0000000000..f59dded8b8 --- /dev/null +++ b/resources/images/refresh_nozzle_3.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/refresh_nozzle_4.svg b/resources/images/refresh_nozzle_4.svg new file mode 100644 index 0000000000..2d89fec145 --- /dev/null +++ b/resources/images/refresh_nozzle_4.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/resources/images/shield.svg b/resources/images/shield.svg new file mode 100644 index 0000000000..643ada60ad --- /dev/null +++ b/resources/images/shield.svg @@ -0,0 +1,4 @@ + + + + diff --git a/resources/printers/N9.json b/resources/printers/N9.json new file mode 100644 index 0000000000..05b42e17a6 --- /dev/null +++ b/resources/printers/N9.json @@ -0,0 +1,86 @@ +{ + "00.00.00.00": { + "display_name": "Bambu Lab A2L", + "print": { + "ipcam": { + "resolution_supported": [ "720p" ], + "liveview": { + "local": "local", + "remote": "tutk" + }, + "file": { + "remote": "tutk", + "model_download": "enabled" + } + }, + "nozzle_temp_range": [ 0, 300 ], + "nozzle_replace_wiki": { + "zh": "https://wiki.bambulab.com/zh/a1-mini/maintenance/hotend-heating-assembly-replacement", + "en": "https://wiki.bambulab.com/en/a1-mini/maintenance/hotend-heating-assembly-replacement" + }, + "support_motor_noise_cali": true, + "support_tunnel_mqtt": true, + "support_mqtt_alive": true, + "support_command_ams_switch": true, + "support_cloud_print_only": true, + "support_1080dpi": true, + "support_prompt_sound": true, + "support_ams_humidity": false, + "support_auto_recovery_step_loss": true, + "support_bed_leveling": 2, + "support_update_remain": false, + "support_timelapse": true, + "timelapse_slow_down": true, + "support_filament_backup": true, + "support_chamber_fan": false, + "support_aux_fan": false, + "support_send_to_sd": true, + "support_print_all": true, + "support_print_without_sd": false, + "support_flow_calibration": true, + "support_auto_flow_calibration": true, + "support_lidar_calibration": false, + "support_ai_monitoring": false, + "support_first_layer_inspect": false, + "support_chamber": false, + "support_chamber_temp_edit": false, + "support_extrusion_cali": true, + "support_user_preset": false, + "bed_temperature_limit": 80, + "support_ams_ext_mix_print": true, + "support_ams_settings_reorder": true, + "support_ams_settings_hide_image": true, + "support_high_tempbed_calibration": true, + "support_print_time_estimate_warning": true + }, + "model_id": "N9", + "compatible_machine": [], + "auto_on_cali_warning_tpu_filaments": [ "GFU03", "GFU04", "GFU01", "GFU00"], + "auto_pa_cali_thumbnail_image": "fd_calibration_auto_i3", + "support_wrapping_detection": false, + "printer_type": "N9", + "ftp_folder": "sdcard/", + "printer_thumbnail_image": "printer_thumbnail_n2s", + "printer_connect_help_image": "input_access_code_n1", + "printer_use_ams_image": "extra_icon", + "printer_ext_image": [ "ext_image_n2s" ], + "use_ams_type": "generic", + "printer_arch": "i3", + "printer_series": "series_n", + "has_cali_line": false, + "printer_is_enclosed": false, + "enable_set_nozzle_info": false, + "support_safety_options": false, + "air_print_detection_position": "print_option" + }, + "01.01.50.01": { + "print": { + "ipcam": { + "file": { + "remote": "tutk" + } + }, + "support_user_preset": true + } + } +} \ No newline at end of file diff --git a/resources/printers/O1C.json b/resources/printers/O1C.json new file mode 100644 index 0000000000..cdf4d6f8b3 --- /dev/null +++ b/resources/printers/O1C.json @@ -0,0 +1,98 @@ +{ + "00.00.00.00": { + "display_name": "Bambu Lab H2C", + "print": { + "2D": { + "laser": { + "power": [ 10, 40 ] + } + }, + "ipcam": { + "resolution_supported": [ "1080p" ], + "virtual_camera": "enabled", + "liveview": { + "remote": "tutk" + }, + "file": { + "local": "local", + "remote": "tutk", + "model_download": "enabled" + } + }, + "nozzle_temp_range": [ 0, 350 ], + "nozzle_replace_wiki": { + "zh": "https://wiki.bambulab.com/zh/h2/maintenance/replace-hotend", + "en": "https://wiki.bambulab.com/en/h2/maintenance/replace-hotend" + }, + "bed_temp_range": [ 0, 120 ], + "support_motor_noise_cali": false, + "support_tunnel_mqtt": true, + "support_mqtt_alive": true, + "support_command_ams_switch": true, + "support_ssl_for_mqtt": true, + "support_cloud_print_only": false, + "support_1080dpi": true, + "support_prompt_sound": false, + "support_ams_humidity": true, + "support_auto_recovery_step_loss": true, + "support_bed_leveling": 2, + "support_update_remain": true, + "support_timelapse": true, + "support_filament_backup": true, + "support_chamber_fan": true, + "support_aux_fan": true, + "support_send_to_sd": true, + "support_print_all": true, + "support_print_without_sd": true, + "support_flow_calibration": true, + "support_auto_flow_calibration": true, + "support_build_plate_marker_detect": true, + "support_build_plate_marker_detect_type": 2, + "support_lidar_calibration": false, + "support_nozzle_offset_calibration": true, + "support_high_tempbed_calibration": true, + "support_ai_monitoring": true, + "support_first_layer_inspect": false, + "support_save_remote_print_file_to_storage": true, + "support_chamber": true, + "support_chamber_temp_edit": true, + "support_chamber_temp_edit_range": [0, 65], + "support_chamber_temp_switch_heating": 40, + "support_extrusion_cali": false, + "support_print_check_extension_fan_f000_mounted": true, + "support_user_preset": false, + "support_ams_ext_mix_print": true, + "support_ams_filament_change_abort": true + }, + "model_id": "O1C", + "auto_pa_cali_thumbnail_image": "fd_calibration_auto_multi_extruders_o1c", + "support_wrapping_detection": true, + "printer_modes": [ "fdm", "laser", "cut" ], + "compatible_machine": [ "O1C2" ], + "printer_type": "O1C", + "printer_thumbnail_image": "printer_thumbnail_o1c", + "printer_connect_help_image": "input_access_code_h2d", + "printer_use_ams_image": "ams_icon", + "printer_ext_image": ["ext_image_o_right", "ext_image_o_left"], + "use_ams_type": "generic", + "printer_arch": "core_xy", + "printer_series": "series_o", + "has_cali_line": true, + "printer_is_enclosed": true, + "enable_set_nozzle_info": false, + "support_safety_options": false, + "filament_load_image": ["filament_load_o1c_series_ext0", "filament_load_o1c_series_ext1"], + "tool_head_display_names": { + "0": { + "extruder": ["Right Extruder", "Right extruder", "right extruder"], + "nozzle": ["Right Nozzle", "Right nozzle", "right nozzle"], + "hotend": ["Right Hotend", "Right hotend", "right hotend"] + }, + "1": { + "extruder": ["Left Extruder", "Left extruder", "left extruder"], + "nozzle": ["Left Nozzle", "Left nozzle", "left nozzle"], + "hotend": ["Left Hotend", "Left hotend", "left hotend"] + } + } + } +} \ No newline at end of file diff --git a/resources/printers/O1C2.json b/resources/printers/O1C2.json new file mode 100644 index 0000000000..bfcaf7e9cc --- /dev/null +++ b/resources/printers/O1C2.json @@ -0,0 +1,102 @@ +{ + "00.00.00.00": { + "display_name": "Bambu Lab H2C", + "print": { + "2D": { + "laser": { + "power": [ 10, 40 ] + } + }, + "ipcam": { + "resolution_supported": [ "1080p" ], + "virtual_camera": "enabled", + "liveview": { + "remote": "tutk" + }, + "file": { + "local": "local", + "remote": "tutk", + "model_download": "enabled" + } + }, + "nozzle_temp_range": [ 0, 350 ], + "nozzle_replace_wiki": { + "zh": "https://wiki.bambulab.com/zh/h2/maintenance/replace-hotend", + "en": "https://wiki.bambulab.com/en/h2/maintenance/replace-hotend" + }, + "bed_temp_range": [ 0, 120 ], + "support_motor_noise_cali": false, + "support_tunnel_mqtt": true, + "support_mqtt_alive": true, + "support_command_ams_switch": true, + "support_ssl_for_mqtt": true, + "support_cloud_print_only": false, + "support_1080dpi": true, + "support_prompt_sound": false, + "support_ams_humidity": true, + "support_auto_recovery_step_loss": true, + "support_bed_leveling": 2, + "support_update_remain": true, + "support_timelapse": true, + "support_filament_backup": true, + "support_chamber_fan": true, + "support_aux_fan": true, + "support_send_to_sd": true, + "support_print_all": true, + "support_print_without_sd": true, + "support_flow_calibration": true, + "support_auto_flow_calibration": true, + "support_build_plate_marker_detect": true, + "support_build_plate_marker_detect_type": 2, + "support_lidar_calibration": false, + "support_nozzle_offset_calibration": true, + "support_high_tempbed_calibration": true, + "support_ai_monitoring": true, + "support_first_layer_inspect": false, + "support_save_remote_print_file_to_storage": true, + "support_chamber": true, + "support_chamber_temp_edit": true, + "support_chamber_temp_edit_range": [0, 65], + "support_chamber_temp_switch_heating": 40, + "support_extrusion_cali": false, + "support_print_check_extension_fan_f000_mounted": true, + "support_user_preset": false, + "support_ams_ext_mix_print": true, + "support_ams_filament_change_abort": true, + "support_print_check_firmware_for_tpu_left": true, + "support_user_first_setup_tpu_check": true, + "support_user_first_setup_tpu_check_url": "https://e.bambulab.com/t?c=Db9YyP5qg3MHbSHD" + }, + "model_id": "O1C2", + "subseries": [ "O1C2-V2" ], + "auto_pa_cali_thumbnail_image": "fd_calibration_auto_multi_extruders_o1c", + "support_wrapping_detection": true, + "printer_modes": [ "fdm", "laser", "cut" ], + "compatible_machine": [ "O1C" ], + "printer_type": "O1C2", + "printer_thumbnail_image": "printer_thumbnail_o1c", + "printer_connect_help_image": "input_access_code_h2d", + "printer_use_ams_image": "ams_icon", + "printer_ext_image": ["ext_image_o_right", "ext_image_o_left"], + "use_ams_type": "generic", + "printer_arch": "core_xy", + "printer_series": "series_o", + "has_cali_line": true, + "printer_is_enclosed": true, + "enable_set_nozzle_info": false, + "support_safety_options": false, + "filament_load_image": ["filament_load_o1c_series_ext0", "filament_load_o1c_series_ext1"], + "tool_head_display_names": { + "0": { + "extruder": ["Right Extruder", "Right extruder", "right extruder"], + "nozzle": ["Right Nozzle", "Right nozzle", "right nozzle"], + "hotend": ["Right Hotend", "Right hotend", "right hotend"] + }, + "1": { + "extruder": ["Left Extruder", "Left extruder", "left extruder"], + "nozzle": ["Left Nozzle", "Left nozzle", "left nozzle"], + "hotend": ["Left Hotend", "Left hotend", "left hotend"] + } + } + } +} \ No newline at end of file diff --git a/resources/printers/filaments_blacklist.json b/resources/printers/filaments_blacklist.json index bba05552c6..1f484c0c20 100644 --- a/resources/printers/filaments_blacklist.json +++ b/resources/printers/filaments_blacklist.json @@ -95,6 +95,224 @@ "action": "warning", "slot": "ams", "description": "The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite." + }, + { + "types": ["TPU"], + "action": "warning", + "model_id": ["O1C2"], + "description": "How to feed TPU filament.", + "wiki": "https://e.bambulab.com/t?c=Db9YyP5qg3MHbSHD" + }, + { + "type_suffix": "CF", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7"], + "action": "warning", + "slot": "ext", + "description": "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." + }, + { + "name_suffix": "PA6-GF", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7", "N6"], + "action": "warning", + "slot": "ext", + "description": "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." + }, + { + "type_suffix": "CF", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7", "N6"], + "action": "warning", + "slot": "ams", + "description": "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." + }, + { + "name_suffix": "PA6-GF", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7", "N6"], + "action": "warning", + "slot": "ams", + "description": "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution." + }, + { + "name_suffix": "TPU 85A", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4, 0.6, 0.8], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7", "N6"], + "action": "warning", + "slot": "ext", + "description": "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." + }, + { + "name_suffix": "TPU 90A", + "nozzle_flows": ["High Flow"], + "nozzle_diameters": [0.4, 0.6, 0.8], + "model_id": ["O1D", "O1S", "O1E", "O1C", "O1C2", "N7", "N6"], + "action": "warning", + "slot": "ext", + "description": "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution." + }, + { + "name_suffix": "PA6-GF", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "type": "PPS-CF", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "type": "PLA-Aero", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "type": "ASA-Aero", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "name_suffix": "TPU 85A", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "name_suffix": "TPU 90A", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "prohibition", + "description": "The current filament doesn't support the E3D high-flow nozzle and can't be used." + }, + { + "white_fila_ids": ["GFU04", "GFU03", "GFU01", "GFU00", "GFU99"], + "nozzle_flows": ["TPU High Flow"], + "model_id": ["O1D", "O1E"], + "action": "prohibition", + "description": "The current filament doesn't support the TPU high-flow nozzle and can't be used." + }, + { + "type": "TPU", + "action": "prohibition", + "calib_mode": "auto_pa", + "model_id": ["O1D", "O1E"], + "description": "Auto dynamic flow calibration is not supported for TPU filament." + }, + { + "name_suffix": "Bambu TPU 85A", + "nozzle_flows": ["Standard", "High Flow"], + "nozzle_diameters": [0.4], + "model_id": ["O1D", "O1E"], + "action": "prohibition", + "description": "Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles." + }, + { + "types": ["TPU", "TPU-AMS"], + "action": "warning", + "model_id": ["N7"], + "description": "How to feed TPU filament.", + "wiki": "https://e.bambulab.com/t?c=blx2TDu3uoRdfyIx" + }, + { + "types": ["TPU"], + "action": "warning", + "model_id": ["O1D"], + "description": "How to feed TPU filament.", + "wiki": "https://e.bambulab.com/t?c=fwWqpBg37Liel92N" + }, + { + "types": ["TPU"], + "action": "warning", + "model_id": ["O1E"], + "description": "How to feed TPU filament.", + "wiki": "https://e.bambulab.com/t?c=fwWqpBg37Liel92N" + }, + { + "types": ["TPU"], + "action": "warning", + "model_id": ["O1S"], + "description": "How to feed TPU filament.", + "wiki": "https://e.bambulab.com/t?c=L45sIEpzy1Wz0tsV" + }, + { + "type": "PLA", + "name_suffix": "PLA Silk", + "action": "warning", + "slot": "ams", + "has_filament_switch": true, + "description": "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue.", + "wiki": "https://e.bambulab.com/t?c=s0CgMOrctZiPablB" + }, + { + "name_suffix": "PC FR", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "PLA Silk", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "Support For PA/PET", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "PVA", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "Support For PLA", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "Support For PLA/PETG", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" + }, + { + "name_suffix": "Support for ABS", + "nozzle_flows": ["High Flow"], + "model_id": ["C11", "C12", "BL-P001"], + "action": "warning", + "description": "Default settings may affect print quality. Adjust as needed for best results.", + "wiki": "https://wiki.bambulab.com/en/accessories/e3d-hotend" } ] } diff --git a/resources/printers/version.txt b/resources/printers/version.txt index 8b31e51e65..6f0c7f552f 100644 --- a/resources/printers/version.txt +++ b/resources/printers/version.txt @@ -1 +1 @@ -02.00.00.30 \ No newline at end of file +02.00.00.31 \ No newline at end of file diff --git a/resources/profiles/BBL.json b/resources/profiles/BBL.json index 67551e9685..d264629348 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.19", + "version": "02.01.00.22", "force_update": "0", "description": "BBL configurations", "machine_model_list": [ @@ -13,6 +13,14 @@ "name": "Bambu Lab A1 mini", "sub_path": "machine/Bambu Lab A1 mini.json" }, + { + "name": "Bambu Lab A2L", + "sub_path": "machine/Bambu Lab A2L.json" + }, + { + "name": "Bambu Lab H2C", + "sub_path": "machine/Bambu Lab H2C.json" + }, { "name": "Bambu Lab H2D", "sub_path": "machine/Bambu Lab H2D.json" @@ -1026,6 +1034,138 @@ { "name": "0.56mm Standard @BBL X1C 0.8 nozzle", "sub_path": "process/0.56mm Standard @BBL X1C 0.8 nozzle.json" + }, + { + "name": "0.08mm High Quality @BBL A2L", + "sub_path": "process/0.08mm High Quality @BBL A2L.json" + }, + { + "name": "0.08mm High Quality @BBL A2L 0.2 nozzle", + "sub_path": "process/0.08mm High Quality @BBL A2L 0.2 nozzle.json" + }, + { + "name": "0.08mm High Quality @BBL H2C", + "sub_path": "process/0.08mm High Quality @BBL H2C.json" + }, + { + "name": "0.08mm High Quality @BBL H2C 0.2 nozzle", + "sub_path": "process/0.08mm High Quality @BBL H2C 0.2 nozzle.json" + }, + { + "name": "0.10mm Standard @BBL A2L 0.2 nozzle", + "sub_path": "process/0.10mm Standard @BBL A2L 0.2 nozzle.json" + }, + { + "name": "0.10mm Standard @BBL H2C 0.2 nozzle", + "sub_path": "process/0.10mm Standard @BBL H2C 0.2 nozzle.json" + }, + { + "name": "0.12mm Balanced Quality @BBL A2L 0.2 nozzle", + "sub_path": "process/0.12mm Balanced Quality @BBL A2L 0.2 nozzle.json" + }, + { + "name": "0.12mm Balanced Quality @BBL H2C 0.2 nozzle", + "sub_path": "process/0.12mm Balanced Quality @BBL H2C 0.2 nozzle.json" + }, + { + "name": "0.12mm High Quality @BBL A2L", + "sub_path": "process/0.12mm High Quality @BBL A2L.json" + }, + { + "name": "0.12mm High Quality @BBL H2C", + "sub_path": "process/0.12mm High Quality @BBL H2C.json" + }, + { + "name": "0.16mm High Quality @BBL A2L", + "sub_path": "process/0.16mm High Quality @BBL A2L.json" + }, + { + "name": "0.16mm High Quality @BBL H2C", + "sub_path": "process/0.16mm High Quality @BBL H2C.json" + }, + { + "name": "0.16mm Standard @BBL A2L", + "sub_path": "process/0.16mm Standard @BBL A2L.json" + }, + { + "name": "0.16mm Standard @BBL H2C", + "sub_path": "process/0.16mm Standard @BBL H2C.json" + }, + { + "name": "0.18mm Balanced Quality @BBL A2L 0.6 nozzle", + "sub_path": "process/0.18mm Balanced Quality @BBL A2L 0.6 nozzle.json" + }, + { + "name": "0.18mm Balanced Quality @BBL H2C 0.6 nozzle", + "sub_path": "process/0.18mm Balanced Quality @BBL H2C 0.6 nozzle.json" + }, + { + "name": "0.20mm High Quality @BBL A2L", + "sub_path": "process/0.20mm High Quality @BBL A2L.json" + }, + { + "name": "0.20mm High Quality @BBL H2C", + "sub_path": "process/0.20mm High Quality @BBL H2C.json" + }, + { + "name": "0.20mm Standard @BBL A2L", + "sub_path": "process/0.20mm Standard @BBL A2L.json" + }, + { + "name": "0.20mm Standard @BBL H2C", + "sub_path": "process/0.20mm Standard @BBL H2C.json" + }, + { + "name": "0.20mm Steady @BBL A2L", + "sub_path": "process/0.20mm Steady @BBL A2L.json" + }, + { + "name": "0.24mm Balanced Quality @BBL A2L 0.6 nozzle", + "sub_path": "process/0.24mm Balanced Quality @BBL A2L 0.6 nozzle.json" + }, + { + "name": "0.24mm Balanced Quality @BBL A2L 0.8 nozzle", + "sub_path": "process/0.24mm Balanced Quality @BBL A2L 0.8 nozzle.json" + }, + { + "name": "0.24mm Balanced Quality @BBL H2C 0.8 nozzle", + "sub_path": "process/0.24mm Balanced Quality @BBL H2C 0.8 nozzle.json" + }, + { + "name": "0.24mm Balanced Strength @BBL H2C 0.6 nozzle", + "sub_path": "process/0.24mm Balanced Strength @BBL H2C 0.6 nozzle.json" + }, + { + "name": "0.24mm Standard @BBL A2L", + "sub_path": "process/0.24mm Standard @BBL A2L.json" + }, + { + "name": "0.24mm Standard @BBL H2C", + "sub_path": "process/0.24mm Standard @BBL H2C.json" + }, + { + "name": "0.30mm Standard @BBL A2L 0.6 nozzle", + "sub_path": "process/0.30mm Standard @BBL A2L 0.6 nozzle.json" + }, + { + "name": "0.30mm Standard @BBL H2C 0.6 nozzle", + "sub_path": "process/0.30mm Standard @BBL H2C 0.6 nozzle.json" + }, + { + "name": "0.32mm Balanced Quality @BBL A2L 0.8 nozzle", + "sub_path": "process/0.32mm Balanced Quality @BBL A2L 0.8 nozzle.json" + }, + { + "name": "0.32mm Balanced Strength @BBL H2C 0.8 nozzle", + "sub_path": "process/0.32mm Balanced Strength @BBL H2C 0.8 nozzle.json" + }, + { + "name": "0.40mm Standard @BBL A2L 0.8 nozzle", + "sub_path": "process/0.40mm Standard @BBL A2L 0.8 nozzle.json" + }, + { + "name": "0.40mm Standard @BBL H2C 0.8 nozzle", + "sub_path": "process/0.40mm Standard @BBL H2C 0.8 nozzle.json" } ], "filament_list": [ @@ -3793,6 +3933,10 @@ "name": "Bambu PETG Basic @BBL H2S 0.2 nozzle", "sub_path": "filament/Bambu PETG Basic @BBL H2S 0.2 nozzle.json" }, + { + "name": "Bambu PETG Basic @BBL H2S 0.6 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json" + }, { "name": "Bambu PETG Basic @BBL P2S 0.2 nozzle", "sub_path": "filament/Bambu PETG Basic @BBL P2S 0.2 nozzle.json" @@ -8721,10 +8865,18 @@ "name": "Bambu TPU 85A @BBL H2D", "sub_path": "filament/Bambu TPU 85A @BBL H2D.json" }, + { + "name": "Bambu TPU 85A @BBL H2D 0.4 nozzle", + "sub_path": "filament/Bambu TPU 85A @BBL H2D 0.4 nozzle.json" + }, { "name": "Bambu TPU 85A @BBL H2DP", "sub_path": "filament/Bambu TPU 85A @BBL H2DP.json" }, + { + "name": "Bambu TPU 85A @BBL H2DP 0.4 nozzle", + "sub_path": "filament/Bambu TPU 85A @BBL H2DP 0.4 nozzle.json" + }, { "name": "Bambu TPU 85A @BBL H2S", "sub_path": "filament/Bambu TPU 85A @BBL H2S.json" @@ -8773,10 +8925,26 @@ "name": "Bambu TPU 90A @BBL H2D", "sub_path": "filament/Bambu TPU 90A @BBL H2D.json" }, + { + "name": "Bambu TPU 90A @BBL H2D 0.6 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json" + }, + { + "name": "Bambu TPU 90A @BBL H2D 0.8 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json" + }, { "name": "Bambu TPU 90A @BBL H2DP", "sub_path": "filament/Bambu TPU 90A @BBL H2DP.json" }, + { + "name": "Bambu TPU 90A @BBL H2DP 0.6 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json" + }, + { + "name": "Bambu TPU 90A @BBL H2DP 0.8 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json" + }, { "name": "Bambu TPU 90A @BBL H2S", "sub_path": "filament/Bambu TPU 90A @BBL H2S.json" @@ -8877,10 +9045,18 @@ "name": "Bambu TPU 95A HF @BBL H2D", "sub_path": "filament/Bambu TPU 95A HF @BBL H2D.json" }, + { + "name": "Bambu TPU 95A HF @BBL H2D 0.4 nozzle", + "sub_path": "filament/Bambu TPU 95A HF @BBL H2D 0.4 nozzle.json" + }, { "name": "Bambu TPU 95A HF @BBL H2DP", "sub_path": "filament/Bambu TPU 95A HF @BBL H2DP.json" }, + { + "name": "Bambu TPU 95A HF @BBL H2DP 0.4 nozzle", + "sub_path": "filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json" + }, { "name": "Bambu TPU 95A HF @BBL H2S", "sub_path": "filament/Bambu TPU 95A HF @BBL H2S.json" @@ -9816,6 +9992,1294 @@ { "name": "fdm_filament_dual_common", "sub_path": "filament/fdm_filament_dual_common.json" + }, + { + "name": "Bambu ABS @BBL H2C", + "sub_path": "filament/Bambu ABS @BBL H2C.json" + }, + { + "name": "Bambu ABS @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu ABS @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu ABS @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu ABS @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu ABS @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu ABS @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu ABS-GF @BBL H2C", + "sub_path": "filament/Bambu ABS-GF @BBL H2C.json" + }, + { + "name": "Bambu ABS-GF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu ASA @BBL H2C", + "sub_path": "filament/Bambu ASA @BBL H2C.json" + }, + { + "name": "Bambu ASA @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu ASA @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu ASA @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu ASA @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu ASA @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu ASA @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu ASA-Aero @BBL H2C", + "sub_path": "filament/Bambu ASA-Aero @BBL H2C.json" + }, + { + "name": "Bambu ASA-Aero @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu ASA-CF @BBL H2C", + "sub_path": "filament/Bambu ASA-CF @BBL H2C.json" + }, + { + "name": "Bambu ASA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PA-CF @BBL H2C", + "sub_path": "filament/Bambu PA-CF @BBL H2C.json" + }, + { + "name": "Bambu PA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PA6-CF @BBL H2C", + "sub_path": "filament/Bambu PA6-CF @BBL H2C.json" + }, + { + "name": "Bambu PA6-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PA6-GF @BBL H2C", + "sub_path": "filament/Bambu PA6-GF @BBL H2C.json" + }, + { + "name": "Bambu PA6-GF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PAHT-CF @BBL H2C", + "sub_path": "filament/Bambu PAHT-CF @BBL H2C.json" + }, + { + "name": "Bambu PAHT-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PC @BBL H2C", + "sub_path": "filament/Bambu PC @BBL H2C.json" + }, + { + "name": "Bambu PC @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PC @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PC @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu PC @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu PC @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu PC @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu PC FR @BBL H2C", + "sub_path": "filament/Bambu PC FR @BBL H2C.json" + }, + { + "name": "Bambu PC FR @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PC FR @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PC FR @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PC FR @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PET-CF @BBL H2C", + "sub_path": "filament/Bambu PET-CF @BBL H2C.json" + }, + { + "name": "Bambu PET-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL H2C", + "sub_path": "filament/Bambu PETG Basic @BBL H2C.json" + }, + { + "name": "Bambu PETG Basic @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PETG Basic @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL A2L", + "sub_path": "filament/Bambu PETG HF @BBL A2L.json" + }, + { + "name": "Bambu PETG HF @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL H2C", + "sub_path": "filament/Bambu PETG HF @BBL H2C.json" + }, + { + "name": "Bambu PETG HF @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu PETG HF @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu PETG Translucent @BBL A2L", + "sub_path": "filament/Bambu PETG Translucent @BBL A2L.json" + }, + { + "name": "Bambu PETG Translucent @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PETG Translucent @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PETG Translucent @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PETG Translucent @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PETG Translucent @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PETG Translucent @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PETG Translucent @BBL H2C", + "sub_path": "filament/Bambu PETG Translucent @BBL H2C.json" + }, + { + "name": "Bambu PETG Translucent @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PETG Translucent @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PETG-CF @BBL A2L", + "sub_path": "filament/Bambu PETG-CF @BBL A2L.json" + }, + { + "name": "Bambu PETG-CF @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PETG-CF @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PETG-CF @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PETG-CF @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PETG-CF @BBL H2C", + "sub_path": "filament/Bambu PETG-CF @BBL H2C.json" + }, + { + "name": "Bambu PETG-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Aero @BBL A2L", + "sub_path": "filament/Bambu PLA Aero @BBL A2L.json" + }, + { + "name": "Bambu PLA Aero @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Aero @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Aero @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Aero @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Aero @BBL H2C", + "sub_path": "filament/Bambu PLA Aero @BBL H2C.json" + }, + { + "name": "Bambu PLA Aero @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL H2C", + "sub_path": "filament/Bambu PLA Basic @BBL H2C.json" + }, + { + "name": "Bambu PLA Basic @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Basic @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Dynamic @BBL A2L", + "sub_path": "filament/Bambu PLA Dynamic @BBL A2L.json" + }, + { + "name": "Bambu PLA Dynamic @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Dynamic @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Dynamic @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Dynamic @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Dynamic @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Dynamic @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Dynamic @BBL H2C", + "sub_path": "filament/Bambu PLA Dynamic @BBL H2C.json" + }, + { + "name": "Bambu PLA Dynamic @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Dynamic @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Galaxy @BBL A2L", + "sub_path": "filament/Bambu PLA Galaxy @BBL A2L.json" + }, + { + "name": "Bambu PLA Galaxy @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Galaxy @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Galaxy @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Galaxy @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Galaxy @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Galaxy @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Galaxy @BBL H2C", + "sub_path": "filament/Bambu PLA Galaxy @BBL H2C.json" + }, + { + "name": "Bambu PLA Galaxy @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Galaxy @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Glow @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Glow @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Glow @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Glow @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Glow @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Glow @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Glow @BBL H2C", + "sub_path": "filament/Bambu PLA Glow @BBL H2C.json" + }, + { + "name": "Bambu PLA Glow @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL H2C", + "sub_path": "filament/Bambu PLA Lite @BBL H2C.json" + }, + { + "name": "Bambu PLA Lite @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Lite @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Marble @BBL A2L", + "sub_path": "filament/Bambu PLA Marble @BBL A2L.json" + }, + { + "name": "Bambu PLA Marble @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Marble @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Marble @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Marble @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Marble @BBL H2C", + "sub_path": "filament/Bambu PLA Marble @BBL H2C.json" + }, + { + "name": "Bambu PLA Marble @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL H2C", + "sub_path": "filament/Bambu PLA Matte @BBL H2C.json" + }, + { + "name": "Bambu PLA Matte @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Matte @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Metal @BBL A2L", + "sub_path": "filament/Bambu PLA Metal @BBL A2L.json" + }, + { + "name": "Bambu PLA Metal @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Metal @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Metal @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Metal @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Metal @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Metal @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Metal @BBL H2C", + "sub_path": "filament/Bambu PLA Metal @BBL H2C.json" + }, + { + "name": "Bambu PLA Metal @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Metal @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Pure @base", + "sub_path": "filament/Bambu PLA Pure @base.json" + }, + { + "name": "Bambu PLA Pure @BBL A2L", + "sub_path": "filament/Bambu PLA Pure @BBL A2L.json" + }, + { + "name": "Bambu PLA Pure @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2C", + "sub_path": "filament/Bambu PLA Pure @BBL H2C.json" + }, + { + "name": "Bambu PLA Pure @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2D", + "sub_path": "filament/Bambu PLA Pure @BBL H2D.json" + }, + { + "name": "Bambu PLA Pure @BBL H2D 0.2 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2D 0.8 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2DP", + "sub_path": "filament/Bambu PLA Pure @BBL H2DP.json" + }, + { + "name": "Bambu PLA Pure @BBL H2DP 0.2 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2DP 0.8 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Pure @BBL H2S", + "sub_path": "filament/Bambu PLA Pure @BBL H2S.json" + }, + { + "name": "Bambu PLA Pure @BBL H2S 0.2 nozzle", + "sub_path": "filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL H2C", + "sub_path": "filament/Bambu PLA Silk @BBL H2C.json" + }, + { + "name": "Bambu PLA Silk @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Silk @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL H2C", + "sub_path": "filament/Bambu PLA Silk+ @BBL H2C.json" + }, + { + "name": "Bambu PLA Silk+ @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Silk+ @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Sparkle @BBL A2L", + "sub_path": "filament/Bambu PLA Sparkle @BBL A2L.json" + }, + { + "name": "Bambu PLA Sparkle @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Sparkle @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Sparkle @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Sparkle @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Sparkle @BBL H2C", + "sub_path": "filament/Bambu PLA Sparkle @BBL H2C.json" + }, + { + "name": "Bambu PLA Sparkle @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Tough @BBL A2L", + "sub_path": "filament/Bambu PLA Tough @BBL A2L.json" + }, + { + "name": "Bambu PLA Tough @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Tough @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Tough @BBL H2C", + "sub_path": "filament/Bambu PLA Tough @BBL H2C.json" + }, + { + "name": "Bambu PLA Tough @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Tough @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL A2L 0.4 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL A2L 0.4 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL H2C", + "sub_path": "filament/Bambu PLA Tough+ @BBL H2C.json" + }, + { + "name": "Bambu PLA Tough+ @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL H2C 0.6 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Tough+ @BBL H2C 0.8 nozzle", + "sub_path": "filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Translucent @BBL A2L", + "sub_path": "filament/Bambu PLA Translucent @BBL A2L.json" + }, + { + "name": "Bambu PLA Translucent @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu PLA Translucent @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Translucent @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Translucent @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Translucent @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Translucent @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Translucent @BBL H2C", + "sub_path": "filament/Bambu PLA Translucent @BBL H2C.json" + }, + { + "name": "Bambu PLA Translucent @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu PLA Wood @BBL A2L", + "sub_path": "filament/Bambu PLA Wood @BBL A2L.json" + }, + { + "name": "Bambu PLA Wood @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA Wood @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA Wood @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA Wood @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA Wood @BBL H2C", + "sub_path": "filament/Bambu PLA Wood @BBL H2C.json" + }, + { + "name": "Bambu PLA Wood @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PLA-CF @BBL A2L", + "sub_path": "filament/Bambu PLA-CF @BBL A2L.json" + }, + { + "name": "Bambu PLA-CF @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu PLA-CF @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu PLA-CF @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu PLA-CF @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu PLA-CF @BBL H2C", + "sub_path": "filament/Bambu PLA-CF @BBL H2C.json" + }, + { + "name": "Bambu PLA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PPA-CF @BBL H2C", + "sub_path": "filament/Bambu PPA-CF @BBL H2C.json" + }, + { + "name": "Bambu PPA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PPS-CF @BBL H2C", + "sub_path": "filament/Bambu PPS-CF @BBL H2C.json" + }, + { + "name": "Bambu PPS-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu PVA @BBL A2L", + "sub_path": "filament/Bambu PVA @BBL A2L.json" + }, + { + "name": "Bambu PVA @BBL H2C", + "sub_path": "filament/Bambu PVA @BBL H2C.json" + }, + { + "name": "Bambu PVA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu PVA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support For PA/PET @BBL H2C", + "sub_path": "filament/Bambu Support For PA PET @BBL H2C.json" + }, + { + "name": "Bambu Support For PA/PET @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support For PLA @BBL A2L", + "sub_path": "filament/Bambu Support For PLA @BBL A2L.json" + }, + { + "name": "Bambu Support For PLA @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu Support For PLA @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu Support For PLA @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu Support For PLA @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu Support For PLA @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu Support For PLA @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu Support For PLA @BBL H2C", + "sub_path": "filament/Bambu Support For PLA @BBL H2C.json" + }, + { + "name": "Bambu Support For PLA @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu Support For PLA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support For PLA/PETG @BBL A2L", + "sub_path": "filament/Bambu Support For PLA-PETG @BBL A2L.json" + }, + { + "name": "Bambu Support For PLA/PETG @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu Support For PLA-PETG @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu Support For PLA/PETG @BBL H2C", + "sub_path": "filament/Bambu Support For PLA-PETG @BBL H2C.json" + }, + { + "name": "Bambu Support For PLA/PETG @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu Support For PLA/PETG @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support G @BBL H2C", + "sub_path": "filament/Bambu Support G @BBL H2C.json" + }, + { + "name": "Bambu Support G @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support G @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support W @BBL A2L", + "sub_path": "filament/Bambu Support W @BBL A2L.json" + }, + { + "name": "Bambu Support W @BBL A2L 0.2 nozzle", + "sub_path": "filament/Bambu Support W @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Bambu Support W @BBL H2C", + "sub_path": "filament/Bambu Support W @BBL H2C.json" + }, + { + "name": "Bambu Support W @BBL H2C 0.2 nozzle", + "sub_path": "filament/Bambu Support W @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Bambu Support W @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support W @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Support for ABS @BBL H2C", + "sub_path": "filament/Bambu Support for ABS @BBL H2C.json" + }, + { + "name": "Bambu Support for ABS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu TPU 85A @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu TPU 85A @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu TPU 85A @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu TPU 85A @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu TPU 85A @BBL H2C", + "sub_path": "filament/Bambu TPU 85A @BBL H2C.json" + }, + { + "name": "Bambu TPU 90A @BBL A2L", + "sub_path": "filament/Bambu TPU 90A @BBL A2L.json" + }, + { + "name": "Bambu TPU 90A @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu TPU 90A @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu TPU 90A @BBL H2C", + "sub_path": "filament/Bambu TPU 90A @BBL H2C.json" + }, + { + "name": "Bambu TPU 90A @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu TPU 95A @BBL A2L", + "sub_path": "filament/Bambu TPU 95A @BBL A2L.json" + }, + { + "name": "Bambu TPU 95A @BBL H2C", + "sub_path": "filament/Bambu TPU 95A @BBL H2C.json" + }, + { + "name": "Bambu TPU 95A @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu TPU 95A HF @BBL A2L", + "sub_path": "filament/Bambu TPU 95A HF @BBL A2L.json" + }, + { + "name": "Bambu TPU 95A HF @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu TPU 95A HF @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu TPU 95A HF @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu TPU 95A HF @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu TPU 95A HF @BBL H2C", + "sub_path": "filament/Bambu TPU 95A HF @BBL H2C.json" + }, + { + "name": "Bambu TPU 95A HF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Bambu TPU for AMS @BBL A2L", + "sub_path": "filament/Bambu TPU for AMS @BBL A2L.json" + }, + { + "name": "Bambu TPU for AMS @BBL A2L 0.6 nozzle", + "sub_path": "filament/Bambu TPU for AMS @BBL A2L 0.6 nozzle.json" + }, + { + "name": "Bambu TPU for AMS @BBL A2L 0.8 nozzle", + "sub_path": "filament/Bambu TPU for AMS @BBL A2L 0.8 nozzle.json" + }, + { + "name": "Bambu TPU for AMS @BBL H2C", + "sub_path": "filament/Bambu TPU for AMS @BBL H2C.json" + }, + { + "name": "Bambu TPU for AMS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic ABS @BBL H2C", + "sub_path": "filament/Generic ABS @BBL H2C.json" + }, + { + "name": "Generic ABS @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic ABS @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic ABS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic ABS @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic ASA @BBL H2C", + "sub_path": "filament/Generic ASA @BBL H2C.json" + }, + { + "name": "Generic ASA @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic ASA @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic ASA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic ASA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic BVOH @BBL A2L", + "sub_path": "filament/Generic BVOH @BBL A2L.json" + }, + { + "name": "Generic BVOH @BBL H2C", + "sub_path": "filament/Generic BVOH @BBL H2C.json" + }, + { + "name": "Generic BVOH @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic BVOH @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic EVA @BBL A2L", + "sub_path": "filament/Generic EVA @BBL A2L.json" + }, + { + "name": "Generic EVA @BBL H2C", + "sub_path": "filament/Generic EVA @BBL H2C.json" + }, + { + "name": "Generic EVA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic EVA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic HIPS @BBL A2L", + "sub_path": "filament/Generic HIPS @BBL A2L.json" + }, + { + "name": "Generic HIPS @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic HIPS @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic HIPS @BBL H2C", + "sub_path": "filament/Generic HIPS @BBL H2C.json" + }, + { + "name": "Generic HIPS @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic HIPS @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic HIPS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic HIPS @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PA @BBL H2C", + "sub_path": "filament/Generic PA @BBL H2C.json" + }, + { + "name": "Generic PA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PA-CF @BBL H2C", + "sub_path": "filament/Generic PA-CF @BBL H2C.json" + }, + { + "name": "Generic PA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PC @BBL H2C", + "sub_path": "filament/Generic PC @BBL H2C.json" + }, + { + "name": "Generic PC @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PC @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PC @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PC @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PCTG @BBL A2L", + "sub_path": "filament/Generic PCTG @BBL A2L.json" + }, + { + "name": "Generic PCTG @BBL H2C", + "sub_path": "filament/Generic PCTG @BBL H2C.json" + }, + { + "name": "Generic PCTG @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PCTG @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PE @BBL A2L", + "sub_path": "filament/Generic PE @BBL A2L.json" + }, + { + "name": "Generic PE @BBL H2C", + "sub_path": "filament/Generic PE @BBL H2C.json" + }, + { + "name": "Generic PE @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PE @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PE-CF @BBL A2L", + "sub_path": "filament/Generic PE-CF @BBL A2L.json" + }, + { + "name": "Generic PE-CF @BBL H2C", + "sub_path": "filament/Generic PE-CF @BBL H2C.json" + }, + { + "name": "Generic PE-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PE-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PETG @BBL A2L", + "sub_path": "filament/Generic PETG @BBL A2L.json" + }, + { + "name": "Generic PETG @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic PETG @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic PETG @BBL H2C", + "sub_path": "filament/Generic PETG @BBL H2C.json" + }, + { + "name": "Generic PETG @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PETG @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PETG @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PETG @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PETG HF @BBL A2L", + "sub_path": "filament/Generic PETG HF @BBL A2L.json" + }, + { + "name": "Generic PETG HF @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic PETG HF @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic PETG HF @BBL H2C", + "sub_path": "filament/Generic PETG HF @BBL H2C.json" + }, + { + "name": "Generic PETG HF @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PETG HF @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PETG HF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PETG HF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PETG-CF @BBL A2L", + "sub_path": "filament/Generic PETG-CF @BBL A2L.json" + }, + { + "name": "Generic PETG-CF @BBL H2C", + "sub_path": "filament/Generic PETG-CF @BBL H2C.json" + }, + { + "name": "Generic PETG-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PHA @BBL A2L", + "sub_path": "filament/Generic PHA @BBL A2L.json" + }, + { + "name": "Generic PHA @BBL H2C", + "sub_path": "filament/Generic PHA @BBL H2C.json" + }, + { + "name": "Generic PHA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PHA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PLA @BBL A2L", + "sub_path": "filament/Generic PLA @BBL A2L.json" + }, + { + "name": "Generic PLA @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic PLA @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic PLA @BBL H2C", + "sub_path": "filament/Generic PLA @BBL H2C.json" + }, + { + "name": "Generic PLA @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PLA @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PLA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PLA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PLA High Speed @BBL A2L", + "sub_path": "filament/Generic PLA High Speed @BBL A2L.json" + }, + { + "name": "Generic PLA High Speed @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic PLA High Speed @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic PLA High Speed @BBL H2C", + "sub_path": "filament/Generic PLA High Speed @BBL H2C.json" + }, + { + "name": "Generic PLA High Speed @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PLA High Speed @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PLA Silk @BBL A2L", + "sub_path": "filament/Generic PLA Silk @BBL A2L.json" + }, + { + "name": "Generic PLA Silk @BBL H2C", + "sub_path": "filament/Generic PLA Silk @BBL H2C.json" + }, + { + "name": "Generic PLA Silk @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PLA-CF @BBL A2L", + "sub_path": "filament/Generic PLA-CF @BBL A2L.json" + }, + { + "name": "Generic PLA-CF @BBL H2C", + "sub_path": "filament/Generic PLA-CF @BBL H2C.json" + }, + { + "name": "Generic PLA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PP @BBL A2L", + "sub_path": "filament/Generic PP @BBL A2L.json" + }, + { + "name": "Generic PP @BBL H2C", + "sub_path": "filament/Generic PP @BBL H2C.json" + }, + { + "name": "Generic PP @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PP @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PP-CF @BBL H2C", + "sub_path": "filament/Generic PP-CF @BBL H2C.json" + }, + { + "name": "Generic PP-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PP-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PP-GF @BBL H2C", + "sub_path": "filament/Generic PP-GF @BBL H2C.json" + }, + { + "name": "Generic PP-GF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PP-GF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PPA-CF @BBL H2C", + "sub_path": "filament/Generic PPA-CF @BBL H2C.json" + }, + { + "name": "Generic PPA-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PPA-GF @BBL H2C", + "sub_path": "filament/Generic PPA-GF @BBL H2C.json" + }, + { + "name": "Generic PPA-GF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PPS @BBL H2C", + "sub_path": "filament/Generic PPS @BBL H2C.json" + }, + { + "name": "Generic PPS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PPS @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PPS-CF @BBL H2C", + "sub_path": "filament/Generic PPS-CF @BBL H2C.json" + }, + { + "name": "Generic PPS-CF @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic PVA @BBL A2L", + "sub_path": "filament/Generic PVA @BBL A2L.json" + }, + { + "name": "Generic PVA @BBL A2L 0.2 nozzle", + "sub_path": "filament/Generic PVA @BBL A2L 0.2 nozzle.json" + }, + { + "name": "Generic PVA @BBL H2C", + "sub_path": "filament/Generic PVA @BBL H2C.json" + }, + { + "name": "Generic PVA @BBL H2C 0.2 nozzle", + "sub_path": "filament/Generic PVA @BBL H2C 0.2 nozzle.json" + }, + { + "name": "Generic PVA @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic PVA @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic TPU @BBL A2L", + "sub_path": "filament/Generic TPU @BBL A2L.json" + }, + { + "name": "Generic TPU @BBL H2C", + "sub_path": "filament/Generic TPU @BBL H2C.json" + }, + { + "name": "Generic TPU @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic TPU @BBL H2C 0.4 nozzle.json" + }, + { + "name": "Generic TPU for AMS @BBL A2L", + "sub_path": "filament/Generic TPU for AMS @BBL A2L.json" + }, + { + "name": "Generic TPU for AMS @BBL H2C", + "sub_path": "filament/Generic TPU for AMS @BBL H2C.json" + }, + { + "name": "Generic TPU for AMS @BBL H2C 0.4 nozzle", + "sub_path": "filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json" } ], "machine_list": [ @@ -10022,6 +11486,38 @@ { "name": "Bambu Lab X2D 0.8 nozzle", "sub_path": "machine/Bambu Lab X2D 0.8 nozzle.json" + }, + { + "name": "Bambu Lab A2L 0.4 nozzle", + "sub_path": "machine/Bambu Lab A2L 0.4 nozzle.json" + }, + { + "name": "Bambu Lab A2L 0.2 nozzle", + "sub_path": "machine/Bambu Lab A2L 0.2 nozzle.json" + }, + { + "name": "Bambu Lab A2L 0.6 nozzle", + "sub_path": "machine/Bambu Lab A2L 0.6 nozzle.json" + }, + { + "name": "Bambu Lab A2L 0.8 nozzle", + "sub_path": "machine/Bambu Lab A2L 0.8 nozzle.json" + }, + { + "name": "Bambu Lab H2C 0.4 nozzle", + "sub_path": "machine/Bambu Lab H2C 0.4 nozzle.json" + }, + { + "name": "Bambu Lab H2C 0.2 nozzle", + "sub_path": "machine/Bambu Lab H2C 0.2 nozzle.json" + }, + { + "name": "Bambu Lab H2C 0.6 nozzle", + "sub_path": "machine/Bambu Lab H2C 0.6 nozzle.json" + }, + { + "name": "Bambu Lab H2C 0.8 nozzle", + "sub_path": "machine/Bambu Lab H2C 0.8 nozzle.json" } ] } diff --git a/resources/profiles/BBL/Bambu Lab A2L_cover.png b/resources/profiles/BBL/Bambu Lab A2L_cover.png new file mode 100644 index 0000000000..513fa6fdaa Binary files /dev/null and b/resources/profiles/BBL/Bambu Lab A2L_cover.png differ diff --git a/resources/profiles/BBL/Bambu Lab H2C_cover.png b/resources/profiles/BBL/Bambu Lab H2C_cover.png new file mode 100644 index 0000000000..6dfddf5ef6 Binary files /dev/null and b/resources/profiles/BBL/Bambu Lab H2C_cover.png differ diff --git a/resources/profiles/BBL/bbl-3dp-H2C.stl b/resources/profiles/BBL/bbl-3dp-H2C.stl new file mode 100644 index 0000000000..4588514dd5 Binary files /dev/null and b/resources/profiles/BBL/bbl-3dp-H2C.stl differ diff --git a/resources/profiles/BBL/cli_config.json b/resources/profiles/BBL/cli_config.json index 1fd91d685c..5aa010c355 100644 --- a/resources/profiles/BBL/cli_config.json +++ b/resources/profiles/BBL/cli_config.json @@ -617,6 +617,151 @@ "Bambu Lab H2C 0.8 nozzle" ] } + }, + "Bambu Lab H2C": { + "downward_check": { + "Bambu Lab H2C 0.2 nozzle": [ + "Bambu Lab A1 0.2 nozzle", + "Bambu Lab A1 mini 0.2 nozzle", + "Bambu Lab H2D 0.2 nozzle", + "Bambu Lab H2D Pro 0.2 nozzle", + "Bambu Lab H2S 0.2 nozzle", + "Bambu Lab P1P 0.2 nozzle", + "Bambu Lab P1S 0.2 nozzle", + "Bambu Lab P2S 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1E 0.2 nozzle", + "Bambu Lab X2D 0.2 nozzle", + "Bambu Lab A2L 0.2 nozzle" + ], + "Bambu Lab H2C 0.4 nozzle": [ + "Bambu Lab A1 0.4 nozzle", + "Bambu Lab A1 mini 0.4 nozzle", + "Bambu Lab H2D 0.4 nozzle", + "Bambu Lab H2D Pro 0.4 nozzle", + "Bambu Lab H2S 0.4 nozzle", + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P2S 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle", + "Bambu Lab X2D 0.4 nozzle", + "Bambu Lab A2L 0.4 nozzle" + ], + "Bambu Lab H2C 0.6 nozzle": [ + "Bambu Lab A1 0.6 nozzle", + "Bambu Lab A1 mini 0.6 nozzle", + "Bambu Lab H2D 0.6 nozzle", + "Bambu Lab H2D Pro 0.6 nozzle", + "Bambu Lab H2S 0.6 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P2S 0.6 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1E 0.6 nozzle", + "Bambu Lab X2D 0.6 nozzle", + "Bambu Lab A2L 0.6 nozzle" + ], + "Bambu Lab H2C 0.8 nozzle": [ + "Bambu Lab A1 0.8 nozzle", + "Bambu Lab A1 mini 0.8 nozzle", + "Bambu Lab H2D 0.8 nozzle", + "Bambu Lab H2D Pro 0.8 nozzle", + "Bambu Lab H2S 0.8 nozzle", + "Bambu Lab P1P 0.8 nozzle", + "Bambu Lab P1S 0.8 nozzle", + "Bambu Lab P2S 0.8 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1E 0.8 nozzle", + "Bambu Lab X2D 0.8 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ] + } + }, + "Bambu Lab A2L": { + "machine_limits": { + "cli_safe_acceleration_e": "0,0", + "cli_safe_acceleration_extruding": "0,0", + "cli_safe_acceleration_retracting": "0,0", + "cli_safe_acceleration_travel": "8000,8000", + "cli_safe_acceleration_x": "6000,6000", + "cli_safe_acceleration_y": "6000,6000", + "cli_safe_acceleration_z": "0,0", + "cli_safe_jerk_e": "0,0", + "cli_safe_jerk_x": "0,0", + "cli_safe_jerk_y": "0,0", + "cli_safe_jerk_z": "0,0", + "cli_safe_speed_e": "0,0", + "cli_safe_speed_x": "0,0", + "cli_safe_speed_y": "0,0", + "cli_safe_speed_z": "0,0" + }, + "downward_check": { + "Bambu Lab A2L 0.2 nozzle": [ + "Bambu Lab P1S 0.2 nozzle", + "Bambu Lab P1P 0.2 nozzle", + "Bambu Lab X1 Carbon 0.2 nozzle", + "Bambu Lab X1E 0.2 nozzle", + "Bambu Lab X1 0.2 nozzle", + "Bambu Lab A1 0.2 nozzle", + "Bambu Lab A1 mini 0.2 nozzle", + "Bambu Lab H2D 0.2 nozzle", + "Bambu Lab H2D Pro 0.2 nozzle", + "Bambu Lab H2S 0.2 nozzle", + "Bambu Lab H2C 0.2 nozzle", + "Bambu Lab P2S 0.2 nozzle", + "Bambu Lab X2D 0.2 nozzle" + ], + "Bambu Lab A2L 0.4 nozzle": [ + "Bambu Lab P1S 0.4 nozzle", + "Bambu Lab P1P 0.4 nozzle", + "Bambu Lab X1 Carbon 0.4 nozzle", + "Bambu Lab X1E 0.4 nozzle", + "Bambu Lab X1 0.4 nozzle", + "Bambu Lab A1 0.4 nozzle", + "Bambu Lab A1 mini 0.4 nozzle", + "Bambu Lab H2D 0.4 nozzle", + "Bambu Lab H2D Pro 0.4 nozzle", + "Bambu Lab H2S 0.4 nozzle", + "Bambu Lab H2C 0.4 nozzle", + "Bambu Lab P2S 0.4 nozzle", + "Bambu Lab X2D 0.4 nozzle" + ], + "Bambu Lab A2L 0.6 nozzle": [ + "Bambu Lab P1S 0.6 nozzle", + "Bambu Lab P1P 0.6 nozzle", + "Bambu Lab X1 Carbon 0.6 nozzle", + "Bambu Lab X1E 0.6 nozzle", + "Bambu Lab X1 0.6 nozzle", + "Bambu Lab A1 0.6 nozzle", + "Bambu Lab A1 mini 0.6 nozzle", + "Bambu Lab H2D 0.6 nozzle", + "Bambu Lab H2D Pro 0.6 nozzle", + "Bambu Lab H2S 0.6 nozzle", + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab P2S 0.6 nozzle", + "Bambu Lab X2D 0.6 nozzle" + ], + "Bambu Lab A2L 0.8 nozzle": [ + "Bambu Lab P1S 0.8 nozzle", + "Bambu Lab P1P 0.8 nozzle", + "Bambu Lab X1 Carbon 0.8 nozzle", + "Bambu Lab X1E 0.8 nozzle", + "Bambu Lab X1 0.8 nozzle", + "Bambu Lab A1 0.8 nozzle", + "Bambu Lab A1 mini 0.8 nozzle", + "Bambu Lab H2D 0.8 nozzle", + "Bambu Lab H2D Pro 0.8 nozzle", + "Bambu Lab H2S 0.8 nozzle", + "Bambu Lab H2C 0.8 nozzle", + "Bambu Lab P2S 0.8 nozzle", + "Bambu Lab X2D 0.8 nozzle" + ] + } } } } diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..476af5f5f2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.2 nozzle.json @@ -0,0 +1,210 @@ +{ + "type": "filament", + "name": "Bambu ABS @BBL H2C 0.2 nozzle", + "inherits": "Bambu ABS @base", + "from": "system", + "setting_id": "GFSB00_23", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0124" + ], + "counter_coef_3": [ + "0.0241" + ], + "counter_limit_max": [ + "0.3341" + ], + "counter_limit_min": [ + "0.0241" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "40" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0008" + ], + "hole_coef_3": [ + "0.1319" + ], + "hole_limit_max": [ + "0.1319" + ], + "hole_limit_min": [ + "0.1119" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..d045691a69 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.6 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu ABS @BBL H2C 0.6 nozzle", + "inherits": "Bambu ABS @base", + "from": "system", + "setting_id": "GFSB00_34", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0124" + ], + "counter_coef_3": [ + "0.0241" + ], + "counter_limit_max": [ + "0.3341" + ], + "counter_limit_min": [ + "0.0241" + ], + "fan_max_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0008" + ], + "hole_coef_3": [ + "0.1319" + ], + "hole_limit_max": [ + "0.1319" + ], + "hole_limit_min": [ + "0.1119" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..e06502611f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C 0.8 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu ABS @BBL H2C 0.8 nozzle", + "inherits": "Bambu ABS @base", + "from": "system", + "setting_id": "GFSB00_35", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0124" + ], + "counter_coef_3": [ + "0.0241" + ], + "counter_limit_max": [ + "0.3341" + ], + "counter_limit_min": [ + "0.0241" + ], + "fan_max_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0008" + ], + "hole_coef_3": [ + "0.1319" + ], + "hole_limit_max": [ + "0.1319" + ], + "hole_limit_min": [ + "0.1119" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json new file mode 100644 index 0000000000..dde059f080 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS @BBL H2C.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu ABS @BBL H2C", + "inherits": "Bambu ABS @base", + "from": "system", + "setting_id": "GFSB00_22", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0124" + ], + "counter_coef_3": [ + "0.0241" + ], + "counter_limit_max": [ + "0.3341" + ], + "counter_limit_min": [ + "0.0241" + ], + "fan_max_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "20", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.6" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0008" + ], + "hole_coef_3": [ + "0.1319" + ], + "hole_limit_max": [ + "0.1319" + ], + "hole_limit_min": [ + "0.1119" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..101af4fbd3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu ABS-GF @BBL H2C 0.4 nozzle", + "inherits": "Bambu ABS-GF @base", + "from": "system", + "setting_id": "GFSB50_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json new file mode 100644 index 0000000000..b4aa3eabe8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ABS-GF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu ABS-GF @BBL H2C", + "inherits": "Bambu ABS-GF @base", + "from": "system", + "setting_id": "GFSB50_09", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..0265544a71 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.2 nozzle.json @@ -0,0 +1,201 @@ +{ + "type": "filament", + "name": "Bambu ASA @BBL H2C 0.2 nozzle", + "inherits": "Bambu ASA @base", + "from": "system", + "setting_id": "GFSB01_24", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0094" + ], + "counter_coef_3": [ + "-0.0092" + ], + "counter_limit_max": [ + "0.2258" + ], + "counter_limit_min": [ + "-0.0092" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0013" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1586" + ], + "hole_limit_min": [ + "0.1261" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "85" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..6dd2e76bce --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.6 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu ASA @BBL H2C 0.6 nozzle", + "inherits": "Bambu ASA @base", + "from": "system", + "setting_id": "GFSB01_37", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0094" + ], + "counter_coef_3": [ + "-0.0092" + ], + "counter_limit_max": [ + "0.2258" + ], + "counter_limit_min": [ + "-0.0092" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0013" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1586" + ], + "hole_limit_min": [ + "0.1261" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "85" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..f0597a6b6b --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C 0.8 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu ASA @BBL H2C 0.8 nozzle", + "inherits": "Bambu ASA @base", + "from": "system", + "setting_id": "GFSB01_38", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0094" + ], + "counter_coef_3": [ + "-0.0092" + ], + "counter_limit_max": [ + "0.2258" + ], + "counter_limit_min": [ + "-0.0092" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0013" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1586" + ], + "hole_limit_min": [ + "0.1261" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "85" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json new file mode 100644 index 0000000000..c9a9653a42 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA @BBL H2C.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu ASA @BBL H2C", + "inherits": "Bambu ASA @base", + "from": "system", + "setting_id": "GFSB01_23", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0094" + ], + "counter_coef_3": [ + "-0.0092" + ], + "counter_limit_max": [ + "0.2258" + ], + "counter_limit_min": [ + "-0.0092" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "20", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.6" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0013" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1586" + ], + "hole_limit_min": [ + "0.1261" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "85" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..54d58171c5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu ASA-Aero @BBL H2C 0.4 nozzle", + "inherits": "Bambu ASA-Aero @base", + "from": "system", + "setting_id": "GFSB02_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.52", + "0.52" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "1.5", + "1.5" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "5", + "5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop": [ + "0", + "0" + ], + "filament_z_hop_types": [ + "Normal Lift", + "Normal Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json new file mode 100644 index 0000000000..af6afa3b7b --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu ASA-Aero @BBL H2C", + "inherits": "Bambu ASA-Aero @base", + "from": "system", + "setting_id": "GFSB02_09", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.52", + "0.52" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "1.5", + "1.5" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "5", + "5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop": [ + "0", + "0" + ], + "filament_z_hop_types": [ + "Normal Lift", + "Normal Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA-Aero @base.json b/resources/profiles/BBL/filament/Bambu ASA-Aero @base.json index 2dcf633a26..1a36118d7f 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-Aero @base.json +++ b/resources/profiles/BBL/filament/Bambu ASA-Aero @base.json @@ -42,8 +42,8 @@ "filament_z_hop_types": [ "Normal Lift" ], - "filament_scarf_seam_type": [ - "none" + "filament_dev_drying_cooling_temperature": [ + "70" ], "impact_strength_z": [ "3.4" diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f6b7e6dc8c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu ASA-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu ASA-CF @base", + "from": "system", + "setting_id": "GFSB51_14", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "eng_plate_temp": [ + "90" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.9", + "0.9" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "235", + "235" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "nozzle_temperature_initial_layer": [ + "275", + "275" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "95" + ], + "textured_plate_temp": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json new file mode 100644 index 0000000000..7ae4df95b1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu ASA-CF @BBL H2C", + "inherits": "Bambu ASA-CF @base", + "from": "system", + "setting_id": "GFSB51_15", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.9", + "0.9" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "235", + "235" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "nozzle_temperature_initial_layer": [ + "275", + "275" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "95" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu ASA-CF @base.json b/resources/profiles/BBL/filament/Bambu ASA-CF @base.json index 9c425dba90..69624032bb 100644 --- a/resources/profiles/BBL/filament/Bambu ASA-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu ASA-CF @base.json @@ -32,6 +32,9 @@ "filament_vendor": [ "Bambu Lab" ], + "filament_dev_drying_cooling_temperature": [ + "95" + ], "hot_plate_temp": [ "100" ], diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..4cc1673410 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu PA-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PA-CF @base", + "from": "system", + "setting_id": "GFSN03_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json new file mode 100644 index 0000000000..3182fc7db5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA-CF @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Bambu PA-CF @BBL H2C", + "inherits": "Bambu PA-CF @base", + "from": "system", + "setting_id": "GFSN03_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..55082c4c58 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu PA6-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PA6-CF @base", + "from": "system", + "setting_id": "GFSN05_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "-0.0016" + ], + "counter_coef_3": [ + "0.0031" + ], + "counter_limit_max": [ + "0.0031" + ], + "counter_limit_min": [ + "-0.038" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "235", + "235" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0051" + ], + "hole_coef_3": [ + "0.2194" + ], + "hole_limit_max": [ + "0.2194" + ], + "hole_limit_min": [ + "0.092" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "nozzle_temperature_initial_layer": [ + "275", + "275" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json new file mode 100644 index 0000000000..52ef42a778 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-CF @BBL H2C.json @@ -0,0 +1,199 @@ +{ + "type": "filament", + "name": "Bambu PA6-CF @BBL H2C", + "inherits": "Bambu PA6-CF @base", + "from": "system", + "setting_id": "GFSN05_09", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "-0.0016" + ], + "counter_coef_3": [ + "0.0031" + ], + "counter_limit_max": [ + "0.0031" + ], + "counter_limit_min": [ + "-0.038" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "235", + "235" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0051" + ], + "hole_coef_3": [ + "0.2194" + ], + "hole_limit_max": [ + "0.2194" + ], + "hole_limit_min": [ + "0.092" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "275", + "275" + ], + "nozzle_temperature_initial_layer": [ + "275", + "275" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..0b1d7c52eb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu PA6-GF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PA6-GF @base", + "from": "system", + "setting_id": "GFSN08_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "10.5", + "10.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "225", + "225" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "265", + "265" + ], + "nozzle_temperature_initial_layer": [ + "265", + "265" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json new file mode 100644 index 0000000000..749ace320a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PA6-GF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu PA6-GF @BBL H2C", + "inherits": "Bambu PA6-GF @base", + "from": "system", + "setting_id": "GFSN08_09", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "10.5", + "10.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "225", + "225" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "265", + "265" + ], + "nozzle_temperature_initial_layer": [ + "265", + "265" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..98bada741c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu PAHT-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PAHT-CF @base", + "from": "system", + "setting_id": "GFSN04_06", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.002" + ], + "counter_coef_3": [ + "-0.055" + ], + "counter_limit_max": [ + "-0.005" + ], + "counter_limit_min": [ + "-0.055" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.1686" + ], + "hole_limit_max": [ + "0.19" + ], + "hole_limit_min": [ + "0.1686" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json new file mode 100644 index 0000000000..fea3dea1a3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @BBL H2C.json @@ -0,0 +1,199 @@ +{ + "type": "filament", + "name": "Bambu PAHT-CF @BBL H2C", + "inherits": "Bambu PAHT-CF @base", + "from": "system", + "setting_id": "GFSN04_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.002" + ], + "counter_coef_3": [ + "-0.055" + ], + "counter_limit_max": [ + "-0.005" + ], + "counter_limit_min": [ + "-0.055" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.1686" + ], + "hole_limit_max": [ + "0.19" + ], + "hole_limit_min": [ + "0.1686" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PAHT-CF @base.json b/resources/profiles/BBL/filament/Bambu PAHT-CF @base.json index 54122f3bbf..28b1391f84 100644 --- a/resources/profiles/BBL/filament/Bambu PAHT-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PAHT-CF @base.json @@ -33,6 +33,9 @@ "full_fan_speed_layer": [ "2" ], + "filament_dev_chamber_drying_time": [ + "16" + ], "impact_strength_z": [ "13.3" ], diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..77cc5e92db --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.2 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PC @BBL H2C 0.2 nozzle", + "inherits": "Bambu PC @base", + "from": "system", + "setting_id": "GFSC00_33", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.0081" + ], + "counter_coef_3": [ + "0.0183" + ], + "counter_limit_max": [ + "0.2208" + ], + "counter_limit_min": [ + "0.0183" + ], + "fan_max_speed": [ + "40" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.94", + "0.94" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.0725" + ], + "hole_limit_max": [ + "0.095" + ], + "hole_limit_min": [ + "0.0725" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..6b8f2211d5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.6 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PC @BBL H2C 0.6 nozzle", + "inherits": "Bambu PC @base", + "from": "system", + "setting_id": "GFSC00_40", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.0081" + ], + "counter_coef_3": [ + "0.0183" + ], + "counter_limit_max": [ + "0.2208" + ], + "counter_limit_min": [ + "0.0183" + ], + "fan_max_speed": [ + "40" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.0725" + ], + "hole_limit_max": [ + "0.095" + ], + "hole_limit_min": [ + "0.0725" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..366352bae8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C 0.8 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PC @BBL H2C 0.8 nozzle", + "inherits": "Bambu PC @base", + "from": "system", + "setting_id": "GFSC00_41", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.0081" + ], + "counter_coef_3": [ + "0.0183" + ], + "counter_limit_max": [ + "0.2208" + ], + "counter_limit_min": [ + "0.0183" + ], + "fan_max_speed": [ + "40" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "25", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.0725" + ], + "hole_limit_max": [ + "0.095" + ], + "hole_limit_min": [ + "0.0725" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json new file mode 100644 index 0000000000..12b7201a0f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC @BBL H2C.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PC @BBL H2C", + "inherits": "Bambu PC @base", + "from": "system", + "setting_id": "GFSC00_34", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "0.0081" + ], + "counter_coef_3": [ + "0.0183" + ], + "counter_limit_max": [ + "0.2208" + ], + "counter_limit_min": [ + "0.0183" + ], + "fan_max_speed": [ + "40" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "20", + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retraction_length": [ + "0.4", + "0.6" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "0.0009" + ], + "hole_coef_3": [ + "0.0725" + ], + "hole_limit_max": [ + "0.095" + ], + "hole_limit_min": [ + "0.0725" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..2753dcaf30 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu PC FR @BBL H2C 0.2 nozzle", + "inherits": "Bambu PC FR @base", + "from": "system", + "setting_id": "GFSC01_32", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.94", + "0.94" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..660d134ea6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu PC FR @BBL H2C 0.4 nozzle", + "inherits": "Bambu PC FR @base", + "from": "system", + "setting_id": "GFSC01_31", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json new file mode 100644 index 0000000000..d5ee574f47 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PC FR @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Bambu PC FR @BBL H2C", + "inherits": "Bambu PC FR @base", + "from": "system", + "setting_id": "GFSC01_33", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "90" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..622e10d1a1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PET-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PET-CF @base", + "from": "system", + "setting_id": "GFST01_08", + "instantiation": "true", + "chamber_temperatures": [ + "50" + ], + "counter_coef_2": [ + "-0.0004" + ], + "counter_coef_3": [ + "-0.0156" + ], + "counter_limit_max": [ + "-0.015" + ], + "counter_limit_min": [ + "-0.025" + ], + "eng_plate_temp": [ + "100" + ], + "eng_plate_temp_initial_layer": [ + "100" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "5", + "5" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0003" + ], + "hole_coef_3": [ + "0.1741" + ], + "hole_limit_max": [ + "0.174" + ], + "hole_limit_min": [ + "0.167" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json new file mode 100644 index 0000000000..ed779934d1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PET-CF @BBL H2C.json @@ -0,0 +1,208 @@ +{ + "type": "filament", + "name": "Bambu PET-CF @BBL H2C", + "inherits": "Bambu PET-CF @base", + "from": "system", + "setting_id": "GFST01_09", + "instantiation": "true", + "chamber_temperatures": [ + "50" + ], + "counter_coef_2": [ + "-0.0004" + ], + "counter_coef_3": [ + "-0.0156" + ], + "counter_limit_max": [ + "-0.015" + ], + "counter_limit_min": [ + "-0.025" + ], + "eng_plate_temp": [ + "100" + ], + "eng_plate_temp_initial_layer": [ + "100" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "5", + "5" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0003" + ], + "hole_coef_3": [ + "0.1741" + ], + "hole_limit_max": [ + "0.174" + ], + "hole_limit_min": [ + "0.167" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PET-CF @base.json b/resources/profiles/BBL/filament/Bambu PET-CF @base.json index b982cd1361..ff8b40070f 100644 --- a/resources/profiles/BBL/filament/Bambu PET-CF @base.json +++ b/resources/profiles/BBL/filament/Bambu PET-CF @base.json @@ -45,6 +45,27 @@ "filament_adhesiveness_category": [ "800" ], + "filament_dev_chamber_drying_bed_temperature": [ + "90" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "165" + ], + "filament_dev_drying_cooling_temperature": [ + "150" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "150" + ], "hot_plate_temp": [ "100" ], diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..cf66b0831f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.2 nozzle.json @@ -0,0 +1,74 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL A2L 0.2 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_26", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "255" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "1" + ], + "filament_overhang_4_4_speed": [ + "30" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "override_process_overhang_speed": [ + "1" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..a0868f4ba7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.4 nozzle.json @@ -0,0 +1,74 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL A2L 0.4 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_33", + "instantiation": "true", + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_bridge_speed": [ + "50" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "13" + ], + "filament_overhang_4_4_speed": [ + "20" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "245" + ], + "overhang_fan_speed": [ + "50" + ], + "override_process_overhang_speed": [ + "1" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..a8142340e5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.6 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL A2L 0.6 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_43", + "instantiation": "true", + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "13" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop": [ + "0.2" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "245" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..c7b58973cd --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL A2L 0.8 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL A2L 0.8 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_27", + "instantiation": "true", + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "13" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop": [ + "0.2" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "245" + ], + "nozzle_temperature_initial_layer": [ + "245" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..855946e799 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.2 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL H2C 0.2 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_24", + "instantiation": "true", + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "210", + "210" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "250", + "250" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..65cdb48cd0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL H2C 0.4 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_23", + "instantiation": "true", + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "20" + ], + "filament_change_length": [ + "4" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "18", + "21" + ], + "filament_pre_cooling_temperature_nc": [ + "210", + "210" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "250", + "250" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json new file mode 100644 index 0000000000..a329a80c3b --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL H2C", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_25", + "instantiation": "true", + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "21", + "28" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop": [ + "0.2", + "0.2" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "210", + "210" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "250", + "250" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json new file mode 100644 index 0000000000..ef961d0710 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S 0.6 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Bambu PETG Basic @BBL H2S 0.6 nozzle", + "inherits": "Bambu PETG Basic @base", + "from": "system", + "setting_id": "GFSG00_32", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "21", + "28" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "2", + "2" + ], + "filament_z_hop": [ + "0.2", + "0.2" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2S 0.6 nozzle", + "Bambu Lab H2S 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json index 4220aae426..08523d6ed9 100644 --- a/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json +++ b/resources/profiles/BBL/filament/Bambu PETG Basic @BBL H2S.json @@ -124,9 +124,7 @@ "0 0 0 0 0 0" ], "compatible_printers": [ - "Bambu Lab H2S 0.4 nozzle", - "Bambu Lab H2S 0.6 nozzle", - "Bambu Lab H2S 0.8 nozzle" + "Bambu Lab H2S 0.4 nozzle" ], "filament_start_gcode": [ "; filament start gcode\n" diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..210184c7ee --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.2 nozzle.json @@ -0,0 +1,77 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL A2L 0.2 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_26", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "40" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "1" + ], + "filament_overhang_4_4_speed": [ + "30" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "240" + ], + "overhang_fan_speed": [ + "100" + ], + "override_process_overhang_speed": [ + "1" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..f816e7f742 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.6 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL A2L 0.6 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_49", + "instantiation": "true", + "fan_cooling_layer_time": [ + "15" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "240" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "7" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..eff5d65efc --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L 0.8 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL A2L 0.8 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_27", + "instantiation": "true", + "fan_cooling_layer_time": [ + "15" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "240" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "7" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L.json new file mode 100644 index 0000000000..bf03c0b74e --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL A2L.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL A2L", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_28", + "instantiation": "true", + "fan_cooling_layer_time": [ + "15" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flow_ratio": [ + "0.94" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "240" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "7" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..6e43d2467d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.2 nozzle.json @@ -0,0 +1,216 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL H2C 0.2 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_24", + "instantiation": "true", + "counter_coef_2": [ + "0.0058" + ], + "counter_coef_3": [ + "0.0107" + ], + "counter_limit_max": [ + "0.15" + ], + "counter_limit_min": [ + "0.01" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_min_speed": [ + "20" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0042" + ], + "hole_coef_3": [ + "0.2006" + ], + "hole_limit_max": [ + "0.2" + ], + "hole_limit_min": [ + "0.09" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_speed": [ + "100" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..03f2f3c393 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.6 nozzle.json @@ -0,0 +1,216 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL H2C 0.6 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_33", + "instantiation": "true", + "counter_coef_2": [ + "0.0058" + ], + "counter_coef_3": [ + "0.0107" + ], + "counter_limit_max": [ + "0.15" + ], + "counter_limit_min": [ + "0.01" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_min_speed": [ + "20" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "30", + "35" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "2", + "2" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0042" + ], + "hole_coef_3": [ + "0.2006" + ], + "hole_limit_max": [ + "0.2" + ], + "hole_limit_min": [ + "0.09" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_speed": [ + "100" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..d035ce27b3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C 0.8 nozzle.json @@ -0,0 +1,216 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL H2C 0.8 nozzle", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_34", + "instantiation": "true", + "counter_coef_2": [ + "0.0058" + ], + "counter_coef_3": [ + "0.0107" + ], + "counter_limit_max": [ + "0.15" + ], + "counter_limit_min": [ + "0.01" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_min_speed": [ + "20" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "30", + "35" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "2", + "2" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0042" + ], + "hole_coef_3": [ + "0.2006" + ], + "hole_limit_max": [ + "0.2" + ], + "hole_limit_min": [ + "0.09" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_speed": [ + "100" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json new file mode 100644 index 0000000000..78644d0987 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG HF @BBL H2C.json @@ -0,0 +1,216 @@ +{ + "type": "filament", + "name": "Bambu PETG HF @BBL H2C", + "inherits": "Bambu PETG HF @base", + "from": "system", + "setting_id": "GFSG02_25", + "instantiation": "true", + "counter_coef_2": [ + "0.0058" + ], + "counter_coef_3": [ + "0.0107" + ], + "counter_limit_max": [ + "0.15" + ], + "counter_limit_min": [ + "0.01" + ], + "fan_cooling_layer_time": [ + "20" + ], + "fan_min_speed": [ + "20" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_tower_ironing_area": [ + "8" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "25", + "35" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "2", + "2" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.6" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0042" + ], + "hole_coef_3": [ + "0.2006" + ], + "hole_limit_max": [ + "0.2" + ], + "hole_limit_min": [ + "0.09" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "overhang_fan_speed": [ + "100" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..5fef31f50e --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.2 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL A2L 0.2 nozzle", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_25", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "30" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "1" + ], + "filament_overhang_4_4_speed": [ + "30" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.3" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "override_process_overhang_speed": [ + "1" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..01a5670ad7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.6 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL A2L 0.6 nozzle", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_39", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "20" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.2" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..38e23138e8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L 0.8 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL A2L 0.8 nozzle", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_26", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "20" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "16" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.2" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L.json new file mode 100644 index 0000000000..a0d99401ce --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL A2L.json @@ -0,0 +1,35 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL A2L", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_27", + "instantiation": "true", + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.3" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..f487455df3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.2 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL H2C 0.2 nozzle", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_24", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "250", + "250" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "slow_down_layer_time": [ + "8" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..6223c186b6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL H2C 0.4 nozzle", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_22", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "250", + "250" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "slow_down_layer_time": [ + "8" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json new file mode 100644 index 0000000000..8b297c56a0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG Translucent @BBL H2C.json @@ -0,0 +1,190 @@ +{ + "type": "filament", + "name": "Bambu PETG Translucent @BBL H2C", + "inherits": "Bambu PETG Translucent @base", + "from": "system", + "setting_id": "GFSG01_23", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "250", + "250" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "slow_down_layer_time": [ + "8" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..6b9e61c9de --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.4 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PETG-CF @BBL A2L 0.4 nozzle", + "inherits": "Bambu PETG-CF @base", + "from": "system", + "setting_id": "GFSG50_20", + "instantiation": "true", + "fan_min_speed": [ + "20" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "255" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "9" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "0" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..8c9bd1abc8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L 0.8 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PETG-CF @BBL A2L 0.8 nozzle", + "inherits": "Bambu PETG-CF @base", + "from": "system", + "setting_id": "GFSG50_29", + "instantiation": "true", + "fan_min_speed": [ + "20" + ], + "filament_flush_temp_fast": [ + "255" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "9" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "0" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L.json new file mode 100644 index 0000000000..62edee9abe --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL A2L.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PETG-CF @BBL A2L", + "inherits": "Bambu PETG-CF @base", + "from": "system", + "setting_id": "GFSG50_23", + "instantiation": "true", + "fan_min_speed": [ + "20" + ], + "filament_flush_temp_fast": [ + "255" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "9" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_speed": [ + "50" + ], + "pre_start_fan_time": [ + "0" + ], + "supertack_plate_temp": [ + "65" + ], + "supertack_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..8b9caf8008 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PETG-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PETG-CF @base", + "from": "system", + "setting_id": "GFSG50_19", + "instantiation": "true", + "counter_coef_2": [ + "0.0022" + ], + "counter_coef_3": [ + "-0.0178" + ], + "counter_limit_max": [ + "0.036" + ], + "counter_limit_min": [ + "-0.0178" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "5" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "11.5", + "11.5" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0014" + ], + "hole_coef_3": [ + "0.11" + ], + "hole_limit_max": [ + "0.11" + ], + "hole_limit_min": [ + "0.075" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "overhang_fan_speed": [ + "100" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json new file mode 100644 index 0000000000..3320eda7ec --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PETG-CF @BBL H2C.json @@ -0,0 +1,214 @@ +{ + "type": "filament", + "name": "Bambu PETG-CF @BBL H2C", + "inherits": "Bambu PETG-CF @base", + "from": "system", + "setting_id": "GFSG50_18", + "instantiation": "true", + "counter_coef_2": [ + "0.0022" + ], + "counter_coef_3": [ + "-0.0178" + ], + "counter_limit_max": [ + "0.036" + ], + "counter_limit_min": [ + "-0.0178" + ], + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "5" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "11.5", + "11.5" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0014" + ], + "hole_coef_3": [ + "0.11" + ], + "hole_limit_max": [ + "0.11" + ], + "hole_limit_min": [ + "0.075" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "overhang_fan_speed": [ + "100" + ], + "supertack_plate_temp": [ + "60" + ], + "supertack_plate_temp_initial_layer": [ + "60" + ], + "temperature_vitrification": [ + "55" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..92de474c10 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.6 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Aero @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Aero @base", + "from": "system", + "setting_id": "GFSA11_18", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..b39e87297d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L 0.8 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Aero @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Aero @base", + "from": "system", + "setting_id": "GFSA11_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L.json new file mode 100644 index 0000000000..e9962474ad --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL A2L.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Aero @BBL A2L", + "inherits": "Bambu PLA Aero @base", + "from": "system", + "setting_id": "GFSA11_13", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..580c187b4e --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu PLA Aero @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Aero @base", + "from": "system", + "setting_id": "GFSA11_11", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.6", + "0.6" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "slow_down_layer_time": [ + "8" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json new file mode 100644 index 0000000000..b6072e3359 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Aero @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Bambu PLA Aero @BBL H2C", + "inherits": "Bambu PLA Aero @base", + "from": "system", + "setting_id": "GFSA11_12", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "0" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.6", + "0.6" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "reduce_fan_stop_start_freq": [ + "0" + ], + "slow_down_layer_time": [ + "8" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..c82796d415 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.2 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..f7b52810e6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.4 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_25", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "23" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..880f94a58c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.6 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_50", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..bafc3729fc --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL A2L 0.8 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_51", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..2f1ab7ef04 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.2 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0025" + ], + "counter_coef_3": [ + "0.014" + ], + "counter_limit_max": [ + "0.076" + ], + "counter_limit_min": [ + "0.014" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.12" + ], + "hole_limit_max": [ + "0.12" + ], + "hole_limit_min": [ + "0.05" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..39bc94d00a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.6 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL H2C 0.6 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_31", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0025" + ], + "counter_coef_3": [ + "0.014" + ], + "counter_limit_max": [ + "0.076" + ], + "counter_limit_min": [ + "0.014" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "30", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.12" + ], + "hole_limit_max": [ + "0.12" + ], + "hole_limit_min": [ + "0.05" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..402f3cddd0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C 0.8 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL H2C 0.8 nozzle", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_32", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0025" + ], + "counter_coef_3": [ + "0.014" + ], + "counter_limit_max": [ + "0.076" + ], + "counter_limit_min": [ + "0.014" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "30", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.12" + ], + "hole_limit_max": [ + "0.12" + ], + "hole_limit_min": [ + "0.05" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json new file mode 100644 index 0000000000..1e6c1643eb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Basic @BBL H2C.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Basic @BBL H2C", + "inherits": "Bambu PLA Basic @base", + "from": "system", + "setting_id": "GFSA00_22", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0025" + ], + "counter_coef_3": [ + "0.014" + ], + "counter_limit_max": [ + "0.076" + ], + "counter_limit_min": [ + "0.014" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "25", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.8" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.12" + ], + "hole_limit_max": [ + "0.12" + ], + "hole_limit_min": [ + "0.05" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..4b224de8c0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.2 nozzle.json @@ -0,0 +1,53 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_26", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..4d5e335fef --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.6 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_39", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..db108940ed --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L 0.8 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_40", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L.json new file mode 100644 index 0000000000..7755b48018 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL A2L.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL A2L", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_27", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..a12fc3a6a5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.2 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_25", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f8209c2c99 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json new file mode 100644 index 0000000000..4fadfcf5ba --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Dynamic @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Dynamic @BBL H2C", + "inherits": "Bambu PLA Dynamic @base", + "from": "system", + "setting_id": "GFSA13_24", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..0e8d20c597 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.2 nozzle.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_26", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..76e3315dc2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.6 nozzle.json @@ -0,0 +1,59 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_39", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..971d39bb47 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L 0.8 nozzle.json @@ -0,0 +1,59 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_40", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L.json new file mode 100644 index 0000000000..a29da01908 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL A2L.json @@ -0,0 +1,59 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL A2L", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_27", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..fe15dcefb2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.2 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_25", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..76b79659ed --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json new file mode 100644 index 0000000000..59ec370472 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Galaxy @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Galaxy @BBL H2C", + "inherits": "Bambu PLA Galaxy @base", + "from": "system", + "setting_id": "GFSA15_24", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..decfd9b658 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.4 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Glow @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Glow @base", + "from": "system", + "setting_id": "GFSA12_27", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..c980532cd1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.6 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Glow @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Glow @base", + "from": "system", + "setting_id": "GFSA12_38", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..cedfcdf86c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL A2L 0.8 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu PLA Glow @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Glow @base", + "from": "system", + "setting_id": "GFSA12_39", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..8558adc1ee --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Glow @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Glow @base", + "from": "system", + "setting_id": "GFSA12_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json new file mode 100644 index 0000000000..20c231beff --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Glow @BBL H2C", + "inherits": "Bambu PLA Glow @base", + "from": "system", + "setting_id": "GFSA12_24", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json index 08f24d63d8..4ae6b67df7 100644 --- a/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json +++ b/resources/profiles/BBL/filament/Bambu PLA Glow @BBL X2D 0.2 nozzle.json @@ -20,7 +20,7 @@ "nil" ], "filament_extruder_compatibility": [ - "9" + "8" ], "filament_flush_volumetric_speed": [ "3", diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..be2d2d0309 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.2 nozzle.json @@ -0,0 +1,77 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_21", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..6e4d34f6f6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.4 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_22", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..91d868c8d0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.6 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_39", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..390387cce7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL A2L 0.8 nozzle.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_40", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..bef804d79e --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.2 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_17", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "24.99" + ], + "filament_density": [ + "1.32" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..45a9cba268 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C 0.4 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_15", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.06" + ], + "counter_coef_3": [ + "-0.32" + ], + "counter_limit_min": [ + "-0.4" + ], + "counter_limit_max": [ + "0.05" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "24.99" + ], + "filament_density": [ + "1.32" + ], + "filament_flow_ratio": [ + "1.01", + "1.01" + ], + "filament_max_volumetric_speed": [ + "20", + "30" + ], + "filament_retraction_length": [ + "0.4", + "0.8" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0081" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json new file mode 100644 index 0000000000..5c1d65e758 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Lite @BBL H2C.json @@ -0,0 +1,214 @@ +{ + "type": "filament", + "name": "Bambu PLA Lite @BBL H2C", + "inherits": "Bambu PLA Lite @base", + "from": "system", + "setting_id": "GFSA18_16", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.06" + ], + "counter_coef_3": [ + "-0.32" + ], + "counter_limit_min": [ + "-0.4" + ], + "counter_limit_max": [ + "0.05" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "24.99" + ], + "filament_density": [ + "1.32" + ], + "filament_flow_ratio": [ + "1.01", + "1.01" + ], + "filament_max_volumetric_speed": [ + "20", + "30" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0081" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..594122a3e3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.6 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Marble @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Marble @base", + "from": "system", + "setting_id": "GFSA07_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..4aca94fe0d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L 0.8 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Marble @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Marble @base", + "from": "system", + "setting_id": "GFSA07_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L.json new file mode 100644 index 0000000000..cf3b42820c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL A2L.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Marble @BBL A2L", + "inherits": "Bambu PLA Marble @base", + "from": "system", + "setting_id": "GFSA07_13", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..ef426cb255 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Marble @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Marble @base", + "from": "system", + "setting_id": "GFSA07_11", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json new file mode 100644 index 0000000000..4055a4021e --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Marble @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Marble @BBL H2C", + "inherits": "Bambu PLA Marble @base", + "from": "system", + "setting_id": "GFSA07_12", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..3434f4e252 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.2 nozzle.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..d9f4a5e0c5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.4 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_25", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "24" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..3e4bec2ae7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.6 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_44", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "22" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_retraction_length": [ + "1" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..a68950ebb2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL A2L 0.8 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_45", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "22" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..cf9b4b85ce --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.2 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.0066" + ], + "counter_limit_max": [ + "0.082" + ], + "counter_limit_min": [ + "0.0066" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0026" + ], + "hole_coef_3": [ + "0.1116" + ], + "hole_limit_max": [ + "0.1116" + ], + "hole_limit_min": [ + "0.046" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..b613b0aea6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.6 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL H2C 0.6 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_31", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.0066" + ], + "counter_limit_max": [ + "0.082" + ], + "counter_limit_min": [ + "0.0066" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "30", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0026" + ], + "hole_coef_3": [ + "0.1116" + ], + "hole_limit_max": [ + "0.1116" + ], + "hole_limit_min": [ + "0.046" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..0e60307815 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C 0.8 nozzle.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL H2C 0.8 nozzle", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_32", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.0066" + ], + "counter_limit_max": [ + "0.082" + ], + "counter_limit_min": [ + "0.0066" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "30", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0026" + ], + "hole_coef_3": [ + "0.1116" + ], + "hole_limit_max": [ + "0.1116" + ], + "hole_limit_min": [ + "0.046" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json new file mode 100644 index 0000000000..58464d719b --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Matte @BBL H2C.json @@ -0,0 +1,213 @@ +{ + "type": "filament", + "name": "Bambu PLA Matte @BBL H2C", + "inherits": "Bambu PLA Matte @base", + "from": "system", + "setting_id": "GFSA01_22", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.0066" + ], + "counter_limit_max": [ + "0.082" + ], + "counter_limit_min": [ + "0.0066" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "25", + "40" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.8" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0026" + ], + "hole_coef_3": [ + "0.1116" + ], + "hole_limit_max": [ + "0.1116" + ], + "hole_limit_min": [ + "0.046" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..7362252ecd --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.2 nozzle.json @@ -0,0 +1,65 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_22", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..df84dabb95 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.6 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_37", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..3b3e4459c2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L 0.8 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_38", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L.json new file mode 100644 index 0000000000..9eba89e942 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL A2L.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL A2L", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..5bfe6de92a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.2 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..4ac0996ec9 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json new file mode 100644 index 0000000000..fde942ad58 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Metal @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Metal @BBL H2C", + "inherits": "Bambu PLA Metal @base", + "from": "system", + "setting_id": "GFSA02_21", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..f910eba123 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.2 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_06", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "1.6" + ], + "filament_overhang_4_4_speed": [ + "30" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "25" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..290e941ac8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.6 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_41", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..d642e84cfd --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L 0.8 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_07", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L.json new file mode 100644 index 0000000000..b5ce60acd9 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL A2L.json @@ -0,0 +1,53 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL A2L", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_08", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..2a4b3a6fa4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C 0.2 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "1.6", + "1.6" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json new file mode 100644 index 0000000000..a53085235d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2C.json @@ -0,0 +1,182 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2C", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_10", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle", + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json new file mode 100644 index 0000000000..d3b7f06b97 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.2 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2D 0.2 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_11", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "3", + "3" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "1.6", + "1.6" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "0" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json new file mode 100644 index 0000000000..a26b9ba6b3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D 0.8 nozzle.json @@ -0,0 +1,169 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2D 0.8 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_12", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.6 nozzle", + "Bambu Lab H2D 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json new file mode 100644 index 0000000000..0d9e3429b2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2D.json @@ -0,0 +1,168 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2D", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_13", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json new file mode 100644 index 0000000000..1b87e764ab --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.2 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2DP 0.2 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_14", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "3", + "3" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "1.6", + "1.6" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "0" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json new file mode 100644 index 0000000000..d4148f9f02 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP 0.8 nozzle.json @@ -0,0 +1,169 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2DP 0.8 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_15", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.6 nozzle", + "Bambu Lab H2D Pro 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json new file mode 100644 index 0000000000..f9ecfa7a20 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2DP.json @@ -0,0 +1,168 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2DP", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_16", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json new file mode 100644 index 0000000000..ad2e498940 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S 0.2 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2S 0.2 nozzle", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_17", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "3", + "3" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "1.6", + "1.6" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "0" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2S 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json new file mode 100644 index 0000000000..dccdd17135 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @BBL H2S.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @BBL H2S", + "inherits": "Bambu PLA Pure @base", + "from": "system", + "setting_id": "GFSA19_18", + "instantiation": "true", + "description": "The generic presets are conservatively tuned for compatibility with a wider range of filaments. For higher printing quality and speeds, please use Bambu filaments with Bambu presets.", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "long_retractions_when_ec": [ + "0", + "0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2S 0.4 nozzle", + "Bambu Lab H2S 0.6 nozzle", + "Bambu Lab H2S 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Pure @base.json b/resources/profiles/BBL/filament/Bambu PLA Pure @base.json new file mode 100644 index 0000000000..ae1b796a47 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Pure @base.json @@ -0,0 +1,29 @@ +{ + "type": "filament", + "name": "Bambu PLA Pure @base", + "inherits": "fdm_filament_pla", + "from": "system", + "filament_id": "GFA19", + "instantiation": "false", + "filament_cost": [ + "21.99" + ], + "filament_flow_ratio": [ + "0.98" + ], + "filament_vendor": [ + "Bambu Lab" + ], + "nozzle_temperature_range_high": [ + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "filament_start_gcode": [ + "; filament start gcode\n{if (bed_temperature[current_extruder] >55)||(bed_temperature_initial_layer[current_extruder] >55)}M106 P3 S200\n{elsif(bed_temperature[current_extruder] >50)||(bed_temperature_initial_layer[current_extruder] >50)}M106 P3 S150\n{elsif(bed_temperature[current_extruder] >45)||(bed_temperature_initial_layer[current_extruder] >45)}M106 P3 S50\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..3f6fb8e7b7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.2 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..d2dec88c9f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.4 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_25", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..6124848c0f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.6 nozzle.json @@ -0,0 +1,53 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_33", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..ee0d0c82cf --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL A2L 0.8 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_34", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..3257a921d8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.2 nozzle.json @@ -0,0 +1,207 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_21", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0036" + ], + "counter_coef_3": [ + "-0.0218" + ], + "counter_limit_max": [ + "0.0682" + ], + "counter_limit_min": [ + "-0.0218" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0037" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1261" + ], + "hole_limit_min": [ + "0.0336" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f5903cea1f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C 0.4 nozzle.json @@ -0,0 +1,207 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_22", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0036" + ], + "counter_coef_3": [ + "-0.0218" + ], + "counter_limit_max": [ + "0.0682" + ], + "counter_limit_min": [ + "-0.0218" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0037" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1261" + ], + "hole_limit_min": [ + "0.0336" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json new file mode 100644 index 0000000000..e46f139763 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk @BBL H2C.json @@ -0,0 +1,208 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk @BBL H2C", + "inherits": "Bambu PLA Silk @base", + "from": "system", + "setting_id": "GFSA05_23", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.0036" + ], + "counter_coef_3": [ + "-0.0218" + ], + "counter_limit_max": [ + "0.0682" + ], + "counter_limit_min": [ + "-0.0218" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0037" + ], + "hole_coef_3": [ + "0.1261" + ], + "hole_limit_max": [ + "0.1261" + ], + "hole_limit_min": [ + "0.0336" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..92f6c76bc0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.2 nozzle.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..30f3feec05 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.4 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..4f9eeba4ba --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.6 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_35", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..2b09d71fe9 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL A2L 0.8 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_36", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..558486b5d4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.2 nozzle.json @@ -0,0 +1,189 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..3773cbe45d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C 0.4 nozzle.json @@ -0,0 +1,189 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_18", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "2", + "2" + ], + "filament_ramming_travel_time_nc": [ + "2", + "2" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json new file mode 100644 index 0000000000..d2f8d19124 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Silk+ @BBL H2C.json @@ -0,0 +1,190 @@ +{ + "type": "filament", + "name": "Bambu PLA Silk+ @BBL H2C", + "inherits": "Bambu PLA Silk+ @base", + "from": "system", + "setting_id": "GFSA06_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "2", + "2" + ], + "filament_ramming_travel_time_nc": [ + "2", + "2" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "35" + ], + "supertack_plate_temp_initial_layer": [ + "35" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..8e133e78f2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.6 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PLA Sparkle @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Sparkle @base", + "from": "system", + "setting_id": "GFSA08_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..4b7c37e987 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L 0.8 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PLA Sparkle @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Sparkle @base", + "from": "system", + "setting_id": "GFSA08_25", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L.json new file mode 100644 index 0000000000..e3d2d6b7a1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL A2L.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu PLA Sparkle @BBL A2L", + "inherits": "Bambu PLA Sparkle @base", + "from": "system", + "setting_id": "GFSA08_13", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..7cdd1dd269 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Sparkle @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Sparkle @base", + "from": "system", + "setting_id": "GFSA08_11", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json new file mode 100644 index 0000000000..8be484d1e4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Sparkle @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Sparkle @BBL H2C", + "inherits": "Bambu PLA Sparkle @base", + "from": "system", + "setting_id": "GFSA08_12", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..048ab331a3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L 0.2 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Tough @base", + "from": "system", + "setting_id": "GFSA09_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L.json new file mode 100644 index 0000000000..c223f15301 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL A2L.json @@ -0,0 +1,49 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough @BBL A2L", + "inherits": "Bambu PLA Tough @base", + "from": "system", + "setting_id": "GFSA09_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..bcb81af9f8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.2 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Tough @base", + "from": "system", + "setting_id": "GFSA09_22", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..2f63485604 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C 0.4 nozzle.json @@ -0,0 +1,204 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Tough @base", + "from": "system", + "setting_id": "GFSA09_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.024" + ], + "counter_limit_max": [ + "0.1" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0081" + ], + "hole_coef_3": [ + "0.2041" + ], + "hole_limit_min": [ + "0.08" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json new file mode 100644 index 0000000000..99a43532bd --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough @BBL H2C.json @@ -0,0 +1,205 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough @BBL H2C", + "inherits": "Bambu PLA Tough @base", + "from": "system", + "setting_id": "GFSA09_21", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.024" + ], + "counter_limit_max": [ + "0.1" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0081" + ], + "hole_coef_3": [ + "0.2041" + ], + "hole_limit_min": [ + "0.08" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..1de9892a2a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.2 nozzle.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "70" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "90" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.4 nozzle.json new file mode 100644 index 0000000000..31c694aeb9 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.4 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL A2L 0.4 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "70" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "90" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..8d6f6b9258 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.6 nozzle.json @@ -0,0 +1,50 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_47", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "70" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "90" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..3272f7c892 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL A2L 0.8 nozzle.json @@ -0,0 +1,59 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_48", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "70" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_min_speed": [ + "90" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "245" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..4fdd5b2f3c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_21", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..c33c99a53f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.6 nozzle.json @@ -0,0 +1,192 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL H2C 0.6 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_22", + "instantiation": "true", + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.01" + ], + "counter_limit_max": [ + "0.088" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_3": [ + "0.18" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..903335f325 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C 0.8 nozzle.json @@ -0,0 +1,192 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL H2C 0.8 nozzle", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_23", + "instantiation": "true", + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.01" + ], + "counter_limit_max": [ + "0.088" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_3": [ + "0.18" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json new file mode 100644 index 0000000000..a12d2cd987 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Tough+ @BBL H2C.json @@ -0,0 +1,192 @@ +{ + "type": "filament", + "name": "Bambu PLA Tough+ @BBL H2C", + "inherits": "Bambu PLA Tough+ @base", + "from": "system", + "setting_id": "GFSA10_24", + "instantiation": "true", + "counter_coef_2": [ + "0.003" + ], + "counter_coef_3": [ + "0.01" + ], + "counter_limit_max": [ + "0.088" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "21", + "21" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_3": [ + "0.18" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..d485c9ce20 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.2 nozzle.json @@ -0,0 +1,71 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL A2L 0.2 nozzle", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_18", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "1.6" + ], + "filament_overhang_4_4_speed": [ + "35" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "25" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..0944ef86cf --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.6 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_42", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..452a5fbd73 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L 0.8 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_19", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L.json new file mode 100644 index 0000000000..0f59f4d269 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL A2L.json @@ -0,0 +1,59 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL A2L", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_20", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_retract_before_wipe": [ + "0" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..1bf9f40acc --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C 0.2 nozzle.json @@ -0,0 +1,189 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL H2C 0.2 nozzle", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_30", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json new file mode 100644 index 0000000000..1a4a5607ab --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Translucent @BBL H2C.json @@ -0,0 +1,191 @@ +{ + "type": "filament", + "name": "Bambu PLA Translucent @BBL H2C", + "inherits": "Bambu PLA Translucent @base", + "from": "system", + "setting_id": "GFSA17_29", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_low": [ + "200" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle", + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\nM145 P0 ; set airduct mode to cooling mode\nM142 P1 R35 S40 U0.3 V0.5 ; set chamber autocooling" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..787b2451b6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.6 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Wood @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA Wood @base", + "from": "system", + "setting_id": "GFSA16_28", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..05c3a08907 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L 0.8 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Wood @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA Wood @base", + "from": "system", + "setting_id": "GFSA16_29", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L.json new file mode 100644 index 0000000000..7cef051eef --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL A2L.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu PLA Wood @BBL A2L", + "inherits": "Bambu PLA Wood @base", + "from": "system", + "setting_id": "GFSA16_18", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "21" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..08a53b3639 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu PLA Wood @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA Wood @base", + "from": "system", + "setting_id": "GFSA16_14", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json new file mode 100644 index 0000000000..b776afff56 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA Wood @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu PLA Wood @BBL H2C", + "inherits": "Bambu PLA Wood @base", + "from": "system", + "setting_id": "GFSA16_15", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..b7a7b77290 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.6 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA-CF @BBL A2L 0.6 nozzle", + "inherits": "Bambu PLA-CF @base", + "from": "system", + "setting_id": "GFSA50_25", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..9857537218 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L 0.8 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu PLA-CF @BBL A2L 0.8 nozzle", + "inherits": "Bambu PLA-CF @base", + "from": "system", + "setting_id": "GFSA50_19", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "230" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "18" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L.json new file mode 100644 index 0000000000..92e1c027d4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL A2L.json @@ -0,0 +1,68 @@ +{ + "type": "filament", + "name": "Bambu PLA-CF @BBL A2L", + "inherits": "Bambu PLA-CF @base", + "from": "system", + "setting_id": "GFSA50_20", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_bridge_speed": [ + "50" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "15" + ], + "filament_overhang_4_4_speed": [ + "25" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "overhang_fan_threshold": [ + "25%" + ], + "override_process_overhang_speed": [ + "1" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..46bbb2e021 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,198 @@ +{ + "type": "filament", + "name": "Bambu PLA-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PLA-CF @base", + "from": "system", + "setting_id": "GFSA50_18", + "instantiation": "true", + "counter_coef_2": [ + "0.0003" + ], + "counter_coef_3": [ + "0.0224" + ], + "counter_limit_max": [ + "0.03" + ], + "counter_limit_min": [ + "0.0224" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "15", + "15" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.1173" + ], + "hole_limit_max": [ + "0.1173" + ], + "hole_limit_min": [ + "0.048" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json new file mode 100644 index 0000000000..a347580105 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PLA-CF @BBL H2C.json @@ -0,0 +1,199 @@ +{ + "type": "filament", + "name": "Bambu PLA-CF @BBL H2C", + "inherits": "Bambu PLA-CF @base", + "from": "system", + "setting_id": "GFSA50_17", + "instantiation": "true", + "counter_coef_2": [ + "0.0003" + ], + "counter_coef_3": [ + "0.0224" + ], + "counter_limit_max": [ + "0.03" + ], + "counter_limit_min": [ + "0.0224" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0028" + ], + "hole_coef_3": [ + "0.1173" + ], + "hole_limit_max": [ + "0.1173" + ], + "hole_limit_min": [ + "0.048" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..48da23e4a8 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,201 @@ +{ + "type": "filament", + "name": "Bambu PPA-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PPA-CF @base", + "from": "system", + "setting_id": "GFSN06_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "-0.0036" + ], + "counter_coef_3": [ + "-0.0075" + ], + "counter_limit_max": [ + "-0.0975" + ], + "counter_limit_min": [ + "-0.0075" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0051" + ], + "hole_coef_3": [ + "0.1702" + ], + "hole_limit_max": [ + "0.17" + ], + "hole_limit_min": [ + "0.04" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json new file mode 100644 index 0000000000..fa07fa6f21 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PPA-CF @BBL H2C.json @@ -0,0 +1,202 @@ +{ + "type": "filament", + "name": "Bambu PPA-CF @BBL H2C", + "inherits": "Bambu PPA-CF @base", + "from": "system", + "setting_id": "GFSN06_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "counter_coef_2": [ + "-0.0036" + ], + "counter_coef_3": [ + "-0.0075" + ], + "counter_limit_max": [ + "-0.0975" + ], + "counter_limit_min": [ + "-0.0075" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0051" + ], + "hole_coef_3": [ + "0.1702" + ], + "hole_limit_max": [ + "0.17" + ], + "hole_limit_min": [ + "0.04" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..310768f7bb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,201 @@ +{ + "type": "filament", + "name": "Bambu PPS-CF @BBL H2C 0.4 nozzle", + "inherits": "Bambu PPS-CF @base", + "from": "system", + "setting_id": "GFST02_03", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0003" + ], + "counter_coef_3": [ + "-0.0033" + ], + "counter_limit_max": [ + "0.0036" + ], + "counter_limit_min": [ + "-0.0033" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0033" + ], + "hole_coef_3": [ + "0.1176" + ], + "hole_limit_max": [ + "0.1176" + ], + "hole_limit_min": [ + "0.035" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json new file mode 100644 index 0000000000..90d3ea985f --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PPS-CF @BBL H2C.json @@ -0,0 +1,202 @@ +{ + "type": "filament", + "name": "Bambu PPS-CF @BBL H2C", + "inherits": "Bambu PPS-CF @base", + "from": "system", + "setting_id": "GFST02_04", + "instantiation": "true", + "chamber_temperatures": [ + "65" + ], + "counter_coef_2": [ + "0.0003" + ], + "counter_coef_3": [ + "-0.0033" + ], + "counter_limit_max": [ + "0.0036" + ], + "counter_limit_min": [ + "-0.0033" + ], + "filament_change_length": [ + "4" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "hole_coef_2": [ + "-0.0033" + ], + "hole_coef_3": [ + "0.1176" + ], + "hole_limit_max": [ + "0.1176" + ], + "hole_limit_min": [ + "0.035" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "temperature_vitrification": [ + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL A2L.json b/resources/profiles/BBL/filament/Bambu PVA @BBL A2L.json new file mode 100644 index 0000000000..1738b4cd44 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL A2L.json @@ -0,0 +1,55 @@ +{ + "type": "filament", + "name": "Bambu PVA @BBL A2L", + "inherits": "Bambu PVA @base", + "from": "system", + "setting_id": "GFSS04_23", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "240" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..2de71b03f5 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,177 @@ +{ + "type": "filament", + "name": "Bambu PVA @BBL H2C 0.4 nozzle", + "inherits": "Bambu PVA @base", + "from": "system", + "setting_id": "GFSS04_17", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json new file mode 100644 index 0000000000..dfe286ab95 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu PVA @BBL H2C.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Bambu PVA @BBL H2C", + "inherits": "Bambu PVA @base", + "from": "system", + "setting_id": "GFSS04_18", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..9492cfe2fc --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu Support For PA/PET @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support For PA/PET @base", + "from": "system", + "setting_id": "GFSS03_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json new file mode 100644 index 0000000000..cfe8734400 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu Support For PA/PET @BBL H2C", + "inherits": "Bambu Support For PA/PET @base", + "from": "system", + "setting_id": "GFSS03_09", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PA PET @base.json b/resources/profiles/BBL/filament/Bambu Support For PA PET @base.json index a622bff105..d199cdb0a0 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PA PET @base.json +++ b/resources/profiles/BBL/filament/Bambu Support For PA PET @base.json @@ -24,6 +24,24 @@ "filament_adhesiveness_category": [ "703" ], + "filament_dev_chamber_drying_time": [ + "16" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "75" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ], "nozzle_temperature": [ "280" ], diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..fefb849bb0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.2 nozzle.json @@ -0,0 +1,62 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL A2L 0.2 nozzle", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_23", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_max_volumetric_speed": [ + "0.5" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..33bc2071f4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.6 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL A2L 0.6 nozzle", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_32", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..fb8f803e75 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L 0.8 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL A2L 0.8 nozzle", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_33", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L.json new file mode 100644 index 0000000000..e4435583c1 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL A2L.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL A2L", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_24", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..725eb7afbf --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.2 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL H2C 0.2 nozzle", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_20", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "0.5", + "0.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..7186e97169 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_21", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json new file mode 100644 index 0000000000..a98e4e44c6 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA @BBL H2C", + "inherits": "Bambu Support For PLA @base", + "from": "system", + "setting_id": "GFSS02_22", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_max_speed": [ + "30" + ], + "fan_min_speed": [ + "20" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA @base.json b/resources/profiles/BBL/filament/Bambu Support For PLA @base.json index 10e4983ebf..9bfdef5bf9 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA @base.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA @base.json @@ -24,11 +24,20 @@ "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_adhesiveness_category": [ "702" + ], + "filament_dev_ams_drying_temperature": [ + "60", + "60", + "50", + "50" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "50" + ], + "filament_dev_drying_softening_temperature": [ + "55" ], "slow_down_layer_time": [ "8" diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..84b2f49104 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L 0.2 nozzle.json @@ -0,0 +1,53 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA/PETG @BBL A2L 0.2 nozzle", + "inherits": "Bambu Support For PLA/PETG @base", + "from": "system", + "setting_id": "GFSS05_22", + "instantiation": "true", + "eng_plate_temp": [ + "65" + ], + "eng_plate_temp_initial_layer": [ + "65" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "210" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_max_volumetric_speed": [ + "0.5" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L.json new file mode 100644 index 0000000000..e3d6f909b4 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL A2L.json @@ -0,0 +1,49 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA/PETG @BBL A2L", + "inherits": "Bambu Support For PLA/PETG @base", + "from": "system", + "setting_id": "GFSS05_23", + "instantiation": "true", + "eng_plate_temp": [ + "65" + ], + "eng_plate_temp_initial_layer": [ + "65" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "210" + ], + "filament_long_retractions_when_cut": [ + "1" + ], + "filament_retraction_distances_when_cut": [ + "18" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..89b94f0622 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA/PETG @BBL H2C 0.2 nozzle", + "inherits": "Bambu Support For PLA/PETG @base", + "from": "system", + "setting_id": "GFSS05_19", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "0.5", + "0.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "supertack_plate_temp": [ + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..784fea9e45 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA/PETG @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support For PLA/PETG @base", + "from": "system", + "setting_id": "GFSS05_17", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "supertack_plate_temp": [ + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json new file mode 100644 index 0000000000..1bbef82d84 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Bambu Support For PLA/PETG @BBL H2C", + "inherits": "Bambu Support For PLA/PETG @base", + "from": "system", + "setting_id": "GFSS05_18", + "instantiation": "true", + "eng_plate_temp": [ + "60" + ], + "eng_plate_temp_initial_layer": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "supertack_plate_temp": [ + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @base.json b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @base.json index 0f1b87e83f..38443f5be3 100644 --- a/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @base.json +++ b/resources/profiles/BBL/filament/Bambu Support For PLA-PETG @base.json @@ -27,14 +27,26 @@ "filament_max_volumetric_speed": [ "6" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_vendor": [ "Bambu Lab" ], "filament_adhesiveness_category": [ "705" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_ams_drying_temperature": [ + "60", + "60", + "50", + "50" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "50" + ], + "filament_dev_drying_softening_temperature": [ + "55" ], "hot_plate_temp": [ "60" diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..00c4001de7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu Support G @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support G @base", + "from": "system", + "setting_id": "GFSS01_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json new file mode 100644 index 0000000000..8237c4f297 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support G @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu Support G @BBL H2C", + "inherits": "Bambu Support G @base", + "from": "system", + "setting_id": "GFSS01_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "280", + "280" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support G @base.json b/resources/profiles/BBL/filament/Bambu Support G @base.json index c903f92d07..9cb01972b8 100644 --- a/resources/profiles/BBL/filament/Bambu Support G @base.json +++ b/resources/profiles/BBL/filament/Bambu Support G @base.json @@ -21,11 +21,26 @@ "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_adhesiveness_category": [ "701" + ], + "filament_dev_chamber_drying_time": [ + "16" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "75" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "85" ], "nozzle_temperature": [ "280" diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..74810aaeb7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL A2L 0.2 nozzle.json @@ -0,0 +1,56 @@ +{ + "type": "filament", + "name": "Bambu Support W @BBL A2L 0.2 nozzle", + "inherits": "Bambu Support W @base", + "from": "system", + "setting_id": "GFSS00_20", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "240" + ], + "filament_max_volumetric_speed": [ + "0.5" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL A2L.json b/resources/profiles/BBL/filament/Bambu Support W @BBL A2L.json new file mode 100644 index 0000000000..64e2cbb5d3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL A2L.json @@ -0,0 +1,46 @@ +{ + "type": "filament", + "name": "Bambu Support W @BBL A2L", + "inherits": "Bambu Support W @base", + "from": "system", + "setting_id": "GFSS00_21", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp": [ + "0" + ], + "filament_flush_temp_fast": [ + "220" + ], + "hot_plate_temp": [ + "60" + ], + "hot_plate_temp_initial_layer": [ + "60" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "60" + ], + "textured_plate_temp_initial_layer": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..2a9e1eb28a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu Support W @BBL H2C 0.2 nozzle", + "inherits": "Bambu Support W @base", + "from": "system", + "setting_id": "GFSS00_19", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "0.5", + "0.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..e84c9efefa --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu Support W @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support W @base", + "from": "system", + "setting_id": "GFSS00_17", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json new file mode 100644 index 0000000000..cfd8dcf4b2 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support W @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Bambu Support W @BBL H2C", + "inherits": "Bambu Support W @base", + "from": "system", + "setting_id": "GFSS00_18", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "supertack_plate_temp": [ + "40" + ], + "supertack_plate_temp_initial_layer": [ + "40" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..0466c80f16 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Bambu Support for ABS @BBL H2C 0.4 nozzle", + "inherits": "Bambu Support for ABS @base", + "from": "system", + "setting_id": "GFSS06_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json new file mode 100644 index 0000000000..3760f214ee --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Bambu Support for ABS @BBL H2C", + "inherits": "Bambu Support for ABS @base", + "from": "system", + "setting_id": "GFSS06_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu Support for ABS @base.json b/resources/profiles/BBL/filament/Bambu Support for ABS @base.json index 35e13e67a0..bc8867db2a 100644 --- a/resources/profiles/BBL/filament/Bambu Support for ABS @base.json +++ b/resources/profiles/BBL/filament/Bambu Support for ABS @base.json @@ -27,11 +27,14 @@ "filament_vendor": [ "Bambu Lab" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_adhesiveness_category": [ "706" + ], + "filament_dev_ams_drying_time": [ + "12", + "4", + "12", + "4" ], "nozzle_temperature_range_high": [ "270" diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..160b3cd5b9 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.6 nozzle.json @@ -0,0 +1,77 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @BBL A2L 0.6 nozzle", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "GFSU04_18", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_pre_cooling_temperature": [ + "195" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "20" + ], + "filament_ramming_volumetric_speed": [ + "0.55" + ], + "filament_retraction_length": [ + "1.3" + ], + "filament_support_printable": [ + "2" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1" + ], + "nozzle_temperature": [ + "220" + ], + "nozzle_temperature_initial_layer": [ + "220" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "pre_start_fan_time": [ + "0" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_min_speed": [ + "20" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..bf04a2f638 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL A2L 0.8 nozzle.json @@ -0,0 +1,80 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @BBL A2L 0.8 nozzle", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "GFSU04_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_max_volumetric_speed": [ + "3" + ], + "filament_pre_cooling_temperature": [ + "195" + ], + "filament_printable": [ + "1" + ], + "filament_ramming_travel_time": [ + "20" + ], + "filament_ramming_volumetric_speed": [ + "0.55" + ], + "filament_retraction_length": [ + "1" + ], + "filament_support_printable": [ + "2" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1" + ], + "nozzle_temperature": [ + "215" + ], + "nozzle_temperature_initial_layer": [ + "215" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "pre_start_fan_time": [ + "0" + ], + "retraction_distances_when_ec": [ + "10" + ], + "slow_down_min_speed": [ + "20" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json new file mode 100644 index 0000000000..c9c84d7b30 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2C.json @@ -0,0 +1,199 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @BBL H2C", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "GFSU04_05", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "2.2", + "2.2" + ], + "filament_ramming_volumetric_speed": [ + "0.55", + "0.55" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.55", + "0.55" + ], + "filament_printable": [ + "2" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "185", + "185" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "impact_strength_z": [ + "88.7" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature": [ + "225", + "225" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D 0.4 nozzle.json new file mode 100644 index 0000000000..635ab2556c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D 0.4 nozzle.json @@ -0,0 +1,101 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @BBL H2D 0.4 nozzle", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "GFSU04_17", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "50" + ], + "filament_extruder_variant": [ + "Direct Drive TPU High Flow" + ], + "filament_flow_ratio": [ + "1.1" + ], + "filament_long_retractions_when_cut": [ + "0" + ], + "filament_max_volumetric_speed": [ + "2.5" + ], + "filament_pre_cooling_temperature": [ + "195" + ], + "filament_printable": [ + "2" + ], + "filament_ramming_travel_time": [ + "20" + ], + "filament_ramming_volumetric_speed": [ + "0.55" + ], + "filament_retraction_length": [ + "2.3" + ], + "filament_retraction_speed": [ + "20" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop": [ + "0.6" + ], + "filament_z_hop_types": [ + "Auto Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "slow_down_layer_time": [ + "14" + ], + "slow_down_min_speed": [ + "30" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json index 052db628f2..7a35448013 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2D.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "50" ], "filament_flow_ratio": [ "1", - "1" + "1", + "1.03" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ "2.2", - "2.2" + "2.2", + "4.8" ], "filament_ramming_volumetric_speed": [ + "0.55", "0.55", "0.55" ], @@ -46,62 +53,77 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "2.3" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "40" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "1" ], "filament_z_hop": [ "nil", - "nil" + "nil", + "0.4" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Auto Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "195", "195", "195" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], @@ -109,6 +131,7 @@ "88.7" ], "long_retractions_when_ec": [ + "1", "1", "1" ], @@ -117,17 +140,21 @@ ], "nozzle_temperature": [ "225", - "225" + "225", + "235" ], "nozzle_temperature_initial_layer": [ "225", - "225" + "225", + "235" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP 0.4 nozzle.json new file mode 100644 index 0000000000..ff23d0e23b --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP 0.4 nozzle.json @@ -0,0 +1,101 @@ +{ + "type": "filament", + "name": "Bambu TPU 85A @BBL H2DP 0.4 nozzle", + "inherits": "Bambu TPU 85A @base", + "from": "system", + "setting_id": "GFSU04_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "50" + ], + "filament_extruder_variant": [ + "Direct Drive TPU High Flow" + ], + "filament_flow_ratio": [ + "1.1" + ], + "filament_long_retractions_when_cut": [ + "0" + ], + "filament_max_volumetric_speed": [ + "2.5" + ], + "filament_pre_cooling_temperature": [ + "195" + ], + "filament_printable": [ + "2" + ], + "filament_ramming_travel_time": [ + "20" + ], + "filament_ramming_volumetric_speed": [ + "0.55" + ], + "filament_retraction_length": [ + "2.3" + ], + "filament_retraction_speed": [ + "20" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop": [ + "0.6" + ], + "filament_z_hop_types": [ + "Auto Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1" + ], + "nozzle_temperature": [ + "230" + ], + "nozzle_temperature_initial_layer": [ + "230" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "slow_down_layer_time": [ + "14" + ], + "slow_down_min_speed": [ + "30" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json index b54d117ea2..eda8e4f60e 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 85A @BBL H2DP.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "50" ], "filament_flow_ratio": [ "1", - "1" + "1", + "1.03" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ "2.2", - "2.2" + "2.2", + "4.8" ], "filament_ramming_volumetric_speed": [ + "0.55", "0.55", "0.55" ], @@ -46,62 +53,77 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "2.3" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "40" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "1" ], "filament_z_hop": [ "nil", - "nil" + "nil", + "0.4" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Auto Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "195", "195", "195" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], @@ -109,6 +131,7 @@ "88.7" ], "long_retractions_when_ec": [ + "1", "1", "1" ], @@ -117,17 +140,21 @@ ], "nozzle_temperature": [ "225", - "225" + "225", + "235" ], "nozzle_temperature_initial_layer": [ "225", - "225" + "225", + "235" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..a3097b65c0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.6 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL A2L 0.6 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_28", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_density": [ + "1.22" + ], + "filament_max_volumetric_speed": [ + "4.5" + ], + "filament_overhang_totally_speed": [ + "20" + ], + "filament_retraction_length": [ + "0.8" + ], + "impact_strength_z": [ + "88.7" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "25" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..8d6283b83d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L 0.8 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL A2L 0.8 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_32", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_density": [ + "1.22" + ], + "filament_max_volumetric_speed": [ + "4.5" + ], + "filament_overhang_totally_speed": [ + "25" + ], + "impact_strength_z": [ + "88.7" + ], + "nozzle_temperature": [ + "205" + ], + "nozzle_temperature_initial_layer": [ + "205" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "20" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L.json new file mode 100644 index 0000000000..7e2c12fdca --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL A2L.json @@ -0,0 +1,38 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL A2L", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_12", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_density": [ + "1.22" + ], + "filament_retraction_length": [ + "1" + ], + "impact_strength_z": [ + "88.7" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..621055a250 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C 0.4 nozzle.json @@ -0,0 +1,195 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2C 0.4 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_08", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.7", + "0.7" + ], + "filament_retraction_length": [ + "2", + "2" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "185", + "185" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "impact_strength_z": [ + "88.7" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature": [ + "225", + "225" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "30", + "30" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json new file mode 100644 index 0000000000..d96ebeb009 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2C.json @@ -0,0 +1,196 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2C", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_cost": [ + "41.99" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.7", + "0.7" + ], + "filament_retraction_length": [ + "1", + "1" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "185", + "185" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "impact_strength_z": [ + "88.7" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "nozzle_temperature": [ + "225", + "225" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json new file mode 100644 index 0000000000..2efb672844 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.6 nozzle.json @@ -0,0 +1,205 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2D 0.6 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_24", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "25", + "25", + "30" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "filament_flow_ratio": [ + "1.05", + "1.05", + "1.08" + ], + "filament_flush_temp": [ + "0", + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8", + "5.6" + ], + "filament_pre_cooling_temperature": [ + "195", + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.6", + "0.6", + "1.8" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "10", + "10", + "30" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift", + "Spiral Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1", + "1", + "1" + ], + "nozzle_temperature": [ + "225", + "225", + "220" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225", + "220" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "retraction_distances_when_ec": [ + "0", + "0", + "0" + ], + "slow_down_min_speed": [ + "25", + "25", + "50" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json new file mode 100644 index 0000000000..347b10121c --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D 0.8 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2D 0.8 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_26", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "25", + "25" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "1.05", + "1.05" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8" + ], + "filament_pre_cooling_temperature": [ + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.2", + "0.2" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "25", + "25" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json index 88597c4a67..e51fc63586 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2D.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "30" ], "filament_flow_ratio": [ "1", - "1" + "1", + "1.05" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ "2.8", - "2.8" + "2.8", + "5.6" ], "filament_ramming_volumetric_speed": [ + "0.7", "0.7", "0.7" ], @@ -46,62 +53,77 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "2.8" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "30" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "2" ], "filament_z_hop": [ "nil", - "nil" + "nil", + "0.4" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Slope Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "195", "195", "195" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], @@ -109,6 +131,7 @@ "88.7" ], "long_retractions_when_ec": [ + "1", "1", "1" ], @@ -116,25 +139,27 @@ "250" ], "nozzle_temperature": [ + "225", "225", "225" ], "nozzle_temperature_initial_layer": [ + "225", "225", "225" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], "compatible_printers": [ - "Bambu Lab H2D 0.4 nozzle", - "Bambu Lab H2D 0.6 nozzle", - "Bambu Lab H2D 0.8 nozzle" + "Bambu Lab H2D 0.4 nozzle" ], "filament_start_gcode": [ "; filament start gcode\n" diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json new file mode 100644 index 0000000000..8fee266af3 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.6 nozzle.json @@ -0,0 +1,205 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2DP 0.6 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_25", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10", + "10" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "25", + "25", + "30" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "filament_flow_ratio": [ + "1.05", + "1.05", + "1.08" + ], + "filament_flush_temp": [ + "0", + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8", + "5.6" + ], + "filament_pre_cooling_temperature": [ + "195", + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10", + "10" + ], + "filament_ramming_travel_time": [ + "20", + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.6", + "0.6", + "1.8" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil", + "nil" + ], + "filament_retraction_speed": [ + "10", + "10", + "30" + ], + "filament_wipe": [ + "nil", + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift", + "Spiral Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1", + "1", + "1" + ], + "nozzle_temperature": [ + "225", + "225", + "220" + ], + "nozzle_temperature_initial_layer": [ + "225", + "225", + "220" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "retraction_distances_when_ec": [ + "0", + "0", + "0" + ], + "slow_down_min_speed": [ + "25", + "25", + "50" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.6 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json new file mode 100644 index 0000000000..bc2728217d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP 0.8 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Bambu TPU 90A @BBL H2DP 0.8 nozzle", + "inherits": "Bambu TPU 90A @base", + "from": "system", + "setting_id": "GFSU03_27", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_density": [ + "1.22" + ], + "filament_deretraction_speed": [ + "25", + "25" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flow_ratio": [ + "1.05", + "1.05" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_max_volumetric_speed": [ + "2.8", + "2.8" + ], + "filament_pre_cooling_temperature": [ + "195", + "195" + ], + "filament_pre_cooling_temperature_nc": [ + "0", + "0" + ], + "filament_preheat_temperature_delta": [ + "10", + "10" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "0.7", + "0.7" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "0.2", + "0.2" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "impact_strength_z": [ + "88.7" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "nozzle_temperature_range_high": [ + "250" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "25", + "25" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json index 92cf3350fd..52c6c8e3c8 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 90A @BBL H2DP.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "30" ], "filament_flow_ratio": [ "1", - "1" + "1", + "1.05" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ "2.8", - "2.8" + "2.8", + "5.6" ], "filament_ramming_volumetric_speed": [ + "0.7", "0.7", "0.7" ], @@ -46,62 +53,77 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "2.8" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "30" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "2" ], "filament_z_hop": [ "nil", - "nil" + "nil", + "0.4" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Slope Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "195", "195", "195" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], @@ -109,6 +131,7 @@ "88.7" ], "long_retractions_when_ec": [ + "1", "1", "1" ], @@ -116,25 +139,27 @@ "250" ], "nozzle_temperature": [ + "225", "225", "225" ], "nozzle_temperature_initial_layer": [ + "225", "225", "225" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], "compatible_printers": [ - "Bambu Lab H2D Pro 0.4 nozzle", - "Bambu Lab H2D Pro 0.6 nozzle", - "Bambu Lab H2D Pro 0.8 nozzle" + "Bambu Lab H2D Pro 0.4 nozzle" ], "filament_start_gcode": [ "; filament start gcode\n" diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL A2L.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL A2L.json new file mode 100644 index 0000000000..767dc230ac --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL A2L.json @@ -0,0 +1,28 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A @BBL A2L", + "inherits": "Bambu TPU 95A @base", + "from": "system", + "setting_id": "GFSU01_11", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_max_volumetric_speed": [ + "3.6" + ], + "pre_start_fan_time": [ + "0" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..252bc0a1bb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A @BBL H2C 0.4 nozzle", + "inherits": "Bambu TPU 95A @base", + "from": "system", + "setting_id": "GFSU01_08", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "3.6", + "3.6" + ], + "filament_ramming_volumetric_speed": [ + "0.9", + "0.9" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.9", + "0.9" + ], + "filament_retraction_length": [ + "2", + "2" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json new file mode 100644 index 0000000000..5ba6a6ae92 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A @BBL H2C", + "inherits": "Bambu TPU 95A @base", + "from": "system", + "setting_id": "GFSU01_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "3.6", + "3.6" + ], + "filament_ramming_volumetric_speed": [ + "0.9", + "0.9" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.9", + "0.9" + ], + "filament_retraction_length": [ + "2", + "2" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json index 8926171526..5c2937c6fb 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2D.json @@ -15,30 +15,37 @@ "35" ], "filament_deretraction_speed": [ + "10", "10", "10" ], "filament_flow_ratio": [ + "1", "1", "1" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ + "3.6", "3.6", "3.6" ], "filament_ramming_volumetric_speed": [ + "0.9", "0.9", "0.9" ], @@ -46,82 +53,102 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ + "2", "2", "2" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ + "10", "10", "10" ], "filament_wipe": [ + "nil", "nil", "nil" ], "filament_wipe_distance": [ + "nil", "nil", "nil" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ + "nil", "nil", "nil" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "200", "200", "200" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ + "230", "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", "230", "230" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json index b37861f53d..a347feaa73 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A @BBL H2DP.json @@ -15,30 +15,37 @@ "35" ], "filament_deretraction_speed": [ + "10", "10", "10" ], "filament_flow_ratio": [ + "1", "1", "1" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ + "3.6", "3.6", "3.6" ], "filament_ramming_volumetric_speed": [ + "0.9", "0.9", "0.9" ], @@ -46,82 +53,102 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ + "2", "2", "2" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ + "10", "10", "10" ], "filament_wipe": [ + "nil", "nil", "nil" ], "filament_wipe_distance": [ + "nil", "nil", "nil" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ + "nil", "nil", "nil" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "200", "200", "200" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ + "230", "230", "230" ], "nozzle_temperature_initial_layer": [ + "230", "230", "230" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..27926d79eb --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.6 nozzle.json @@ -0,0 +1,35 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL A2L 0.6 nozzle", + "inherits": "Bambu TPU 95A HF @base", + "from": "system", + "setting_id": "GFSU00_24", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_deretraction_speed": [ + "50" + ], + "filament_retraction_length": [ + "2.5" + ], + "filament_retraction_speed": [ + "100" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..e332366dad --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L 0.8 nozzle.json @@ -0,0 +1,35 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL A2L 0.8 nozzle", + "inherits": "Bambu TPU 95A HF @base", + "from": "system", + "setting_id": "GFSU00_25", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_deretraction_speed": [ + "50" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_retraction_speed": [ + "100" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L.json new file mode 100644 index 0000000000..4a0835012a --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL A2L.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL A2L", + "inherits": "Bambu TPU 95A HF @base", + "from": "system", + "setting_id": "GFSU00_15", + "instantiation": "true", + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_deretraction_speed": [ + "50" + ], + "filament_retraction_length": [ + "1.2" + ], + "filament_retraction_speed": [ + "100" + ], + "nozzle_temperature": [ + "240" + ], + "nozzle_temperature_initial_layer": [ + "240" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_min_speed": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f451928fb0 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL H2C 0.4 nozzle", + "inherits": "Bambu TPU 95A HF @base", + "from": "system", + "setting_id": "GFSU00_13", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_ramming_volumetric_speed": [ + "3.0", + "3.0" + ], + "filament_ramming_volumetric_speed_nc": [ + "3.0", + "3.0" + ], + "filament_retraction_length": [ + "2", + "2" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json new file mode 100644 index 0000000000..347c0fc4d7 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL H2C", + "inherits": "Bambu TPU 95A HF @base", + "from": "system", + "setting_id": "GFSU00_14", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_deretraction_speed": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_ramming_volumetric_speed": [ + "3.0", + "3.0" + ], + "filament_ramming_volumetric_speed_nc": [ + "3.0", + "3.0" + ], + "filament_retraction_length": [ + "2", + "2" + ], + "filament_retraction_speed": [ + "10", + "10" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.4 nozzle.json new file mode 100644 index 0000000000..b061a22065 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D 0.4 nozzle.json @@ -0,0 +1,46 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL H2D 0.4 nozzle", + "inherits": "Bambu TPU 95A HF @BBL H2D", + "from": "system", + "setting_id": "GFSU00_20", + "instantiation": "true", + "filament_deretraction_speed": [ + "10", + "10", + "50" + ], + "filament_retraction_length": [ + "2", + "2", + "0.8" + ], + "filament_retraction_speed": [ + "10", + "10", + "50" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "Slope Lift" + ], + "nozzle_temperature": [ + "230", + "230", + "240" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230", + "240" + ], + "slow_down_min_speed": [ + "10", + "10", + "40" + ], + "compatible_printers": [ + "Bambu Lab H2D 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json index c13d24d024..57f8ff236f 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2D.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "40" ], "filament_flow_ratio": [ "1", - "1" + "1", + "0.99" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ "12", - "12" + "12", + "16" ], "filament_ramming_volumetric_speed": [ + "3.0", "3.0", "3.0" ], @@ -46,87 +53,106 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "0.4" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "40" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "1" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Spiral Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "200", "200", "200" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ "230", - "230" + "230", + "235" ], "nozzle_temperature_initial_layer": [ "230", - "230" + "230", + "235" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], "compatible_printers": [ - "Bambu Lab H2D 0.4 nozzle", "Bambu Lab H2D 0.6 nozzle", "Bambu Lab H2D 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json new file mode 100644 index 0000000000..c99895e092 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP 0.4 nozzle.json @@ -0,0 +1,51 @@ +{ + "type": "filament", + "name": "Bambu TPU 95A HF @BBL H2DP 0.4 nozzle", + "inherits": "Bambu TPU 95A HF @BBL H2DP", + "from": "system", + "setting_id": "GFSU00_21", + "instantiation": "true", + "filament_deretraction_speed": [ + "10", + "10", + "50" + ], + "filament_max_volumetric_speed": [ + "12", + "12", + "16" + ], + "filament_retraction_length": [ + "2", + "2", + "0.8" + ], + "filament_retraction_speed": [ + "10", + "10", + "50" + ], + "filament_z_hop_types": [ + "nil", + "nil", + "Slope Lift" + ], + "nozzle_temperature": [ + "230", + "230", + "240" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230", + "240" + ], + "slow_down_min_speed": [ + "10", + "10", + "40" + ], + "compatible_printers": [ + "Bambu Lab H2D Pro 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json index 10f6e414a0..181e7f9931 100644 --- a/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Bambu TPU 95A HF @BBL H2DP.json @@ -16,29 +16,36 @@ ], "filament_deretraction_speed": [ "10", - "10" + "10", + "40" ], "filament_flow_ratio": [ "1", - "1" + "1", + "0.99" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ + "12", "12", "12" ], "filament_ramming_volumetric_speed": [ + "3.0", "3.0", "3.0" ], @@ -46,87 +53,106 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ "2", - "2" + "2", + "0.4" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ "10", - "10" + "10", + "40" ], "filament_wipe": [ "nil", - "nil" + "nil", + "1" ], "filament_wipe_distance": [ "nil", - "nil" + "nil", + "1" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ "nil", - "nil" + "nil", + "Spiral Lift" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "200", "200", "200" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ "230", - "230" + "230", + "235" ], "nozzle_temperature_initial_layer": [ "230", - "230" + "230", + "235" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], "compatible_printers": [ - "Bambu Lab H2D Pro 0.4 nozzle", "Bambu Lab H2D Pro 0.6 nozzle", "Bambu Lab H2D Pro 0.8 nozzle" ], diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..f4d92511dd --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.6 nozzle.json @@ -0,0 +1,38 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @BBL A2L 0.6 nozzle", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "GFSU02_21", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "30" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_retraction_length": [ + "0.6" + ], + "filament_retraction_speed": [ + "90" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "19" + ], + "slow_down_min_speed": [ + "30" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..02a3c85695 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L 0.8 nozzle.json @@ -0,0 +1,38 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @BBL A2L 0.8 nozzle", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "GFSU02_22", + "instantiation": "true", + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "30" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_retraction_length": [ + "0.6" + ], + "filament_retraction_speed": [ + "90" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "16" + ], + "slow_down_min_speed": [ + "30" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L.json new file mode 100644 index 0000000000..3338821e07 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL A2L.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @BBL A2L", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "GFSU02_12", + "instantiation": "true", + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "50" + ], + "filament_deretraction_speed": [ + "nil" + ], + "filament_retraction_length": [ + "0.4" + ], + "filament_retraction_speed": [ + "nil" + ], + "filament_wipe": [ + "1" + ], + "filament_wipe_distance": [ + "1" + ], + "filament_z_hop_types": [ + "Spiral Lift" + ], + "pre_start_fan_time": [ + "0" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "35" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..68b634336d --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,186 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @BBL H2C 0.4 nozzle", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "GFSU02_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "fan_max_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_ramming_volumetric_speed": [ + "4.5", + "4.5" + ], + "filament_ramming_volumetric_speed_nc": [ + "4.5", + "4.5" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json new file mode 100644 index 0000000000..2eca7e2354 --- /dev/null +++ b/resources/profiles/BBL/filament/Bambu TPU for AMS @BBL H2C.json @@ -0,0 +1,187 @@ +{ + "type": "filament", + "name": "Bambu TPU for AMS @BBL H2C", + "inherits": "Bambu TPU for AMS @base", + "from": "system", + "setting_id": "GFSU02_10", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "fan_max_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_ramming_volumetric_speed": [ + "4.5", + "4.5" + ], + "filament_ramming_volumetric_speed_nc": [ + "4.5", + "4.5" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..921bd56b9f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic ABS @BBL H2C 0.2 nozzle", + "inherits": "Generic ABS @base", + "from": "system", + "setting_id": "GFSB99_18", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "60" + ], + "fan_min_speed": [ + "40" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..1fd81f53d5 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic ABS @BBL H2C 0.4 nozzle", + "inherits": "Generic ABS @base", + "from": "system", + "setting_id": "GFSB99_16", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "15", + "15" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json b/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json new file mode 100644 index 0000000000..e14004572f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ABS @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic ABS @BBL H2C", + "inherits": "Generic ABS @base", + "from": "system", + "setting_id": "GFSB99_17", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "15", + "15" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "230", + "230" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "270", + "270" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..777de9e63b --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.2 nozzle.json @@ -0,0 +1,177 @@ +{ + "type": "filament", + "name": "Generic ASA @BBL H2C 0.2 nozzle", + "inherits": "Generic ASA @base", + "from": "system", + "setting_id": "GFSB98_16", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "220", + "220" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "overhang_fan_speed": [ + "100" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..0fbf7075a8 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic ASA @BBL H2C 0.4 nozzle", + "inherits": "Generic ASA @base", + "from": "system", + "setting_id": "GFSB98_17", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "220", + "220" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json b/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json new file mode 100644 index 0000000000..c454519dcb --- /dev/null +++ b/resources/profiles/BBL/filament/Generic ASA @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic ASA @BBL H2C", + "inherits": "Generic ASA @base", + "from": "system", + "setting_id": "GFSB98_18", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "220", + "220" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL A2L.json b/resources/profiles/BBL/filament/Generic BVOH @BBL A2L.json new file mode 100644 index 0000000000..2e2d66ea50 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL A2L.json @@ -0,0 +1,19 @@ +{ + "type": "filament", + "name": "Generic BVOH @BBL A2L", + "inherits": "Generic BVOH @base", + "from": "system", + "setting_id": "GFSS97_10", + "instantiation": "true", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..bb5ed16dbe --- /dev/null +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C 0.4 nozzle.json @@ -0,0 +1,177 @@ +{ + "type": "filament", + "name": "Generic BVOH @BBL H2C 0.4 nozzle", + "inherits": "Generic BVOH @base", + "from": "system", + "setting_id": "GFSS97_08", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json new file mode 100644 index 0000000000..6bdf0d5c99 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic BVOH @BBL H2C.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic BVOH @BBL H2C", + "inherits": "Generic BVOH @base", + "from": "system", + "setting_id": "GFSS97_09", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL A2L.json b/resources/profiles/BBL/filament/Generic EVA @BBL A2L.json new file mode 100644 index 0000000000..7f8afc4732 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic EVA @BBL A2L.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Generic EVA @BBL A2L", + "inherits": "Generic EVA @base", + "from": "system", + "setting_id": "GFSR99_11", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..d20e6c6608 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic EVA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic EVA @BBL H2C 0.4 nozzle", + "inherits": "Generic EVA @base", + "from": "system", + "setting_id": "GFSR99_08", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json b/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json new file mode 100644 index 0000000000..5c32ec697a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic EVA @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic EVA @BBL H2C", + "inherits": "Generic EVA @base", + "from": "system", + "setting_id": "GFSR99_09", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..88c952b8d6 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL A2L 0.2 nozzle.json @@ -0,0 +1,41 @@ +{ + "type": "filament", + "name": "Generic HIPS @BBL A2L 0.2 nozzle", + "inherits": "Generic HIPS @base", + "from": "system", + "setting_id": "GFSS98_18", + "instantiation": "true", + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "filament_max_volumetric_speed": [ + "0.5" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL A2L.json b/resources/profiles/BBL/filament/Generic HIPS @BBL A2L.json new file mode 100644 index 0000000000..9af02ee93a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL A2L.json @@ -0,0 +1,37 @@ +{ + "type": "filament", + "name": "Generic HIPS @BBL A2L", + "inherits": "Generic HIPS @base", + "from": "system", + "setting_id": "GFSS98_19", + "instantiation": "true", + "eng_plate_temp": [ + "70" + ], + "eng_plate_temp_initial_layer": [ + "70" + ], + "hot_plate_temp": [ + "70" + ], + "hot_plate_temp_initial_layer": [ + "70" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "70" + ], + "textured_plate_temp_initial_layer": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..06ce0cbc13 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.2 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic HIPS @BBL H2C 0.2 nozzle", + "inherits": "Generic HIPS @base", + "from": "system", + "setting_id": "GFSS98_17", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "0.5", + "0.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..da9c295fc8 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic HIPS @BBL H2C 0.4 nozzle", + "inherits": "Generic HIPS @base", + "from": "system", + "setting_id": "GFSS98_15", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json new file mode 100644 index 0000000000..71ab193857 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic HIPS @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic HIPS @BBL H2C", + "inherits": "Generic HIPS @base", + "from": "system", + "setting_id": "GFSS98_16", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "200", + "200" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "240", + "240" + ], + "nozzle_temperature_initial_layer": [ + "240", + "240" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "75" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..eeb46a95ff --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic PA @BBL H2C 0.4 nozzle", + "inherits": "Generic PA @base", + "from": "system", + "setting_id": "GFSN99_06", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "220", + "220" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "temperature_vitrification": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PA @BBL H2C.json new file mode 100644 index 0000000000..65615430e6 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PA @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic PA @BBL H2C", + "inherits": "Generic PA @base", + "from": "system", + "setting_id": "GFSN99_07", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "220", + "220" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "260", + "260" + ], + "nozzle_temperature_initial_layer": [ + "260", + "260" + ], + "retraction_distances_when_ec": [ + "4", + "4" + ], + "temperature_vitrification": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PA @base.json b/resources/profiles/BBL/filament/Generic PA @base.json index 5947f5a859..fe819487b0 100644 --- a/resources/profiles/BBL/filament/Generic PA @base.json +++ b/resources/profiles/BBL/filament/Generic PA @base.json @@ -21,6 +21,21 @@ "filament_max_volumetric_speed": [ "12" ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "65" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ], "nozzle_temperature": [ "260" ], diff --git a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..830430cea4 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PA-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PA-CF", + "from": "system", + "setting_id": "GFSN98_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "130" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json new file mode 100644 index 0000000000..aa932ea447 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PA-CF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PA-CF @BBL H2C", + "inherits": "Generic PA-CF", + "from": "system", + "setting_id": "GFSN98_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "130" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..a3aad0310b --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.2 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PC @BBL H2C 0.2 nozzle", + "inherits": "Generic PC @base", + "from": "system", + "setting_id": "GFSC99_20", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.94", + "0.94" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..96341294ac --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PC @BBL H2C 0.4 nozzle", + "inherits": "Generic PC @base", + "from": "system", + "setting_id": "GFSC99_21", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PC @BBL H2C.json b/resources/profiles/BBL/filament/Generic PC @BBL H2C.json new file mode 100644 index 0000000000..df406fff54 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PC @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PC @BBL H2C", + "inherits": "Generic PC @base", + "from": "system", + "setting_id": "GFSC99_22", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "240", + "240" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "280", + "280" + ], + "nozzle_temperature_initial_layer": [ + "270", + "270" + ], + "slow_down_layer_time": [ + "12" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL A2L.json b/resources/profiles/BBL/filament/Generic PCTG @BBL A2L.json new file mode 100644 index 0000000000..4908632fd1 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL A2L.json @@ -0,0 +1,19 @@ +{ + "type": "filament", + "name": "Generic PCTG @BBL A2L", + "inherits": "Generic PCTG @base", + "from": "system", + "setting_id": "GFSG97_10", + "instantiation": "true", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..8c4b384ba1 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic PCTG @BBL H2C 0.4 nozzle", + "inherits": "Generic PCTG @base", + "from": "system", + "setting_id": "GFSG97_08", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json new file mode 100644 index 0000000000..1111bf79dd --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PCTG @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic PCTG @BBL H2C", + "inherits": "Generic PCTG @base", + "from": "system", + "setting_id": "GFSG97_09", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PCTG @base.json b/resources/profiles/BBL/filament/Generic PCTG @base.json index d0ec60848f..e8b7c1ce0a 100644 --- a/resources/profiles/BBL/filament/Generic PCTG @base.json +++ b/resources/profiles/BBL/filament/Generic PCTG @base.json @@ -38,6 +38,34 @@ "filament_max_volumetric_speed": [ "6" ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "75" + ], + "filament_dev_drying_cooling_temperature": [ + "55" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "65", + "55", + "55" + ], + "filament_dev_drying_softening_temperature": [ + "60" + ], "hot_plate_temp": [ "70" ], diff --git a/resources/profiles/BBL/filament/Generic PE @BBL A2L.json b/resources/profiles/BBL/filament/Generic PE @BBL A2L.json new file mode 100644 index 0000000000..010887c67a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE @BBL A2L.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Generic PE @BBL A2L", + "inherits": "Generic PE @base", + "from": "system", + "setting_id": "GFSP99_10", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..2fdd6dfb3b --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PE @BBL H2C 0.4 nozzle", + "inherits": "Generic PE @base", + "from": "system", + "setting_id": "GFSP99_08", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PE @BBL H2C.json b/resources/profiles/BBL/filament/Generic PE @BBL H2C.json new file mode 100644 index 0000000000..84601671d0 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic PE @BBL H2C", + "inherits": "Generic PE @base", + "from": "system", + "setting_id": "GFSP99_09", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "8", + "8" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL A2L.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL A2L.json new file mode 100644 index 0000000000..49e57d939f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL A2L.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Generic PE-CF @BBL A2L", + "inherits": "Generic PE-CF @base", + "from": "system", + "setting_id": "GFSP98_10", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..5e444e7926 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,177 @@ +{ + "type": "filament", + "name": "Generic PE-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PE-CF @base", + "from": "system", + "setting_id": "GFSP98_08", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json new file mode 100644 index 0000000000..47ec6b69cf --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PE-CF @BBL H2C.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PE-CF @BBL H2C", + "inherits": "Generic PE-CF @base", + "from": "system", + "setting_id": "GFSP98_09", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "170", + "170" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "210", + "210" + ], + "nozzle_temperature_initial_layer": [ + "210", + "210" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..bfce104d88 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @BBL A2L 0.2 nozzle.json @@ -0,0 +1,26 @@ +{ + "type": "filament", + "name": "Generic PETG @BBL A2L 0.2 nozzle", + "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "GFSG99_21", + "instantiation": "true", + "filament_flush_temp_fast": [ + "255" + ], + "filament_max_volumetric_speed": [ + "1" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL A2L.json b/resources/profiles/BBL/filament/Generic PETG @BBL A2L.json new file mode 100644 index 0000000000..62f2c876b5 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @BBL A2L.json @@ -0,0 +1,25 @@ +{ + "type": "filament", + "name": "Generic PETG @BBL A2L", + "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "GFSG99_22", + "instantiation": "true", + "filament_flush_temp_fast": [ + "255" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..e252904409 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.2 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PETG @BBL H2C 0.2 nozzle", + "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "GFSG99_20", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..2d726beb14 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PETG @BBL H2C 0.4 nozzle", + "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "GFSG99_18", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json new file mode 100644 index 0000000000..e853d20f76 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PETG @BBL H2C", + "inherits": "Generic PETG @base", + "from": "system", + "setting_id": "GFSG99_19", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..2599094d1e --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L 0.2 nozzle.json @@ -0,0 +1,23 @@ +{ + "type": "filament", + "name": "Generic PETG HF @BBL A2L 0.2 nozzle", + "inherits": "Generic PETG HF @base", + "from": "system", + "setting_id": "GFSG96_20", + "instantiation": "true", + "filament_flush_temp_fast": [ + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L.json new file mode 100644 index 0000000000..6c1582d465 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL A2L.json @@ -0,0 +1,25 @@ +{ + "type": "filament", + "name": "Generic PETG HF @BBL A2L", + "inherits": "Generic PETG HF @base", + "from": "system", + "setting_id": "GFSG96_21", + "instantiation": "true", + "filament_flush_temp_fast": [ + "220" + ], + "filament_retraction_length": [ + "0.4" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..d4b72d6747 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.2 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PETG HF @BBL H2C 0.2 nozzle", + "inherits": "Generic PETG HF @base", + "from": "system", + "setting_id": "GFSG96_19", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "205", + "205" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "245", + "245" + ], + "nozzle_temperature_initial_layer": [ + "245", + "245" + ], + "pre_start_fan_time": [ + "2" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..450f208606 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PETG HF @BBL H2C 0.4 nozzle", + "inherits": "Generic PETG HF @base", + "from": "system", + "setting_id": "GFSG96_17", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json new file mode 100644 index 0000000000..e603865aff --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG HF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PETG HF @BBL H2C", + "inherits": "Generic PETG HF @base", + "from": "system", + "setting_id": "GFSG96_18", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.97", + "0.97" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL A2L.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL A2L.json new file mode 100644 index 0000000000..3936c4b090 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL A2L.json @@ -0,0 +1,25 @@ +{ + "type": "filament", + "name": "Generic PETG-CF @BBL A2L", + "inherits": "Generic PETG-CF @base", + "from": "system", + "setting_id": "GFSG98_11", + "instantiation": "true", + "filament_flush_temp_fast": [ + "255" + ], + "filament_max_volumetric_speed": [ + "8" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..50e41672f4 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Generic PETG-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PETG-CF @base", + "from": "system", + "setting_id": "GFSG98_08", + "instantiation": "true", + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "5" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "11.5", + "11.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "overhang_fan_speed": [ + "100" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json new file mode 100644 index 0000000000..26119cd309 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PETG-CF @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Generic PETG-CF @BBL H2C", + "inherits": "Generic PETG-CF @base", + "from": "system", + "setting_id": "GFSG98_09", + "instantiation": "true", + "fan_cooling_layer_time": [ + "30" + ], + "fan_max_speed": [ + "40" + ], + "fan_min_speed": [ + "5" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "11.5", + "11.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "215", + "215" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "255", + "255" + ], + "nozzle_temperature_initial_layer": [ + "255", + "255" + ], + "overhang_fan_speed": [ + "100" + ], + "temperature_vitrification": [ + "60" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL A2L.json b/resources/profiles/BBL/filament/Generic PHA @BBL A2L.json new file mode 100644 index 0000000000..6fa1b48bde --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PHA @BBL A2L.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Generic PHA @BBL A2L", + "inherits": "Generic PHA @base", + "from": "system", + "setting_id": "GFSR98_10", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle", + "Bambu Lab A2L 0.4 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f2217f38f2 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PHA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PHA @BBL H2C 0.4 nozzle", + "inherits": "Generic PHA @base", + "from": "system", + "setting_id": "GFSR98_08", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "45" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json new file mode 100644 index 0000000000..ba9d4b46ce --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PHA @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic PHA @BBL H2C", + "inherits": "Generic PHA @base", + "from": "system", + "setting_id": "GFSR98_09", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "45" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..f5207ee1d0 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @BBL A2L 0.2 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "filament", + "name": "Generic PLA @BBL A2L 0.2 nozzle", + "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "GFSL99_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "1.6" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL A2L.json b/resources/profiles/BBL/filament/Generic PLA @BBL A2L.json new file mode 100644 index 0000000000..d5c951a78f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @BBL A2L.json @@ -0,0 +1,40 @@ +{ + "type": "filament", + "name": "Generic PLA @BBL A2L", + "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "GFSL99_24", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..02dd3a5f48 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic PLA @BBL H2C 0.2 nozzle", + "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "GFSL99_22", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "1.6", + "1.6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..468699489e --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic PLA @BBL H2C 0.4 nozzle", + "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "GFSL99_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json new file mode 100644 index 0000000000..5e0433e39a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Generic PLA @BBL H2C", + "inherits": "Generic PLA @base", + "from": "system", + "setting_id": "GFSL99_21", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..a10f03de18 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L 0.2 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL A2L 0.2 nozzle", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_22", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "2" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "slow_down_min_speed": [ + "40" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L.json new file mode 100644 index 0000000000..d3bf1ac5b8 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL A2L", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_23", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "6" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..5a8a52641a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.2 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL H2C 0.2 nozzle", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_21", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.98", + "0.98" + ], + "filament_max_volumetric_speed": [ + "2", + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..e3114fb4a5 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL H2C 0.4 nozzle", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_19", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json new file mode 100644 index 0000000000..bdb8905b0d --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA High Speed @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Generic PLA High Speed @BBL H2C", + "inherits": "Generic PLA High Speed @base", + "from": "system", + "setting_id": "GFSL95_20", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "18", + "18" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "4" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL A2L.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL A2L.json new file mode 100644 index 0000000000..e8db9edc9a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL A2L.json @@ -0,0 +1,46 @@ +{ + "type": "filament", + "name": "Generic PLA Silk @BBL A2L", + "inherits": "Generic PLA Silk @base", + "from": "system", + "setting_id": "GFSL96_10", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "filament_max_volumetric_speed": [ + "7.5" + ], + "filament_retraction_length": [ + "0.5" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..730b5e0f02 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic PLA Silk @BBL H2C 0.4 nozzle", + "inherits": "Generic PLA Silk @base", + "from": "system", + "setting_id": "GFSL96_08", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "7.5", + "7.5" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json new file mode 100644 index 0000000000..1d75400976 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA Silk @BBL H2C.json @@ -0,0 +1,181 @@ +{ + "type": "filament", + "name": "Generic PLA Silk @BBL H2C", + "inherits": "Generic PLA Silk @base", + "from": "system", + "setting_id": "GFSL96_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "75" + ], + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.99", + "0.99" + ], + "filament_max_volumetric_speed": [ + "7.5", + "7.5" + ], + "filament_retraction_length": [ + "0.4", + "0.4" + ], + "filament_wipe": [ + "1", + "1" + ], + "filament_wipe_distance": [ + "1", + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_z_hop_types": [ + "Spiral Lift", + "Spiral Lift" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL A2L.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL A2L.json new file mode 100644 index 0000000000..9a94369480 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "filament", + "name": "Generic PLA-CF @BBL A2L", + "inherits": "Generic PLA-CF @base", + "from": "system", + "setting_id": "GFSL98_11", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_flush_temp_fast": [ + "220" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..98e1f99a5b --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PLA-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PLA-CF @base", + "from": "system", + "setting_id": "GFSL98_08", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json new file mode 100644 index 0000000000..29befe21c2 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PLA-CF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PLA-CF @BBL H2C", + "inherits": "Generic PLA-CF @base", + "from": "system", + "setting_id": "GFSL98_09", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_retract_length_nc": [ + "18", + "18" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP @BBL A2L.json b/resources/profiles/BBL/filament/Generic PP @BBL A2L.json new file mode 100644 index 0000000000..e8ea2d9f54 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP @BBL A2L.json @@ -0,0 +1,20 @@ +{ + "type": "filament", + "name": "Generic PP @BBL A2L", + "inherits": "Generic PP @base", + "from": "system", + "setting_id": "GFSP97_11", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "pre_start_fan_time": [ + "2" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f82945ba5d --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PP @BBL H2C 0.4 nozzle", + "inherits": "Generic PP @base", + "from": "system", + "setting_id": "GFSP97_09", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP @BBL H2C.json new file mode 100644 index 0000000000..7904a38119 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic PP @BBL H2C", + "inherits": "Generic PP @base", + "from": "system", + "setting_id": "GFSP97_10", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "12", + "12" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..31dba2afa7 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PP-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PP-CF @base", + "from": "system", + "setting_id": "GFSP96_07", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json new file mode 100644 index 0000000000..1a34b1491c --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP-CF @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic PP-CF @BBL H2C", + "inherits": "Generic PP-CF @base", + "from": "system", + "setting_id": "GFSP96_08", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..2c96691c1e --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,178 @@ +{ + "type": "filament", + "name": "Generic PP-GF @BBL H2C 0.4 nozzle", + "inherits": "Generic PP-GF @base", + "from": "system", + "setting_id": "GFSP95_06", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json new file mode 100644 index 0000000000..1622a69a3d --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PP-GF @BBL H2C.json @@ -0,0 +1,179 @@ +{ + "type": "filament", + "name": "Generic PP-GF @BBL H2C", + "inherits": "Generic PP-GF @base", + "from": "system", + "setting_id": "GFSP95_07", + "instantiation": "true", + "description": "This is neither a commonly used filament, nor one of Bambu filaments, and it varies a lot from brand to brand. So, it's highly recommended to ask its vendor for suitable profile before printing and adjust some parameters according to its performances.", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "195", + "195" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "235", + "235" + ], + "nozzle_temperature_initial_layer": [ + "235", + "235" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "50" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..f5a311d686 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,180 @@ +{ + "type": "filament", + "name": "Generic PPA-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PPA-CF @base", + "from": "system", + "setting_id": "GFSN97_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6.5", + "6.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json new file mode 100644 index 0000000000..70355a7fd4 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPA-CF @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Generic PPA-CF @BBL H2C", + "inherits": "Generic PPA-CF @base", + "from": "system", + "setting_id": "GFSN97_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "fan_max_speed": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6.5", + "6.5" + ], + "filament_printable": [ + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "overhang_fan_threshold": [ + "25%" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "70" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..1b85c2abc9 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PPA-GF @BBL H2C 0.4 nozzle", + "inherits": "Generic PPA-GF @base", + "from": "system", + "setting_id": "GFSN96_07", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "100" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json new file mode 100644 index 0000000000..f9d47164c5 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPA-GF @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PPA-GF @BBL H2C", + "inherits": "Generic PPA-GF @base", + "from": "system", + "setting_id": "GFSN96_08", + "instantiation": "true", + "chamber_temperatures": [ + "60" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "6", + "6" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "250", + "250" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "290", + "290" + ], + "nozzle_temperature_initial_layer": [ + "290", + "290" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "temperature_vitrification": [ + "100" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..145ea2ecd6 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,171 @@ +{ + "type": "filament", + "name": "Generic PPS @BBL H2C 0.4 nozzle", + "inherits": "Generic PPS @base", + "from": "system", + "setting_id": "GFST97_03", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "4", + "4" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "temperature_vitrification": [ + "80" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json new file mode 100644 index 0000000000..5f90d205f1 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPS @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic PPS @BBL H2C", + "inherits": "Generic PPS @base", + "from": "system", + "setting_id": "GFST97_04", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "4", + "4" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "temperature_vitrification": [ + "80" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPS @base.json b/resources/profiles/BBL/filament/Generic PPS @base.json index e8da776dfc..882fea94e0 100644 --- a/resources/profiles/BBL/filament/Generic PPS @base.json +++ b/resources/profiles/BBL/filament/Generic PPS @base.json @@ -4,5 +4,26 @@ "inherits": "fdm_filament_pps", "from": "system", "filament_id": "GFT97", - "instantiation": "false" + "instantiation": "false", + "filament_dev_chamber_drying_bed_temperature": [ + "90" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "80" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ] } diff --git a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..379b9fb35b --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C 0.4 nozzle.json @@ -0,0 +1,168 @@ +{ + "type": "filament", + "name": "Generic PPS-CF @BBL H2C 0.4 nozzle", + "inherits": "Generic PPS-CF @base", + "from": "system", + "setting_id": "GFST98_03", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "3", + "3" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json new file mode 100644 index 0000000000..3d2bf461d6 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PPS-CF @BBL H2C.json @@ -0,0 +1,172 @@ +{ + "type": "filament", + "name": "Generic PPS-CF @BBL H2C", + "inherits": "Generic PPS-CF @base", + "from": "system", + "setting_id": "GFST98_04", + "instantiation": "true", + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "0.96", + "0.96" + ], + "filament_max_volumetric_speed": [ + "3", + "3" + ], + "filament_printable": [ + "1" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "280", + "280" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "slow_down_min_speed": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "320", + "320" + ], + "nozzle_temperature_initial_layer": [ + "320", + "320" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PVA @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..66a2cd7851 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PVA @BBL A2L 0.2 nozzle.json @@ -0,0 +1,47 @@ +{ + "type": "filament", + "name": "Generic PVA @BBL A2L 0.2 nozzle", + "inherits": "Generic PVA @base", + "from": "system", + "setting_id": "GFSS99_19", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "filament_max_volumetric_speed": [ + "0.5" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "slow_down_min_speed": [ + "40" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL A2L.json b/resources/profiles/BBL/filament/Generic PVA @BBL A2L.json new file mode 100644 index 0000000000..59cbcc89e4 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PVA @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "filament", + "name": "Generic PVA @BBL A2L", + "inherits": "Generic PVA @base", + "from": "system", + "setting_id": "GFSS99_20", + "instantiation": "true", + "fan_cooling_layer_time": [ + "80" + ], + "fan_max_speed": [ + "80" + ], + "fan_min_speed": [ + "60" + ], + "hot_plate_temp": [ + "65" + ], + "hot_plate_temp_initial_layer": [ + "65" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "8" + ], + "textured_plate_temp": [ + "65" + ], + "textured_plate_temp_initial_layer": [ + "65" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..914e544994 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.2 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PVA @BBL H2C 0.2 nozzle", + "inherits": "Generic PVA @base", + "from": "system", + "setting_id": "GFSS99_16", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "0.5", + "0.5" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..b8e2d6bb77 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C 0.4 nozzle.json @@ -0,0 +1,174 @@ +{ + "type": "filament", + "name": "Generic PVA @BBL H2C 0.4 nozzle", + "inherits": "Generic PVA @base", + "from": "system", + "setting_id": "GFSS99_17", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json b/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json new file mode 100644 index 0000000000..3d4ad8d48f --- /dev/null +++ b/resources/profiles/BBL/filament/Generic PVA @BBL H2C.json @@ -0,0 +1,175 @@ +{ + "type": "filament", + "name": "Generic PVA @BBL H2C", + "inherits": "Generic PVA @base", + "from": "system", + "setting_id": "GFSS99_18", + "instantiation": "true", + "eng_plate_temp": [ + "55" + ], + "eng_plate_temp_initial_layer": [ + "55" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_max_volumetric_speed": [ + "16", + "16" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature_nc": [ + "180", + "180" + ], + "filament_ramming_travel_time": [ + "0", + "0" + ], + "filament_ramming_travel_time_nc": [ + "1", + "1" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_flow_ratio": [ + "0.95", + "0.95" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_pre_cooling_temperature": [ + "0", + "0" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_ramming_volumetric_speed": [ + "-1", + "-1" + ], + "filament_ramming_volumetric_speed_nc": [ + "-1", + "-1" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "220", + "220" + ], + "nozzle_temperature_initial_layer": [ + "220", + "220" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL A2L.json b/resources/profiles/BBL/filament/Generic TPU @BBL A2L.json new file mode 100644 index 0000000000..2942151d52 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU @BBL A2L.json @@ -0,0 +1,31 @@ +{ + "type": "filament", + "name": "Generic TPU @BBL A2L", + "inherits": "Generic TPU", + "from": "system", + "setting_id": "GFSU99_10", + "instantiation": "true", + "hot_plate_temp": [ + "30" + ], + "hot_plate_temp_initial_layer": [ + "30" + ], + "pre_start_fan_time": [ + "2" + ], + "textured_plate_temp": [ + "30" + ], + "textured_plate_temp_initial_layer": [ + "30" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..a977e63e1a --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C 0.4 nozzle.json @@ -0,0 +1,183 @@ +{ + "type": "filament", + "name": "Generic TPU @BBL H2C 0.4 nozzle", + "inherits": "Generic TPU @base", + "from": "system", + "setting_id": "GFSU99_08", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "3.2", + "3.2" + ], + "filament_ramming_volumetric_speed": [ + "0.8", + "0.8" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.8", + "0.8" + ], + "filament_printable": [ + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "210", + "210" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json new file mode 100644 index 0000000000..d7ad1a41ab --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2C.json @@ -0,0 +1,184 @@ +{ + "type": "filament", + "name": "Generic TPU @BBL H2C", + "inherits": "Generic TPU @base", + "from": "system", + "setting_id": "GFSU99_09", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "3.2", + "3.2" + ], + "filament_ramming_volumetric_speed": [ + "0.8", + "0.8" + ], + "filament_ramming_volumetric_speed_nc": [ + "0.8", + "0.8" + ], + "filament_printable": [ + "2" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "210", + "210" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_retract_length_nc": [ + "10", + "10" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "pre_start_fan_time": [ + "2" + ], + "retraction_distances_when_ec": [ + "0", + "0" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json index fae7b49f19..12844a54e6 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2D.json @@ -15,30 +15,37 @@ "35" ], "filament_deretraction_speed": [ + "nil", "nil", "nil" ], "filament_flow_ratio": [ + "1", "1", "1" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ + "3.2", "3.2", "3.2" ], "filament_ramming_volumetric_speed": [ + "0.8", "0.8", "0.8" ], @@ -46,82 +53,102 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ + "nil", "nil", "nil" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ + "nil", "nil", "nil" ], "filament_wipe": [ + "nil", "nil", "nil" ], "filament_wipe_distance": [ + "nil", "nil", "nil" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ + "nil", "nil", "nil" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "210", "210", "210" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ + "240", "240", "240" ], "nozzle_temperature_initial_layer": [ + "240", "240", "240" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json index 2bbc90696b..d5801a1b6a 100644 --- a/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json +++ b/resources/profiles/BBL/filament/Generic TPU @BBL H2DP.json @@ -15,30 +15,37 @@ "35" ], "filament_deretraction_speed": [ + "nil", "nil", "nil" ], "filament_flow_ratio": [ + "1", "1", "1" ], "filament_flush_temp": [ + "0", "0", "0" ], "filament_flush_volumetric_speed": [ + "0", "0", "0" ], "filament_long_retractions_when_cut": [ + "nil", "nil", "nil" ], "filament_max_volumetric_speed": [ + "3.2", "3.2", "3.2" ], "filament_ramming_volumetric_speed": [ + "0.8", "0.8", "0.8" ], @@ -46,82 +53,102 @@ "2" ], "filament_retract_before_wipe": [ + "nil", "nil", "nil" ], "filament_retract_restart_extra": [ + "nil", "nil", "nil" ], "filament_retract_when_changing_layer": [ + "nil", "nil", "nil" ], "filament_retraction_distances_when_cut": [ + "nil", "nil", "nil" ], "filament_retraction_length": [ + "nil", "nil", "nil" ], "filament_retraction_minimum_travel": [ + "nil", "nil", "nil" ], "filament_retraction_speed": [ + "nil", "nil", "nil" ], "filament_wipe": [ + "nil", "nil", "nil" ], "filament_wipe_distance": [ + "nil", "nil", "nil" ], "filament_z_hop": [ + "nil", "nil", "nil" ], "filament_z_hop_types": [ + "nil", "nil", "nil" ], "filament_extruder_variant": [ "Direct Drive Standard", - "Direct Drive High Flow" + "Direct Drive High Flow", + "Direct Drive TPU High Flow" ], "filament_pre_cooling_temperature": [ + "210", "210", "210" ], "filament_ramming_travel_time": [ + "20", "20", "20" ], "filament_adaptive_volumetric_speed": [ + "0", "0", "0" ], "long_retractions_when_ec": [ + "1", "1", "1" ], "nozzle_temperature": [ + "240", "240", "240" ], "nozzle_temperature_initial_layer": [ + "240", "240", "240" ], "retraction_distances_when_ec": [ + "0", "0", "0" ], "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", "0 0 0 0 0 0", "0 0 0 0 0 0" ], diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL A2L.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL A2L.json new file mode 100644 index 0000000000..7c76a301d8 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL A2L.json @@ -0,0 +1,34 @@ +{ + "type": "filament", + "name": "Generic TPU for AMS @BBL A2L", + "inherits": "Generic TPU for AMS @base", + "from": "system", + "setting_id": "GFSU98_12", + "instantiation": "true", + "fan_cooling_layer_time": [ + "40" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "10" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle", + "Bambu Lab A2L 0.6 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ], + "filament_start_gcode": [ + "" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json new file mode 100644 index 0000000000..b2ba07c308 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C 0.4 nozzle.json @@ -0,0 +1,195 @@ +{ + "type": "filament", + "name": "Generic TPU for AMS @BBL H2C 0.4 nozzle", + "inherits": "Generic TPU for AMS @base", + "from": "system", + "setting_id": "GFSU98_10", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "fan_cooling_layer_time": [ + "40" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "10" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "10.5", + "10.5" + ], + "filament_ramming_volumetric_speed": [ + "2.63", + "2.63" + ], + "filament_ramming_volumetric_speed_nc": [ + "2.63", + "2.63" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json new file mode 100644 index 0000000000..b60988cad2 --- /dev/null +++ b/resources/profiles/BBL/filament/Generic TPU for AMS @BBL H2C.json @@ -0,0 +1,196 @@ +{ + "type": "filament", + "name": "Generic TPU for AMS @BBL H2C", + "inherits": "Generic TPU for AMS @base", + "from": "system", + "setting_id": "GFSU98_11", + "instantiation": "true", + "additional_cooling_fan_speed": [ + "100" + ], + "eng_plate_temp": [ + "35" + ], + "eng_plate_temp_initial_layer": [ + "35" + ], + "fan_cooling_layer_time": [ + "40" + ], + "fan_max_speed": [ + "50" + ], + "fan_min_speed": [ + "10" + ], + "filament_cooling_before_tower": [ + "10", + "10" + ], + "filament_flow_ratio": [ + "1", + "1" + ], + "filament_max_volumetric_speed": [ + "10.5", + "10.5" + ], + "filament_ramming_volumetric_speed": [ + "2.63", + "2.63" + ], + "filament_ramming_volumetric_speed_nc": [ + "2.63", + "2.63" + ], + "filament_prime_volume": [ + "30" + ], + "filament_prime_volume_nc": [ + "30" + ], + "filament_pre_cooling_temperature": [ + "200", + "200" + ], + "filament_pre_cooling_temperature_nc": [ + "190", + "190" + ], + "filament_ramming_travel_time": [ + "20", + "20" + ], + "filament_ramming_travel_time_nc": [ + "20", + "20" + ], + "filament_change_length": [ + "4" + ], + "first_x_layer_fan_speed": [ + "0" + ], + "filament_change_length_nc": [ + "4" + ], + "filament_preheat_temperature_delta": [ + "20", + "20" + ], + "filament_adaptive_volumetric_speed": [ + "0", + "0" + ], + "filament_deretraction_speed": [ + "nil", + "nil" + ], + "filament_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "filament_flush_temp": [ + "0", + "0" + ], + "filament_flush_volumetric_speed": [ + "0", + "0" + ], + "filament_long_retractions_when_cut": [ + "nil", + "nil" + ], + "filament_retract_length_nc": [ + "14", + "14" + ], + "filament_retract_before_wipe": [ + "nil", + "nil" + ], + "filament_retract_restart_extra": [ + "nil", + "nil" + ], + "filament_retract_when_changing_layer": [ + "nil", + "nil" + ], + "filament_retraction_distances_when_cut": [ + "nil", + "nil" + ], + "filament_retraction_length": [ + "nil", + "nil" + ], + "filament_retraction_minimum_travel": [ + "nil", + "nil" + ], + "filament_retraction_speed": [ + "nil", + "nil" + ], + "filament_wipe": [ + "nil", + "nil" + ], + "filament_wipe_distance": [ + "nil", + "nil" + ], + "filament_z_hop": [ + "nil", + "nil" + ], + "filament_z_hop_types": [ + "nil", + "nil" + ], + "long_retractions_when_ec": [ + "1", + "1" + ], + "retraction_distances_when_ec": [ + "10", + "10" + ], + "volumetric_speed_coefficients": [ + "0 0 0 0 0 0", + "0 0 0 0 0 0" + ], + "nozzle_temperature": [ + "230", + "230" + ], + "nozzle_temperature_initial_layer": [ + "230", + "230" + ], + "overhang_fan_threshold": [ + "25%" + ], + "pre_start_fan_time": [ + "2" + ], + "slow_down_layer_time": [ + "10" + ], + "slow_down_min_speed": [ + "20", + "20" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle", + "Bambu Lab H2C 0.8 nozzle" + ], + "filament_start_gcode": [ + "; filament start gcode\n" + ], + "filament_end_gcode": [ + "; filament end gcode \n" + ] +} diff --git a/resources/profiles/BBL/filament/Polymaker/Fiberon PET-CF @base.json b/resources/profiles/BBL/filament/Polymaker/Fiberon PET-CF @base.json index 921ce55dd6..365ebb2fd7 100644 --- a/resources/profiles/BBL/filament/Polymaker/Fiberon PET-CF @base.json +++ b/resources/profiles/BBL/filament/Polymaker/Fiberon PET-CF @base.json @@ -41,6 +41,30 @@ "filament_vendor": [ "Polymaker" ], + "filament_adhesiveness_category": [ + "800" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "90" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "165" + ], + "filament_dev_drying_cooling_temperature": [ + "150" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "150" + ], "hot_plate_temp": [ "70" ], @@ -83,9 +107,6 @@ "textured_plate_temp_initial_layer": [ "70" ], - "filament_adhesiveness_category": [ - "800" - ], "filament_start_gcode": [ "; filament start gcode\n{if (bed_temperature[current_extruder] >80)||(bed_temperature_initial_layer[current_extruder] >80)}M106 P3 S255\n{elsif (bed_temperature[current_extruder] >60)||(bed_temperature_initial_layer[current_extruder] >60)}M106 P3 S180\n{endif}\n\n{if activate_air_filtration[current_extruder] && support_air_filtration}\nM106 P3 S{during_print_exhaust_fan_speed_num[current_extruder]} \n{endif}" ] diff --git a/resources/profiles/BBL/filament/fdm_filament_abs.json b/resources/profiles/BBL/filament/fdm_filament_abs.json index d05b005db9..4eb47ce0bd 100644 --- a/resources/profiles/BBL/filament/fdm_filament_abs.json +++ b/resources/profiles/BBL/filament/fdm_filament_abs.json @@ -43,6 +43,27 @@ "filament_adhesiveness_category": [ "200" ], + "filament_dev_ams_drying_time": [ + "12", + "8.0", + "12", + "8.0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "75" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "75" + ], + "filament_dev_drying_softening_temperature": [ + "80" + ], "hot_plate_temp": [ "90" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_asa.json b/resources/profiles/BBL/filament/fdm_filament_asa.json index de053b5e14..b5ae3ad8b5 100644 --- a/resources/profiles/BBL/filament/fdm_filament_asa.json +++ b/resources/profiles/BBL/filament/fdm_filament_asa.json @@ -43,6 +43,27 @@ "filament_adhesiveness_category": [ "200" ], + "filament_dev_ams_drying_time": [ + "12", + "8.0", + "12", + "8.0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "100" + ], + "filament_dev_drying_cooling_temperature": [ + "85" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "85" + ], "hot_plate_temp": [ "90" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_bvoh.json b/resources/profiles/BBL/filament/fdm_filament_bvoh.json index 1a766a5a71..ee15cc5e30 100644 --- a/resources/profiles/BBL/filament/fdm_filament_bvoh.json +++ b/resources/profiles/BBL/filament/fdm_filament_bvoh.json @@ -43,6 +43,34 @@ "filament_type": [ "BVOH" ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "65" + ], + "filament_dev_drying_cooling_temperature": [ + "40" + ], + "filament_dev_ams_drying_temperature": [ + "60", + "60", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" + ], "hot_plate_temp": [ "55" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_eva.json b/resources/profiles/BBL/filament/fdm_filament_eva.json index 283606c21e..a3f9ab0011 100644 --- a/resources/profiles/BBL/filament/fdm_filament_eva.json +++ b/resources/profiles/BBL/filament/fdm_filament_eva.json @@ -7,6 +7,34 @@ "filament_type": [ "EVA" ], + "filament_dev_chamber_drying_bed_temperature": [ + "70" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "45" + ], + "filament_dev_drying_cooling_temperature": [ + "40" + ], + "filament_dev_ams_drying_temperature": [ + "45", + "45", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" + ], "supertack_plate_temp": [ "0" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_hips.json b/resources/profiles/BBL/filament/fdm_filament_hips.json index 25c0acbb6f..7016a866f6 100644 --- a/resources/profiles/BBL/filament/fdm_filament_hips.json +++ b/resources/profiles/BBL/filament/fdm_filament_hips.json @@ -4,9 +4,6 @@ "inherits": "fdm_filament_common", "from": "system", "instantiation": "false", - "additional_cooling_fan_speed": [ - "0" - ], "cool_plate_temp": [ "0" ], @@ -42,6 +39,27 @@ ], "filament_adhesiveness_category": [ "798" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "90" + ], + "filament_dev_drying_cooling_temperature": [ + "75" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "75" + ], + "filament_dev_drying_softening_temperature": [ + "80" ], "hot_plate_temp": [ "90" diff --git a/resources/profiles/BBL/filament/fdm_filament_pa.json b/resources/profiles/BBL/filament/fdm_filament_pa.json index 629ef70885..61aeed66ce 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pa.json +++ b/resources/profiles/BBL/filament/fdm_filament_pa.json @@ -43,6 +43,30 @@ "filament_adhesiveness_category": [ "400" ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_chamber_drying_time": [ + "18" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "165" + ], + "filament_dev_drying_cooling_temperature": [ + "150" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "85", + "65", + "85" + ], + "filament_dev_drying_softening_temperature": [ + "150" + ], "hot_plate_temp": [ "100" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pc.json b/resources/profiles/BBL/filament/fdm_filament_pc.json index 11dcf5ea46..a73a56b440 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pc.json +++ b/resources/profiles/BBL/filament/fdm_filament_pc.json @@ -40,6 +40,27 @@ "filament_adhesiveness_category": [ "500" ], + "filament_dev_ams_drying_time": [ + "12", + "8.0", + "12", + "8.0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "105" + ], + "filament_dev_drying_cooling_temperature": [ + "90" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "80", + "65", + "80" + ], + "filament_dev_drying_softening_temperature": [ + "90" + ], "hot_plate_temp": [ "110" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pctg.json b/resources/profiles/BBL/filament/fdm_filament_pctg.json index f735c26f48..01810a2ddc 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pctg.json +++ b/resources/profiles/BBL/filament/fdm_filament_pctg.json @@ -28,6 +28,37 @@ "filament_type": [ "PCTG" ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_chamber_drying_time": [ + "12" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "75" + ], + "filament_dev_drying_cooling_temperature": [ + "55" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "65", + "55", + "55" + ], + "filament_dev_drying_softening_temperature": [ + "60" + ], "hot_plate_temp": [ "80" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pe.json b/resources/profiles/BBL/filament/fdm_filament_pe.json index 51549b2d8d..9235c3301e 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pe.json +++ b/resources/profiles/BBL/filament/fdm_filament_pe.json @@ -40,6 +40,31 @@ "filament_type": [ "PE" ], + "filament_dev_chamber_drying_bed_temperature": [ + "70" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_drying_cooling_temperature": [ + "50" + ], + "filament_dev_ams_drying_temperature": [ + "45", + "45", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" + ], "hot_plate_temp": [ "55" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pet.json b/resources/profiles/BBL/filament/fdm_filament_pet.json index 8fde5f2faa..23a8f73fe4 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pet.json +++ b/resources/profiles/BBL/filament/fdm_filament_pet.json @@ -31,6 +31,34 @@ "filament_adhesiveness_category": [ "300" ], + "filament_dev_chamber_drying_bed_temperature": [ + "80" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "75" + ], + "filament_dev_drying_cooling_temperature": [ + "55" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "65", + "55", + "55" + ], + "filament_dev_drying_softening_temperature": [ + "60" + ], "hot_plate_temp": [ "80" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pha.json b/resources/profiles/BBL/filament/fdm_filament_pha.json index b9ac18587d..2bd348e2de 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pha.json +++ b/resources/profiles/BBL/filament/fdm_filament_pha.json @@ -40,6 +40,31 @@ "filament_type": [ "PHA" ], + "filament_dev_chamber_drying_bed_temperature": [ + "70" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_drying_cooling_temperature": [ + "45" + ], + "filament_dev_ams_drying_temperature": [ + "45", + "45", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" + ], "hot_plate_temp": [ "55" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pla.json b/resources/profiles/BBL/filament/fdm_filament_pla.json index 3c6713b86d..f1e1c9a244 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pla.json +++ b/resources/profiles/BBL/filament/fdm_filament_pla.json @@ -37,14 +37,39 @@ "filament_max_volumetric_speed": [ "12" ], - "filament_scarf_seam_type": [ - "none" - ], "filament_scarf_gap": [ "15%" ], "filament_adhesiveness_category": [ "100" + ], + "filament_dev_chamber_drying_bed_temperature": [ + "70" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "45" + ], + "filament_dev_drying_cooling_temperature": [ + "45" + ], + "filament_dev_ams_drying_temperature": [ + "45", + "45", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" ], "hot_plate_temp": [ "55" diff --git a/resources/profiles/BBL/filament/fdm_filament_pp.json b/resources/profiles/BBL/filament/fdm_filament_pp.json index dd390e0a82..2d8c3772ba 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pp.json +++ b/resources/profiles/BBL/filament/fdm_filament_pp.json @@ -43,6 +43,34 @@ "filament_adhesiveness_category": [ "902" ], + "filament_dev_chamber_drying_bed_temperature": [ + "70" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [ + "1", + "0" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "60" + ], + "filament_dev_drying_cooling_temperature": [ + "50" + ], + "filament_dev_ams_drying_temperature": [ + "60", + "60", + "50", + "50" + ], + "filament_dev_drying_softening_temperature": [ + "55" + ], "hot_plate_temp": [ "55" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_ppa.json b/resources/profiles/BBL/filament/fdm_filament_ppa.json index bb06a73c76..3bba318bc5 100644 --- a/resources/profiles/BBL/filament/fdm_filament_ppa.json +++ b/resources/profiles/BBL/filament/fdm_filament_ppa.json @@ -46,6 +46,34 @@ "filament_vendor": [ "Bambu Lab" ], + "filament_dev_chamber_drying_bed_temperature": [ + "100" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [], + "filament_dev_chamber_drying_time": [ + "18" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "165" + ], + "filament_dev_drying_cooling_temperature": [ + "150" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "85", + "65", + "85" + ], + "filament_dev_drying_softening_temperature": [ + "150" + ], "hot_plate_temp": [ "100" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pps.json b/resources/profiles/BBL/filament/fdm_filament_pps.json index a19a5aca2b..d1c6a6aed2 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pps.json +++ b/resources/profiles/BBL/filament/fdm_filament_pps.json @@ -43,6 +43,31 @@ "filament_adhesiveness_category": [ "801" ], + "filament_dev_chamber_drying_bed_temperature": [ + "100" + ], + "filament_dev_ams_drying_time": [ + "12", + "12", + "12", + "12" + ], + "filament_dev_ams_drying_ams_limitations": [], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "165" + ], + "filament_dev_drying_cooling_temperature": [ + "150" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "85", + "65", + "85" + ], + "filament_dev_drying_softening_temperature": [ + "150" + ], "hot_plate_temp": [ "110" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_pva.json b/resources/profiles/BBL/filament/fdm_filament_pva.json index 98ca7e63b9..55d83517ce 100644 --- a/resources/profiles/BBL/filament/fdm_filament_pva.json +++ b/resources/profiles/BBL/filament/fdm_filament_pva.json @@ -49,6 +49,27 @@ "filament_adhesiveness_category": [ "704" ], + "filament_dev_ams_drying_time": [ + "12", + "18", + "12", + "18" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "75" + ], + "filament_dev_drying_cooling_temperature": [ + "40" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "85", + "65", + "70" + ], + "filament_dev_drying_softening_temperature": [ + "75" + ], "hot_plate_temp": [ "55" ], diff --git a/resources/profiles/BBL/filament/fdm_filament_tpu.json b/resources/profiles/BBL/filament/fdm_filament_tpu.json index f6ab1d3edf..d2ef5db84e 100644 --- a/resources/profiles/BBL/filament/fdm_filament_tpu.json +++ b/resources/profiles/BBL/filament/fdm_filament_tpu.json @@ -46,6 +46,30 @@ "filament_adhesiveness_category": [ "600" ], + "filament_dev_ams_drying_time": [ + "12", + "18", + "12", + "18" + ], + "filament_dev_chamber_drying_time": [ + "16" + ], + "filament_dev_ams_drying_heat_distortion_temperature": [ + "45" + ], + "filament_dev_drying_cooling_temperature": [ + "40" + ], + "filament_dev_ams_drying_temperature": [ + "65", + "75", + "45", + "45" + ], + "filament_dev_drying_softening_temperature": [ + "50" + ], "hot_plate_temp": [ "35" ], diff --git a/resources/profiles/BBL/machine/Bambu Lab A2L 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab A2L 0.2 nozzle.json new file mode 100644 index 0000000000..afdfa19fdd --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab A2L 0.2 nozzle.json @@ -0,0 +1,37 @@ +{ + "type": "machine", + "name": "Bambu Lab A2L 0.2 nozzle", + "inherits": "Bambu Lab A2L 0.4 nozzle", + "from": "system", + "setting_id": "GM055", + "instantiation": "true", + "nozzle_diameter": [ + "0.2" + ], + "printer_model": "Bambu Lab A2L", + "printer_variant": "0.2", + "default_filament_profile": [ + "Bambu PLA Basic @BBL A2L 0.2 nozzle" + ], + "default_print_profile": "0.10mm Standard @BBL A2L 0.2 nozzle", + "machine_max_speed_x": [ + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200" + ], + "max_layer_height": [ + "0.14" + ], + "min_layer_height": [ + "0.04" + ], + "retract_lift_below": [ + "326" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab A2L 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab A2L 0.4 nozzle.json new file mode 100644 index 0000000000..93bf4afd83 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab A2L 0.4 nozzle.json @@ -0,0 +1,100 @@ +{ + "type": "machine", + "name": "Bambu Lab A2L 0.4 nozzle", + "inherits": "fdm_bbl_3dp_001_common", + "from": "system", + "setting_id": "GM056", + "instantiation": "true", + "nozzle_diameter": [ + "0.4" + ], + "printer_model": "Bambu Lab A2L", + "printer_variant": "0.4", + "auxiliary_fan": "0", + "bed_exclude_area": [], + "default_filament_profile": [ + "Bambu PLA Basic @BBL A2L 0.4 nozzle" + ], + "default_print_profile": "0.20mm Standard @BBL A2L", + "enable_long_retraction_when_cut": "2", + "extruder_clearance_height_to_lid": "325", + "extruder_clearance_height_to_rod": "25", + "extruder_clearance_max_radius": "73", + "grab_length": [ + "17.4" + ], + "head_wrap_detect_zone": [ + "226x224", + "256x224", + "256x256", + "226x256" + ], + "machine_bed_mass_Y": "2700", + "machine_load_filament_time": "11", + "machine_max_acceleration_extruding": [ + "12000", + "12000" + ], + "machine_max_acceleration_x": [ + "12000", + "12000" + ], + "machine_max_acceleration_y": [ + "8000", + "8000" + ], + "machine_max_acceleration_z": [ + "1500", + "1500" + ], + "machine_max_force_Y": "29", + "machine_max_jerk_e": [ + "3", + "3" + ], + "machine_max_printed_mass": "2000", + "machine_max_speed_x": [ + "500", + "500" + ], + "machine_max_speed_y": [ + "500", + "500" + ], + "machine_max_speed_z": [ + "30", + "30" + ], + "machine_unload_filament_time": "12", + "nozzle_height": "4.76", + "nozzle_type": [ + "stainless_steel" + ], + "nozzle_volume": [ + "92" + ], + "deretract_speed_extruder_change": [ + "30" + ], + "printable_area": [ + "0x0", + "330x0", + "330x320", + "0x320" + ], + "printable_height": "325", + "printer_structure": "i3", + "retract_lift_below": [ + "326" + ], + "support_fast_purge_mode": "1", + "support_object_skip_flush": "1", + "upward_compatible_machine": [ + "Bambu Lab H2S 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 build_plate_detect_flag=1\n;M1002 set_flag bed_heat_stable_wait_flag=1\n\n;======== A2L start gcode==========\n;===== 2026/05/26 =====\nT1000 O0\nM1002 gcode_claim_action : 2\n{if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n M140 S65\n{else}\n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n{endif}\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\nM400\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L30 C53 D9 M30 E53 F9 N30\nM1006 A56 B9 L30 C56 D9 M30 E56 F9 N30\nM1006 A61 B9 L30 C61 D9 M30 E61 F9 N30\nM1006 A53 B9 L30 C53 D9 M30 E53 F9 N30\nM1006 A56 B9 L30 C56 D9 M30 E56 F9 N30\nM1006 A61 B18 L30 C61 D18 M30 E61 F18 N30\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 M220 S100 ;Reset Feedrate\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n M983.4 S0\n;===== reset machine status =================\n;Set the filament gear warning temperature\n{if (temperature_vitrification[initial_filament_id] <= 50)}\n {if ((filament_ids[initial_filament_id]==\"GFA05\") || (filament_ids[initial_filament_id]==\"GFA06\"))}\n M142 P1 O45; set PLASILK gear warning temperature when start\n {else}\n M142 P1 O60; set PLA/PLACF/PLAAERO/PVA/TPU gear warning temperature when start\n {endif}\n{else}\n M142 P1 O100 ; set gear warning temperature when start\n{endif}\n;===== start to heat heatbed & hotend==========\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\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 M105\n G28 X Z P0 T300 W\n G150.3\n G1 Z1.3 F1200\n G150.1 F16000 ; wipe mouth to avoid filament stick to heatbed\n G90\n M400\n;===== first homing end =====\n\n\n;===== detection start =====\n;===== build_plate_detect_flag start =====\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n G91\n G1 Z5 F1200\n G90\n G0 X15 F30000\n G0 Y319 F3000\n G91\n G1 Z-5 F1200\n G28 Z P0 T140\n G1 F1200\n G39.4\n G90\n G1 Z5 F1200\nM623\n;===== build_plate_detect_flag end =====\n;===== detection end =====\n\n\n;===== hotend hotbed pre-heat start =====\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]-80} A ; rise nozzle temp in advance\n\n G90\n G1 Y220 F3000 ; Put away the heated bed to prevent collisions\n\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n M190 S65\n {else}\n M190 S[bed_temperature_initial_layer_single]\n {endif}\n;===== hotend hotbed pre-heat end =====\n\n\n;===== prepare print temperature and material ==========\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n\n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG\") || (filament_type[initial_no_support_filament_id] == \"PETG-CF\")) && (nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{endif}\n\n M620.11 P0 L0 I[initial_no_support_filament_id] E0\n M620.11 K0 I[initial_no_support_filament_id] R0\n\n M620 S[initial_no_support_filament_id]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_filament_id]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M621 S[initial_no_support_filament_id]A\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n{if ((filament_type[initial_no_support_filament_id] == \"PETG\") || (filament_type[initial_no_support_filament_id] == \"PETG-CF\") || (filament_type[initial_no_support_filament_id] == \"TPU\") || (filament_type[initial_no_support_filament_id] == \"TPU-AMS\"))}\n G390.7 M6 G4 C3\n{else}\n G390.7 M6 G6 C3\n{endif}\n;===== prepare print temperature and material ==========\n\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M623\n;===== auto extrude cali end =========================\n\n\n {if filament_type[initial_filament_id] == \"TPU\" || filament_type[initial_filament_id] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G0 Z1.3 F1200\n G150.2\n G150.1 F16000\n\n G91\n G1 X20 F12000 ; move away from the trash bin\n G90\n M400\n\n\n;===== wipe nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M400\n M109 S140 A\n M106 P1 S255\n G91\n G1 Z1.3 F1200\n G90\n M400 S1\n ;======== enhance brush nozzle start =====\n G150.1 F16000\n G91\n G1 Y5 F5000\n G1 X-20 F16000\n G1 Y-10 F5000\n G1 X-20 F16000\n G1 Y10 F5000\n G1 X20 F16000\n G1 Y-10 F5000\n G1 X20 F16000\n G1 Y5 F5000\n G90\n G150.1 F16000\n G150.3\n ;======== enhance brush nozzle end =====\n M106 P1 S0\n;===== wipe nozzle end =====\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 Z5 F1200\n G1 X165 Y160 F20000\n M400 P200\n M970.3 Q1 A5 K0 O3\n M970.3 Q1 B1\n M970.2 Q1 K1 W52 Z0.1 B30 ;\n M970.3 Q0 A10 K0 O1\n M970.3 Q0 B1\n M970.2 Q0 K1 W40 Z0.1 B20 ;\n M974 Q0 S2 P0\n M974 Q1 S2 P0\n M975 S1 R1 M1\n M400\n G1 X155 F3000\n G150.3\n;===== mech mode sweep end =====\n\n\n;===== bed leveling ==================================\n\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n M190 S65\n {else}\n M190 S[bed_temperature_initial_layer_single] ; ensure bed temp\n {endif}\n M109 S140 A\n\n\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n M1002 gcode_claim_action : 58\n SYNC R0 T600\n M1030 S500 ; action before has done 200s insulation\n M1030 C\n {else}\n M1002 judge_flag bed_heat_stable_wait_flag\n M622 J1\n {if (bed_temperature_initial_layer_single > 35)}\n M1002 gcode_claim_action : 54\n G29.30 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 M623\n {endif}\n SYNC R0 T120 ; Adjust estimated time\n\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 && (bed_temperature_initial_layer_single == 55)}\n G29 R\n {else}\n {if (bed_temperature_initial_layer_single > 35)}\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]} O1 R\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} O R\n {endif}\n {endif}\n M400\n M623\n\n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n G29 R\n {else}\n {if (bed_temperature_initial_layer_single > 35)}\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]} O1 R\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} O R\n {endif}\n {endif}\n M400\n M623\n\n M622 J0\n G28 R\n M623\n G29.2 S1\n;===== bed leveling end ================================\n\n M985.1 U0 E2\n M985.1 U1 E2\n\n M104 S{nozzle_temperature_initial_layer[initial_filament_id]} A\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n M190 S65\n {else}\n M190 S[bed_temperature_initial_layer_single] ; ensure bed temp\n {endif}\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;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n {if hold_chamber_temp_for_flat_print && (bed_temperature_initial_layer_single == 55)}\n G29.1 Z{-0.03} ; for Textured PEI Plate first layer\n {else}\n G29.1 Z{-0.04} ; for Textured PEI Plate\n {endif}\n {else}\n G29.1 Z{-0.01}\n {endif}\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n G0 X145 Y0 F24000\n M400\n G130 O0 X145 Y-0.2 Z0.8 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2/2.4053} L40 E20 D4\n G90\n M83\n G1 Z0.2\n M400\n;===== nozzle load line end ===========================\nM1007 S1 C1;turn on mass estimation && clear\nM1002 gcode_claim_action : 0\n G29.99\n\n{if (filament_type[initial_no_support_filament_id] == \"TPU\")}\nM1015.3 S1 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]};enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PETG\")\n || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_filament_id] W1 ;enable ams air printing detect\n\nM1010 Q0 B0.005 S0.01\nM1010 Q1 B0.002 S0.01\nM1010.1 S1\n", + "machine_end_gcode": ";======== A2L end gcode ==========\n;===== 2026/04/07 =====\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\nG150.3\nG1 Y295 F3600\nG90\nG1 Z{max_layer_z + 0.4} F900 ; lower z a little\nM1002 judge_flag timelapse_record_flag\nM622 J1\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\nM106 S0 ; turn off fan\nM106 P2 S0 ; turn off remote part cooling fan\nM106 P3 S0 ; turn off chamber cooling fan\nM142 P1 Q0 ; turn off extruder autocool\n\nM220 S100 ; Reset feedrate magnitude\nM204.2 K1.0 ; Reset acc magnitude\nM73.2 R1.0 ;Reset left time magnitude\n\nM1015.3 S0 ;disable clog detect\nM1015.4 S0 K0 ;disable air printing detect\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L30 C53 D10 M30 E53 F10 N30 \nM1006 A57 B10 L30 C57 D10 M30 E57 F10 N30 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L30 C53 D10 M30 E53 F10 N30 \nM1006 A57 B10 L30 C57 D10 M30 E57 F10 N30 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L30 C48 D10 M30 E48 F10 N30 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L30 C60 D10 M30 E60 F10 N30 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\nM104 S0 ; turn off hotend\nM140 S0 ; turn off bed\nM1007 S0", + "layer_change_gcode": ";======== A2L layer_change gcode ==========\n;===== 2026/04/29 ====\n; update layer progress\nM201 N1 Y[curr_y_acceleration_limit]\nM73 L{layer_num+1}\nM991 S0 P{layer_num} ;notify layer change\nM1007 L1", + "time_lapse_gcode": ";======== A2L timelapse gcode ==========\n;===== 2026/05/09 ====\n{if !spiral_mode && print_sequence != \"by object\"}\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firware, default turned on\nM1002 judge_flag timelapse_record_flag\nM622 J1\n G1 Z{max_layer_z + 0.4} F1200\n G150.3 ; move to garbage can\n G1 Y{first_layer_center_no_wipe_tower[1]} F30000; move to safe pos\n M400\n M1004 S5 P1 ; external shutter\n M971 S11 C11 O0\n M400 P350\nM623\n; SKIPPABLE_END\n{endif}\n; SKIPPABLE_START\n; SKIPTYPE: g39_detection\n; go x0 clamping detection, clear_to_x0 = [clear_to_x0]\n{if !spiral_mode && (print_sequence != \"by object\" || clear_to_x0)}\nM1002 judge_flag g39_detection_flag\nM622 J1\n ; enable nozzle clog detect at 3rd layer\n {if layer_num == 1 || layer_num == 2}\n M400\n G390.7 M7 S1 Z2.5\n {endif}\n {if layer_num > 5 && layer_z <= 10 && layer_z > 0.4 && layer_num % 6 == 0}\n M400\n G390.7 M7 S1 Z2.5\n {endif}\n M1002 judge_flag g39_mass_exceed_flag\n M622 J1\n {if layer_num > 2}\n M400\n G390.7 M9 S1 Z2.5\n {endif}\n M623\nM623\n{endif}\n; SKIPPABLE_END", + "change_filament_gcode": ";======== A2L filament_change gcode ==========\n;===== 2026/05/26 =====\n\nM620 S[next_filament_id]A\nM204 S9000\n{if toolchange_count > 1 && (z_hop_types[current_filament_id] == 0 || z_hop_types[current_filament_id] == 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_filament_id] == \"PLA\") || (filament_type[current_filament_id] == \"PLA-CF\") || (filament_type[current_filament_id] == \"PETG\") || (filament_type[current_filament_id] == \"PETG-CF\")) && (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_filament_id]/2.4053*60} L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG\") || (filament_type[next_filament_id] == \"PETG-CF\")) && (nozzle_diameter_at_nozzle_id[next_nozzle_id] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_filament_id]/2.4053*60} L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 L0 I[current_filament_id] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 P0 L0 I[current_filament_id] E0\n{endif}\n\nM620.11 K0 I[current_filament_id] R0\n\n\nT[next_filament_id]\n\n;deretract\n{if filament_type[next_filament_id] == \"TPU\"}\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\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 80) * 7.5 + 6.5}\n\n; compensate for heating and cooling\n{if flush_length > 0}\n{if flush_temperatures[next_filament_id] > new_filament_temp}\nSYNC T{(flush_temperatures[next_filament_id]-(new_filament_temp - filament_cooling_before_tower[next_filament_id]))/hotend_cooling_rate[filament_map[next_filament_id]-1]}\nSYNC T{(flush_temperatures[next_filament_id]-(new_filament_temp - filament_cooling_before_tower[next_filament_id]))/hotend_heating_rate[filament_map[next_filament_id]-1]}\n{else}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_filament_id] -flush_temperatures[next_filament_id])/hotend_cooling_rate[filament_map[next_filament_id]-1]}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_filament_id] -flush_temperatures[next_filament_id])/hotend_heating_rate[filament_map[next_filament_id]-1]}\n{endif}\n{endif}\n\n; VFLUSH_END\n\n\n\nM1002 set_filament_type:{filament_type[next_filament_id]}\n\nM400\nM83\n{if next_filament_id < 255}\nM620.10 R{retract_length_toolchange[filament_map[next_filament_id]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\nM983.3 F{filament_max_volumetric_speed[next_filament_id]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_filament_id]-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_filament_id]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_filament_id]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_filament_id]-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_filament_id] == \"TPU\")}\nM1015.3 S1 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]};enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PETG\")\n || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} ;disable E air printing detect\n{endif}\n\n{if ((filament_type[next_filament_id] == \"PETG\") || (filament_type[next_filament_id] == \"PETG-CF\") || (filament_type[next_filament_id] == \"TPU\") || (filament_type[next_filament_id] == \"TPU-AMS\"))}\n G390.7 M6 G4 C3\n{else}\n G390.7 M6 G6 C3\n{endif}\n\nM620.6 I[next_filament_id] W1 ;enable ams air printing detect\n\n;Set the filament gear warning temperature\n{if (temperature_vitrification[next_filament_id] <= 50)}\n {if ((filament_ids[next_filament_id]==\"GFA05\") || (filament_ids[next_filament_id]==\"GFA06\"))}\n M142 P1 O45; set PLASILK gear warning temperature when filament change\n {else}\n M142 P1 O60; set PLA/PLACF/PLAAERO/PVA/TPU gear warning temperature when filament change\n {endif}\n{else}\n M142 P1 O100 ; set gear warning temperature when filament change\n{endif}\n" +} diff --git a/resources/profiles/BBL/machine/Bambu Lab A2L 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab A2L 0.6 nozzle.json new file mode 100644 index 0000000000..56a902f6a2 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab A2L 0.6 nozzle.json @@ -0,0 +1,37 @@ +{ + "type": "machine", + "name": "Bambu Lab A2L 0.6 nozzle", + "inherits": "Bambu Lab A2L 0.4 nozzle", + "from": "system", + "setting_id": "GM057", + "instantiation": "true", + "nozzle_diameter": [ + "0.6" + ], + "printer_model": "Bambu Lab A2L", + "printer_variant": "0.6", + "default_filament_profile": [ + "Bambu PLA Basic @BBL A2L 0.6 nozzle" + ], + "default_print_profile": "0.30mm Standard @BBL A2L 0.6 nozzle", + "machine_max_speed_x": [ + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200" + ], + "max_layer_height": [ + "0.42" + ], + "min_layer_height": [ + "0.12" + ], + "retract_lift_below": [ + "326" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab A2L 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab A2L 0.8 nozzle.json new file mode 100644 index 0000000000..20cf48518c --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab A2L 0.8 nozzle.json @@ -0,0 +1,37 @@ +{ + "type": "machine", + "name": "Bambu Lab A2L 0.8 nozzle", + "inherits": "Bambu Lab A2L 0.4 nozzle", + "from": "system", + "setting_id": "GM058", + "instantiation": "true", + "nozzle_diameter": [ + "0.8" + ], + "printer_model": "Bambu Lab A2L", + "printer_variant": "0.8", + "default_filament_profile": [ + "Bambu PLA Basic @BBL A2L 0.8 nozzle" + ], + "default_print_profile": "0.40mm Standard @BBL A2L 0.8 nozzle", + "machine_max_speed_x": [ + "500", + "200" + ], + "machine_max_speed_y": [ + "500", + "200" + ], + "max_layer_height": [ + "0.56" + ], + "min_layer_height": [ + "0.16" + ], + "retract_lift_below": [ + "326" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab A2L.json b/resources/profiles/BBL/machine/Bambu Lab A2L.json new file mode 100644 index 0000000000..b9ad344d22 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab A2L.json @@ -0,0 +1,17 @@ +{ + "type": "machine_model", + "name": "Bambu Lab A2L", + "nozzle_diameter": "0.4;0.2;0.6;0.8", + "url": "http://www.bambulab.com/Parameters/printer_model/Bambu Lab X1.json", + "bed_model": "bbl-3dp-H2C.stl", + "bed_texture": "bbl-3dp-logo.svg", + "bottom_texture_rect_longer": "45, -14.5, 240, 8", + "default_bed_type": "Textured PEI Plate", + "family": "BBL-3DP", + "image_bed_type": "o", + "machine_tech": "FFF", + "model_id": "N9", + "not_support_bed_type": "Cool Plate", + "use_double_extruder_default_texture": "true", + "default_materials": "Bambu PLA Matte @BBL A2L;Bambu PLA Basic @BBL A2L;Bambu PLA Silk @BBL A2L;Bambu Support For PLA/PETG @BBL A2L;Bambu TPU 95A @BBL A2L;Bambu PLA Tough @BBL A2L;Generic PLA @BBL A2L;Generic PLA High Speed @BBL A2L;Generic PETG @BBL A2L;Generic PVA @BBL A2L;Bambu PETG HF @BBL A2L" +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.2 nozzle.json new file mode 100644 index 0000000000..1f1f1c4314 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.2 nozzle.json @@ -0,0 +1,38 @@ +{ + "type": "machine", + "name": "Bambu Lab H2C 0.2 nozzle", + "inherits": "Bambu Lab H2C 0.4 nozzle", + "from": "system", + "setting_id": "GM042", + "instantiation": "true", + "nozzle_diameter": [ + "0.2", + "0.2" + ], + "printer_model": "Bambu Lab H2C", + "printer_variant": "0.2", + "default_filament_profile": [ + "Bambu PLA Basic @BBL H2C 0.2 nozzle" + ], + "default_print_profile": "0.10mm Standard @BBL H2C 0.2 nozzle", + "max_layer_height": [ + "0.14", + "0.14" + ], + "min_layer_height": [ + "0.04", + "0.04" + ], + "retraction_length": [ + "0.4", + "0.4", + "0.4", + "0.4" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.2 nozzle", + "Bambu Lab H2D 0.2 nozzle", + "Bambu Lab H2D Pro 0.2 nozzle", + "Bambu Lab A2L 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle.json new file mode 100644 index 0000000000..867e419c60 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.4 nozzle.json @@ -0,0 +1,139 @@ +{ + "type": "machine", + "name": "Bambu Lab H2C 0.4 nozzle", + "inherits": "fdm_bbl_3dp_002_common", + "from": "system", + "setting_id": "GM041", + "instantiation": "true", + "nozzle_diameter": [ + "0.4", + "0.4" + ], + "printer_model": "Bambu Lab H2C", + "printer_variant": "0.4", + "farthest_point_timelapse": "1", + "default_filament_profile": [ + "Bambu PLA Basic @BBL H2C" + ], + "default_print_profile": "0.20mm Standard @BBL H2C", + "enable_long_retraction_when_cut": [ + "2" + ], + "enable_pre_heating": "1", + "extruder_clearance_height_to_lid": "201", + "extruder_clearance_height_to_rod": "47.4", + "extruder_clearance_max_radius": "96", + "extruder_printable_area": [ + "0x0,325x0,325x320,0x320", + "25x0,330x0,330x320,25x320" + ], + "extruder_max_nozzle_count": [ + "1", + "6" + ], + "fan_direction": "left", + "hotend_cooling_rate": [ + "1.6", + "1.6", + "3.4", + "3.4" + ], + "hotend_heating_rate": [ + "3.5", + "3.5", + "13.3", + "13.3" + ], + "long_retractions_when_cut": [ + "1", + "1", + "1", + "1" + ], + "machine_load_filament_time": "15", + "machine_max_speed_x": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_y": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_z": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "machine_unload_filament_time": "15", + "machine_max_speed_e": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "master_extruder_id": "2", + "nozzle_volume": [ + "130", + "133", + "145", + "148" + ], + "printable_area": [ + "0x0", + "330x0", + "330x320", + "0x320" + ], + "retract_lift_below": [ + "319", + "319", + "319", + "319" + ], + "retraction_distances_when_cut": [ + "14", + "14", + "14", + "14" + ], + "support_chamber_temp_control": "1", + "support_cooling_filter": "1", + "wrapping_exclude_area": [ + "145x310", + "251x310", + "251x326", + "145x326" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.4 nozzle", + "Bambu Lab H2D 0.4 nozzle", + "Bambu Lab H2D Pro 0.4 nozzle", + "Bambu Lab A2L 0.4 nozzle" + ], + "machine_start_gcode": ";===== machine: H2C =========================\n;===== date: 20260608 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99\nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99\nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99\nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99\nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99\nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1\nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\nM620 N ;enable hotend remap\nM620 T0 ;print tmpr\nM620 T1 ;sn -> pos\nM620 T2 ;filament_id\n\n;===== start to heat heatbed & hotend==========\n\n M104 O-80 A\n M140 D[bed_temperature_initial_layer_single]\n\n;===== start to heat heatbead & hotend==========\n\n;===== avoid end stop =================\nG91\nG380 S2 Z42 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ====\n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ====\n\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nM640 S\nM640.1 R\nM641\nG28 X T300\nT1000\n\nG150.3\nM972 S24 P0 T2000 ; live-view camera foolproof\nM972 S46 P0 T5000 ; vortek anti-collision\nM640.1 S\nM640.4\n{if (first_non_support_filaments[0] != -1)}\nM640 S\nM640.8 T A{first_non_support_filaments[0]} H{first_non_support_hotend[0]}\nM640.7 L\nM641\n{endif}\n\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\n\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\nM104 S0\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n\n;===== first homing end =====\n\n;===== detection start =====\n\nM1002 judge_flag build_plate_detect_flag\nM104 S0\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\nM1002 gcode_claim_action : 72 ; Hotend Type Detection\nT1001\nM972 S14 P0 T5000 ; nozzle type detection\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]} T{filament_map[initial_no_support_filament_id] % 2} ; rise temp in advance\n\nG151 P{filament_map[initial_no_support_filament_id] % 2} M ; plug the heat nozzle\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Heatbed underside foreign object detection\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60*0.8} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60*0.8} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{endif}\n\nM620.11 P1 I[initial_no_support_filament_id] B[initial_no_support_hotend] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_filament_id] B[initial_no_support_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_filament_id] B[initial_no_support_hotend] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_filament_id] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_filament_id] B[initial_no_support_hotend] E-{retraction_distances_when_cut[initial_no_support_filament_id]} F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_filament_id] == \"PA\") || (filament_type[initial_no_support_filament_id] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_filament_id] B[initial_no_support_hotend] R4 D2 E-{retraction_distances_when_cut[initial_no_support_filament_id]} F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_filament_id] B[initial_no_support_hotend] R10 D8 E-{retraction_distances_when_cut[initial_no_support_filament_id]} F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_filament_id]A H[initial_no_support_hotend] ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_filament_id] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\nM621 S[initial_no_support_filament_id]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\nM400\nM106 P1 S0\n\nG91\nG1 Y-16 F60000\nG90\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\n\nM400\n;M73 P99\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J2\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n\n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383.3 U140 L{initial_no_support_filament_id}\nM623\n\nM622 J1\n M1002 gcode_claim_action : 54\n M190 D[bed_temperature_initial_layer_single]\n\n M1002 gcode_claim_action : 39\n M620 D[initial_no_support_hotend]\n G383 O2 U140 L{initial_no_support_filament_id}\nM623\n\n;===== xy ofst cali end =====\n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n G150.3\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_filament_id] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n G150.3\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_filament_id]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_filament_id] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\nM622 J0\n G91\n G1 Z5 F1200\n G90\n M1012.7\n G383.7 U140 J0\nM623\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z10 F1200\n{if (first_non_support_filaments[0] != -1) && filament_type[initial_no_support_filament_id] != \"TPU\"}\nM640 S\nM640.7 U\nM640.7 L\nM640.2 R1\nM641\n{endif}\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n M400\nM623\n\nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\nM623\n\nM622 J0\n G28 R\nM623\n\n;===== bed leveling end ================================\n\nG39.1 ; cali nozzle wrapped detection pos\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\n;============switch again==================\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\nM620 S[initial_no_support_filament_id]A H[initial_no_support_hotend]\nM400\nT[initial_no_support_filament_id] H[initial_no_support_hotend]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_filament_id]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X165 Y160 F20000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n\n M975 S1\n;===== mech mode sweep end =====\n\n;===== wait temperature reaching the reference value =======\n\nM140 S[bed_temperature_initial_layer_single]\nM190 S[bed_temperature_initial_layer_single]\n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ====\n {if (min_vitrification_temperature <= 50)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n {if nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n {else}\n {if nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2}\n G29.1 Z{0.01}\n {endif}\n {endif}\nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation\nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n\n ========== record data ==========\n M1026\n M1012.8\n M1012.9\n G29.9\n ========== record data ==========\n\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M83\n{if nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.8}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n{endif}\n{if (filament_type[initial_no_support_filament_id] == \"TPU\")}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n{endif}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n G1 X290 E10 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_filament_id] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PETG\")\n || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_filament_id] H[initial_no_support_hotend] W1 ;enable ams air printing detect\nM620 O1\n\nM211 Z1\nG29.99\nM1002 gcode_claim_action : 0\nM400\n", + "machine_end_gcode": ";===== machine: H2C end =====\n;====== date: 20260313 ======\n\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nM211 Z1\nM640.2 R0\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\nG90\nM141 S0 ; turn off chamber heating\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 P9 S0 ; turn off ext toodhead cooling fan\n\n; pull back filament to AMS\nM620 S65535\n{if long_retraction_when_cut}\nM620.11 P1 I[current_filament_id] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_filament_id] B[current_hotend] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_filament_id] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_filament_id] B[current_hotend] R0\n{endif}\n\nM620.11 P1 I[current_filament_id] B[current_hotend] E-14\nT65535\nG150.2\nM621 S65535\n\nM620 S65279\nT65279\nG150.2\nM621 S65279\n\nG150.3\n\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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 (100.0 - max_layer_z/2) > 0}\n {if (max_layer_z + 100.0 - max_layer_z/2) < 320}\n G1 Z{max_layer_z + 100.0 - max_layer_z/2} F600\n G1 Z{max_layer_z + 98.0 - max_layer_z/2}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{else}\n {if (max_layer_z + 4.0) < 320}\n G1 Z{max_layer_z + 4.0} F600\n G1 Z{max_layer_z + 2.0}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{endif}\nM400 P100\nM17 R ; restore z current\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.4 S0 K0 ;disable air printing detect\n\n\n;=====printer finish air purification=========\nM622.1 S0\nM1002 judge_flag print_finish_air_filt_flag\n\nM622 J1\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P6 S255\nM400 S180\nM106 P6 S0\nM623\n\nM622 J2\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S127\nM400 S180\nM106 P3 S0\nM623\n;=====printer finish air purification=========\n\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99\nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99\nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99\nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99\nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0\nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99\nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0\nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99\nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", + "time_lapse_gcode": ";===== machine: H2C timelapse =====\n;======== date: 20260603 ========\n\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\n {if !spiral_mode}\n M993 A2 B2 C2\n M993 A0 B0 C0\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if timelapse_inline_photo}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {elsif has_timelapse_safe_pos && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} U{timelapse_pos_x} V{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n {endif}\n \n {if !spiral_mode}\n M993 A3 B3 C3\n {endif}\nM623\n; SKIPPABLE_END\n", + "wrapping_detection_gcode": ";===== machine: H2C =========================\n;===== date: 20251104 =====================\n\n{if !spiral_mode}\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 Y295 F30000\n G1 Y265 F18000\n \n M993 A3 B3 C3 ; nozzle cam detection allow status restore.\n {endif}\n{endif}\n", + "change_filament_gcode": ";======== H2C filament_change ========\n;===== 20260413 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PETG\")\n || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_filament_id]A H[next_hotend]\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if wipe_tower_center_pos_valid}\n M620.14 X[wipe_tower_center_pos_x] Y[wipe_tower_center_pos_y]\n{else}\n M620.14 X95.5 Y336\n{endif}\n\n{if ((filament_type[current_filament_id] == \"PLA\") || (filament_type[current_filament_id] == \"PLA-CF\") || (filament_type[current_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_filament_id]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[next_nozzle_id] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_filament_id]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 I[current_filament_id] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_filament_id] B[current_hotend] E0\n{endif}\n\n\nM620.15 P[filament_pre_cooling_temperature_nc[next_filament_id]]\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_filament_id]}\nM620.11 O1 T[filament_retract_length_nc]\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_filament_id] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_filament_id] B[current_hotend] R0\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_filament_id]}\n\nM628 S1\n{if filament_type[current_filament_id] == \"TPU\"}\nM620.11 S0 L0 I[current_filament_id] B[current_hotend] E-{retraction_distances_when_cut[current_filament_id]} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_filament_id] == \"PA\") || (filament_type[current_filament_id] == \"PA-GF\")}\nM620.11 S1 L0 I[current_filament_id] B[current_hotend] R4 D2 E-{retraction_distances_when_cut[current_filament_id]} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_filament_id] B[current_hotend] R10 D8 E-{retraction_distances_when_cut[current_filament_id]} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if (filament_type[current_filament_id] == \"TPU\") && (filament_map[current_filament_id] == 2) && (nozzle_volume_types[current_nozzle_id] != \"TPU High Flow\")}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\n{if (nozzle_volume_types[current_nozzle_id] == \"TPU High Flow\") && (filament_map[current_filament_id] == 2) && (filament_map[next_filament_id] == 1)}\n;sw from R2L&TPU kit, travel run a distance for sketch TPU\nG1 X30 Y30 F5000\nM400\nG1 X300 Y30 F5000\nM400\n{endif}\n\nT[next_filament_id] H[next_hotend]\n\n;deretract\n{if filament_type[next_filament_id] == \"TPU\"}\n{else}\n{if (filament_type[next_filament_id] == \"PA\") || (filament_type[next_filament_id] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; compensate for heating and cooling\n{if flush_length > 0}\n{if flush_temperatures[next_filament_id] > new_filament_temp}\nSYNC T{(flush_temperatures[next_filament_id]-(new_filament_temp - filament_cooling_before_tower[next_filament_id]))/hotend_cooling_rate[filament_map[next_filament_id]-1]}\nSYNC T{(flush_temperatures[next_filament_id]-(new_filament_temp - filament_cooling_before_tower[next_filament_id]))/hotend_heating_rate[filament_map[next_filament_id]-1]}\n{else}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_filament_id] -flush_temperatures[next_filament_id])/hotend_cooling_rate[filament_map[next_filament_id]-1]}\nSYNC T{(new_filament_temp - filament_cooling_before_tower[next_filament_id] -flush_temperatures[next_filament_id])/hotend_heating_rate[filament_map[next_filament_id]-1]}\n{endif}\n{endif}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_filament_id]}\n\nM400\nM83\n{if next_filament_id < 255}\n\n\nM620.10 R{new_extruder_retracted_length}\n\n{if (print_sequence == \"by object\" && !has_wipe_tower)}\nM628 S0 F1 L10.0\n; VFLUSH_START\n;VG1 E10 F[new_filament_e_feedrate]\n; VFLUSH_END\n{else}\nM628 S0\n{endif}\n;VM109 S[new_filament_temp]\n\nM629\nM400\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_filament_id]/2.4} A0.4 R{new_extruder_retracted_length}\n\n\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_filament_id]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_filament_id]/2.4} A0.4 R{new_extruder_retracted_length}\nM400\n{if wipe_avoid_perimeter}\nG387 Y320 J1 F10000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG387 Y295 J1 F30000\nG387 Y265 J1 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\nM1002 set_flag powerloss_resume_flag=0\nM623\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_filament_id] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PETG\")\n || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_filament_id] H[next_hotend] W1 ;enable ams air printing detect\nM620 O{toolchange_count + 1}\nM1002 gcode_claim_action : 0" +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.6 nozzle.json new file mode 100644 index 0000000000..7174ec6f93 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.6 nozzle.json @@ -0,0 +1,38 @@ +{ + "type": "machine", + "name": "Bambu Lab H2C 0.6 nozzle", + "inherits": "Bambu Lab H2C 0.4 nozzle", + "from": "system", + "setting_id": "GM043", + "instantiation": "true", + "nozzle_diameter": [ + "0.6", + "0.6" + ], + "printer_model": "Bambu Lab H2C", + "printer_variant": "0.6", + "default_print_profile": "0.30mm Standard @BBL H2C 0.6 nozzle", + "default_filament_profile": [ + "Bambu PLA Basic @BBL H2C 0.6 nozzle" + ], + "max_layer_height": [ + "0.42", + "0.42" + ], + "min_layer_height": [ + "0.12", + "0.12" + ], + "retraction_length": [ + "1.4", + "1.4", + "1.4", + "1.4" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.6 nozzle", + "Bambu Lab H2D 0.6 nozzle", + "Bambu Lab H2D Pro 0.6 nozzle", + "Bambu Lab A2L 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2C 0.8 nozzle.json new file mode 100644 index 0000000000..67da881c6d --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab H2C 0.8 nozzle.json @@ -0,0 +1,38 @@ +{ + "type": "machine", + "name": "Bambu Lab H2C 0.8 nozzle", + "inherits": "Bambu Lab H2C 0.4 nozzle", + "from": "system", + "setting_id": "GM044", + "instantiation": "true", + "nozzle_diameter": [ + "0.8", + "0.8" + ], + "printer_model": "Bambu Lab H2C", + "printer_variant": "0.8", + "default_print_profile": "0.40mm Standard @BBL H2C 0.8 nozzle", + "default_filament_profile": [ + "Bambu PLA Basic @BBL H2C 0.8 nozzle" + ], + "max_layer_height": [ + "0.56", + "0.56" + ], + "min_layer_height": [ + "0.16", + "0.16" + ], + "retraction_length": [ + "3", + "3", + "3", + "3" + ], + "upward_compatible_machine": [ + "Bambu Lab H2S 0.8 nozzle", + "Bambu Lab H2D 0.8 nozzle", + "Bambu Lab H2D Pro 0.8 nozzle", + "Bambu Lab A2L 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2C.json b/resources/profiles/BBL/machine/Bambu Lab H2C.json new file mode 100644 index 0000000000..92645a5933 --- /dev/null +++ b/resources/profiles/BBL/machine/Bambu Lab H2C.json @@ -0,0 +1,16 @@ +{ + "type": "machine_model", + "name": "Bambu Lab H2C", + "nozzle_diameter": "0.2;0.4;0.6;0.8", + "url": "http://www.bambulab.com/Parameters/printer_model/Bambu Lab X1.json", + "bed_model": "bbl-3dp-H2C.stl", + "bed_texture": "bbl-3dp-logo.svg", + "default_bed_type": "Textured PEI Plate", + "bottom_texture_rect_longer": "45, -14.5, 240, 8", + "image_bed_type": "o", + "family": "BBL-3DP", + "machine_tech": "FFF", + "model_id": "O1C2", + "not_support_bed_type": "Cool Plate;Smooth PEI Plate / High Temp Plate", + "default_materials": "Bambu PLA Basic @BBL H2C;Bambu PLA-CF @BBL H2C;Bambu PETG Basic @BBL H2C;Bambu ABS @BBL H2C;Bambu PETG HF @BBL H2C;Bambu PLA Silk @BBL H2C;Bambu PLA Matte @BBL H2C;Bambu PC @BBL H2C;Bambu PA-CF @BBL H2C;Bambu PLA Pure @BBL H2C" +} diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D 0.2 nozzle.json index b8f7b6e090..5f4e504a7d 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D 0.2 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D 0.2 nozzle.json @@ -31,5 +31,303 @@ ], "upward_compatible_machine": [ "Bambu Lab H2D Pro 0.2 nozzle" + ], + "deretraction_speed": [ + "30", + "30", + "30", + "30" + ], + "deretract_speed_extruder_change": [ + "15", + "15", + "15", + "15" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2" + ], + "hotend_heating_rate": [ + "3.6", + "3.6", + "3.6", + "3.6" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "machine_max_speed_e": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "machine_max_speed_x": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_y": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_z": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "130", + "133", + "145", + "148" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0" + ], + "retract_lift_below": [ + "319", + "319", + "319", + "319" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1" + ], + "retraction_distances_when_cut": [ + "10", + "10", + "10", + "10" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow" ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D 0.4 nozzle.json index d420705590..6259ce4946 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D 0.4 nozzle.json @@ -11,6 +11,7 @@ ], "printer_model": "Bambu Lab H2D", "printer_variant": "0.4", + "farthest_point_timelapse": "1", "enable_long_retraction_when_cut": [ "2" ], @@ -23,10 +24,12 @@ "0x0,325x0,325x320,0x320", "25x0,350x0,350x320,25x320" ], + "fan_direction": "left", "hotend_heating_rate": [ "3.6", "3.6", "3.6", + "3.6", "3.6" ], "machine_load_filament_time": "30", @@ -38,6 +41,8 @@ "50", "50", "50", + "50", + "50", "50" ], "machine_max_speed_x": [ @@ -48,6 +53,8 @@ "1000", "1000", "1000", + "1000", + "1000", "1000" ], "machine_max_speed_y": [ @@ -58,6 +65,8 @@ "1000", "1000", "1000", + "1000", + "1000", "1000" ], "machine_max_speed_z": [ @@ -68,6 +77,8 @@ "30", "30", "30", + "30", + "30", "30" ], "machine_switch_extruder_time": "5.6", @@ -77,6 +88,7 @@ "130", "133", "145", + "148", "148" ], "printable_area": [ @@ -89,16 +101,19 @@ "319", "319", "319", + "319", "319" ], "retraction_distances_when_cut": [ "10", "10", "10", + "10", "10" ], "support_air_filtration": "1", "support_chamber_temp_control": "1", + "support_cooling_filter": "1", "support_object_skip_flush": "1", "wrapping_exclude_area": [ "145x310", @@ -109,10 +124,293 @@ "upward_compatible_machine": [ "Bambu Lab H2D Pro 0.4 nozzle" ], - "machine_start_gcode": ";===== machine: H2D start ======\n;===== date: 20250821 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z27 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140 A\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{elsif curr_bed_type==\"High Temp Plate\"}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n\n T1001\n G383.4 ; left-extruder load status detection\n \n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\n M972 S14 P0 ; nozzle type detection\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} 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\nM620.11 P0 I[initial_no_support_extruder] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M83\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\n;===== z ofst cali start =====\n\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n\n G383 O0 M2 T140\n M500\n\n;===== z ofst cali end =====\n\nG39.1 ; cali nozzle wrapped detection pos\nM500\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\n M500\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\nM400\n;M73 P99\n\nM1002 gcode_claim_action : 0\nM400\n\n;============switch again==================\n\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n\n", - "machine_end_gcode": ";===== date: 2025/05/16 =====================\n;===== H2D =====================\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 0.5} F900 ; lower z a little\n\nG90\nM141 S0 ; turn off chamber heating\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\n\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nM620 S65279\nT65279\nG150.2\nM621 S65279\n\nG150.3\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\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\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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 (max_layer_z + 100.0) < 320}\n G1 Z{max_layer_z + 100.0} F600\n G1 Z{max_layer_z +98.0}\n{else}\n G1 Z320 F600\n G1 Z320\n{endif}\nM400 P100\nM17 R ; restore z current\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.4 S0 K0 ;disable air printing detect\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", + "machine_start_gcode": ";===== machine: H2D =========================\n;===== date: 20260116 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\nG28.140 D0; reset pre-extrude z pos\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z42 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n {if(cooling_filter_enabled)}\n M145.2 P0 F0\n {else}\n M145.2 P0 F1\n {endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140 A\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n\nM1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG91\nG380 S2 Z30 F1200 ; lower heatbed to move toolhead\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n \nM1002 judge_flag build_plate_detect_flag\nM622 S1\n ;M1002 gcode_claim_action : 11 ; Indentifying build plate type\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n ;M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\nM1002 gcode_claim_action : 72 ; Hotend Type Detection\nT1001\nM972 S14 P0 T5000 ; nozzle type detection\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n\nG151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n\n{if max_print_z >= 145}\nM1002 gcode_claim_action : 75 ; Heatbed underside foreign object detection\nG3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n{endif}\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n\nM620.11 P0 I[initial_no_support_extruder] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R \n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28 R\nM623\n\n;===== bed leveling end ================================\n\n;===== z ofst cali start =====\n\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n\n G383 O0 M2 T140\n M500\n\n;===== z ofst cali end =====\n\nG39.1 ; cali nozzle wrapped detection pos\nM500\n\nG90\nG1 Z5 F1200\nG1 X270 Y-0.5 F60000\nG28.140 S0 ; cali pre-extrude z pos\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\nG29.9\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\n M500\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\nM400\n;M73 P99\n\nM1002 gcode_claim_action : 0\nM400\n\n;============switch again==================\n\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ==== \n {if (min_vitrification_temperature <= 50)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {else}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n {else}\n {if nozzle_diameter[initial_no_support_extruder] == 0.2}\n G29.1 Z{0.01} ; for Textured PEI Plate\n {endif}\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14 R0\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n{endif}\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 X290 E10 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n\n", + "machine_end_gcode": ";========== H2D end ==========\n;===== date: 2025/12/26 =====\n\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nM400\nM211 Z1\nG1 Z{max_layer_z + 0.4} F900 ; lower z a little\n\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\nG90\nM141 S0 ; turn off chamber heating\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 P9 S0 ; turn off ext toodhead cooling fan\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nM620 S65279\nT65279\nG150.2\nM621 S65279\n\nG150.3\n\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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 (100.0 - max_layer_z/2) > 0}\n {if (max_layer_z + 100.0 - max_layer_z/2) < 320}\n G1 Z{max_layer_z + 100.0 - max_layer_z/2} F600\n G1 Z{max_layer_z + 98.0 - max_layer_z/2}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{else}\n {if (max_layer_z + 4.0) < 320}\n G1 Z{max_layer_z + 4.0} F600\n G1 Z{max_layer_z + 2.0}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{endif}\nM400 P100\nM17 R ; restore z current\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.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\nM622 J1\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P6 S255\nM400 S180\nM106 P6 S0\nM623\n\nM622 J2\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S127\nM400 S180\nM106 P3 S0\nM623\n;=====printer finish air purification=========\n\n\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", "layer_change_gcode": ";======== H2D 20250710 layer_change ========\n; layer num/total_layer_count: {layer_num+1}/[total_layer_count]\n; update layer progress\nM73 L{layer_num+1}\nM991 S0 P{layer_num} ;notify layer change\n", - "time_lapse_gcode": ";======== H2D 20250818========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firmware, default turned on\n\nM1002 judge_flag timelapse_record_flag\n\nM622 J1\nM993 A2 B2 C2\nM993 A0 B0 C0\n\n{if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n{endif}\n\n{if has_timelapse_safe_pos && timelapse_type == 0 && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} X{timelapse_pos_x} Y{timelapse_pos_y} Z{layer_z + 0.4} S11 C10 O0 T3000\n{else}\n {if spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z} S11 C10 O0 T3000\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + 0.4} S11 C10 O0 T3000\n {endif}\n{endif}\n\n{if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n{endif}\nM993 A3 B3 C3\n\nM623\n; SKIPPABLE_END\n", + "time_lapse_gcode": ";======== H2D 20260612========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firmware, default turned on\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\n {if !spiral_mode}\n M993 A2 B2 C2\n M993 A0 B0 C0\n {endif}\n\n {if timelapse_inline_photo}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M622.1 S0 ; for prev firmware, default turn off\n M1002 set_flag smooth_safe_pos_suppoprt_flag=1\n M1002 judge_flag smooth_safe_pos_suppoprt_flag\n \n M622 J0\n {if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if has_timelapse_safe_pos && timelapse_type == 0 && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} X{timelapse_pos_x} Y{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n {endif}\n M623\n\n M622 J1\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if has_timelapse_safe_pos && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} U{timelapse_pos_x} V{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n {endif}\n M623\n {endif}\n \n {if !spiral_mode}\n M993 A3 B3 C3\n {endif}\nM623\n; SKIPPABLE_END\n", "wrapping_detection_gcode": ";======== H2D 20250729 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 Y295 F30000\n G1 Y265 F18000\n \n M993 A3 B3 C3 ; nozzle cam detection allow status restore.\n {endif}\n M623\n{endif}\n", - "change_filament_gcode": ";======== H2D ========\n;===== 20250729 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((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 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\"}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\n\nM400\n{if wipe_avoid_perimeter}\nG1 Y320 F30000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG1 Y295 F30000\nG1 Y265 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\nM1002 gcode_claim_action : 0\n" + "change_filament_gcode": ";======== H2D ========\n;===== 20260116 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] R0\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if (filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\") && (old_extruder_variant != \"Direct Drive TPU High Flow\")}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\n{if (old_extruder_variant == \"Direct Drive TPU High Flow\") && (filament_map[current_extruder] == 2) && (filament_map[next_extruder] == 1)}\n;debug log pe:{previous_extruder} ce:{current_extruder} ne:{next_extruder} oev: {old_extruder_variant} nev:{new_extruder_variant}\n;debug fm-curr:{filament_map[current_extruder]} fm-next:{filament_map[next_extruder]}\n;sw from R2L&TPU kit, travel run a distance for sketch TPU\nG1 X30 Y30 F5000\nM400\nG1 X300 Y30 F5000\nM400\n{endif}\n\nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\nM620.10 R{new_extruder_retracted_length}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{new_extruder_retracted_length}\n\nM400\n{if wipe_avoid_perimeter}\nG1 Y320 F30000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG1 Y295 F30000\nG1 Y265 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\nM1002 gcode_claim_action : 0", + "deretraction_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "deretract_speed_extruder_change": [ + "15", + "15", + "15", + "15", + "15" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2", + "2" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1", + "1" + ], + "retraction_length": [ + "0.8", + "0.8", + "0.8", + "0.8", + "0.8" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive TPU High Flow" + ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D 0.6 nozzle.json index 77dbd3b3ed..164b2a606c 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D 0.6 nozzle.json @@ -27,6 +27,7 @@ "1.4", "1.4", "1.4", + "1.4", "1.4" ], "upward_compatible_machine": [ diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D 0.8 nozzle.json index adb65f2caa..acae75a038 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D 0.8 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D 0.8 nozzle.json @@ -31,5 +31,303 @@ ], "upward_compatible_machine": [ "Bambu Lab H2D Pro 0.8 nozzle" + ], + "deretraction_speed": [ + "30", + "30", + "30", + "30" + ], + "deretract_speed_extruder_change": [ + "15", + "15", + "15", + "15" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2" + ], + "hotend_heating_rate": [ + "3.6", + "3.6", + "3.6", + "3.6" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "machine_max_speed_e": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "machine_max_speed_x": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_y": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_z": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "130", + "133", + "145", + "148" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0" + ], + "retract_lift_below": [ + "319", + "319", + "319", + "319" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1" + ], + "retraction_distances_when_cut": [ + "10", + "10", + "10", + "10" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow" ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.2 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.2 nozzle.json index d4489dca79..2a5830740f 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.2 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.2 nozzle.json @@ -31,5 +31,297 @@ ], "upward_compatible_machine": [ "Bambu Lab H2D 0.2 nozzle" + ], + "deretraction_speed": [ + "30", + "30", + "30", + "30" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2" + ], + "hotend_heating_rate": [ + "3.6", + "3.6", + "3.6", + "3.6" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "machine_max_speed_e": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "machine_max_speed_x": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_y": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_z": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "130", + "133", + "145", + "148" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0" + ], + "retract_lift_below": [ + "319", + "319", + "319", + "319" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1" + ], + "retraction_distances_when_cut": [ + "10", + "10", + "10", + "10" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow" ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.4 nozzle.json index b62da4655f..842461e4d6 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.4 nozzle.json @@ -27,10 +27,12 @@ "0x0,325x0,325x320,0x320", "25x0,350x0,350x320,25x320" ], + "fan_direction": "left", "hotend_heating_rate": [ "3.6", "3.6", "3.6", + "3.6", "3.6" ], "machine_load_filament_time": "30", @@ -42,6 +44,8 @@ "50", "50", "50", + "50", + "50", "50" ], "machine_max_speed_x": [ @@ -52,6 +56,8 @@ "1000", "1000", "1000", + "1000", + "1000", "1000" ], "machine_max_speed_y": [ @@ -62,6 +68,8 @@ "1000", "1000", "1000", + "1000", + "1000", "1000" ], "machine_max_speed_z": [ @@ -72,6 +80,8 @@ "30", "30", "30", + "30", + "30", "30" ], "machine_switch_extruder_time": "5.6", @@ -81,6 +91,7 @@ "130", "133", "145", + "148", "148" ], "printable_area": [ @@ -93,16 +104,19 @@ "319", "319", "319", + "319", "319" ], "retraction_distances_when_cut": [ "10", "10", "10", + "10", "10" ], "support_air_filtration": "1", "support_chamber_temp_control": "1", + "support_cooling_filter": "1", "support_object_skip_flush": "1", "wrapping_exclude_area": [ "145x310", @@ -113,10 +127,286 @@ "upward_compatible_machine": [ "Bambu Lab H2D 0.4 nozzle" ], - "machine_start_gcode": ";===== machine: H2D Pro start ======\n;===== date: 20250821 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z27 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140 A\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{elsif curr_bed_type==\"High Temp Plate\"}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM1009 Q1 L1\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n\n T1001\n G383.4 ; left-extruder load status detection\n \n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n M972 S19 P0 C0 ; heatbed presence detection\nM623\n\n M972 S14 P0 ; nozzle type detection\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} 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\nM620.11 P0 I[initial_no_support_extruder] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M83\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\n;===== z ofst cali start =====\n\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n\n G383 O0 M2 T140\n M500\n\n;===== z ofst cali end =====\n\nG39.1 ; cali nozzle wrapped detection pos\nM500\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\n M500\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\nM400\n;M73 P99\n\nM1002 gcode_claim_action : 0\nM400\n\n;============switch again==================\n\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ==== \n {if (min_vitrification_temperature <= 70)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n\n", - "machine_end_gcode": ";===== date: 2025/05/27 =====================\n;===== H2D Pro =====================\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 0.5} F900 ; lower z a little\n\nG90\nM141 S0 ; turn off chamber heating\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 P9 S0 ; turn off ext toodhead cooling fan\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nM620 S65279\nT65279\nG150.2\nM621 S65279\n\nG150.3\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\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\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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 (max_layer_z + 100.0) < 320}\n G1 Z{max_layer_z + 100.0} F600\n G1 Z{max_layer_z +98.0}\n{else}\n G1 Z320 F600\n G1 Z320\n{endif}\nM400 P100\nM17 R ; restore z current\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.4 S0 K0 ;disable air printing detect\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", + "machine_start_gcode": ";===== machine: H2D Pro start ======\n;===== date: 20251104 =====================\n\n;M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\nM960 S10 P1 ; ext fan led\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM1002 set_gcode_claim_speed_level 5 ;Reset speed level\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z27 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140 A\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\n\nM972 S41 P0 T5000 ; trash can anti-collision\n\nM1009 Q1 L1\nG90\nG1 X175 Y160 F30000\nG28 Z P0 T250\nM1009 Q1 L0\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n\n T1001\n \n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A ; rise temp in advance\n\nM1002 judge_flag build_plate_detect_flag\nM622 S1\n M972 S19 P0 C0 ; heatbed presence detection\n M972 S31 P0 T5000 ; toolhead camera dirty detection\n M972 S34 P0 T5000 ; heatbed plate offset detection\nM623\n\n M972 S14 P0 ; nozzle type detection\n\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60*0.8} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n\nM620.11 P0 I[initial_no_support_extruder] E0\n\n{if long_retraction_when_ec }\nM620.11 K1 I[initial_no_support_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[initial_no_support_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n M620.11 S0 L0 I[initial_no_support_extruder] E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n{if (filament_type[initial_no_support_extruder] == \"PA\") || (filament_type[initial_no_support_extruder] == \"PA-GF\")}\n M620.11 S1 L0 I[initial_no_support_extruder] R4 D2 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{else}\n M620.11 S1 L0 I[initial_no_support_extruder] R10 D8 E-{retraction_distances_when_cut[initial_no_support_extruder]} F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60}\n{endif}\n{endif}\nM629\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M109 S{nozzle_temperature[initial_no_support_extruder]} ; wait tmpr to extrude\n M83\n {if(nozzle_diameter == 0.8)}\n G1 E60 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {else}\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n {endif}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140 A\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X175 Y160 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\n;===== z ofst cali start =====\n\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n\n G383 O0 M2 T140\n M500\n\n;===== z ofst cali end =====\n\nG39.1 ; cali nozzle wrapped detection pos\nM500\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\nG29.9\n\n;===== xy ofst cali start =====\n\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\n M500\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M500\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\nM400\n;M73 P99\n\nM1002 gcode_claim_action : 0\nM400\n\n;============switch again==================\n\nM211 X0 Y0 Z0 ;turn off soft endstop\nG91\nG1 Z6 F1200\nG90\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM620 S[initial_no_support_extruder]A\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM621 S[initial_no_support_extruder]A\n\n;============switch again==================\n\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n ;==== set ext toodhead cooling fan ==== \n {if (min_vitrification_temperature <= 50)}\n M106 P9 S255\n {endif}\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.02} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n\n", + "machine_end_gcode": ";======== H2D Pro end ========\n;===== date: 2025/11/11 =====\n\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nM400\nM211 Z1\nG1 Z{max_layer_z + 0.4} F900 ; lower z a little\n\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\nG90\nM141 S0 ; turn off chamber heating\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 P9 S0 ; turn off ext toodhead cooling fan\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nM620 S65279\nT65279\nG150.2\nM621 S65279\n\nG150.3\n\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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 (100.0 - max_layer_z/2) > 0}\n {if (max_layer_z + 100.0 - max_layer_z/2) < 320}\n G1 Z{max_layer_z + 100.0 - max_layer_z/2} F600\n G1 Z{max_layer_z + 98.0 - max_layer_z/2}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{else}\n {if (max_layer_z + 4.0) < 320}\n G1 Z{max_layer_z + 4.0} F600\n G1 Z{max_layer_z + 2.0}\n {else}\n G1 Z320 F600\n G1 Z320\n {endif}\n{endif}\nM400 P100\nM17 R ; restore z current\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.4 S0 K0 ;disable air printing detect\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", "layer_change_gcode": ";======== H2D Pro 20250725 layer_change ========\n; layer num/total_layer_count: {layer_num+1}/[total_layer_count]\n; update layer progress\nM73 L{layer_num+1}\nM991 S0 P{layer_num} ;notify layer change\n", - "time_lapse_gcode": ";======== H2D Pro 20250818========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firmware, default turned on\n\nM1002 judge_flag timelapse_record_flag\n\nM622 J1\nM993 A2 B2 C2\nM993 A0 B0 C0\n\n{if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n{endif}\n\n{if has_timelapse_safe_pos && timelapse_type == 0 && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} X{timelapse_pos_x} Y{timelapse_pos_y} Z{layer_z + 0.4} S11 C10 O0 T3000\n{else}\n {if spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z} S11 C10 O0 T3000\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + 0.4} S11 C10 O0 T3000\n {endif}\n{endif}\n\n{if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n{endif}\nM993 A3 B3 C3\n\nM623\n; SKIPPABLE_END\n", + "time_lapse_gcode": ";======== H2D Pro 20260612========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firmware, default turned on\n\nM1002 judge_flag timelapse_record_flag\nM622 J1\n {if !spiral_mode}\n M993 A2 B2 C2\n M993 A0 B0 C0\n {endif}\n\n {if timelapse_inline_photo}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M622.1 S0 ; for prev firmware, default turn off\n M1002 set_flag smooth_safe_pos_suppoprt_flag=1\n M1002 judge_flag smooth_safe_pos_suppoprt_flag\n \n M622 J0\n {if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if has_timelapse_safe_pos && timelapse_type == 0 && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} X{timelapse_pos_x} Y{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos && timelapse_type == 0) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n {endif}\n M623\n\n M622 J1\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if has_timelapse_safe_pos && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} U{timelapse_pos_x} V{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n M83\n {endif}\n {endif}\n M623\n {endif}\n \n {if !spiral_mode}\n M993 A3 B3 C3\n {endif}\nM623\n; SKIPPABLE_END\n", "wrapping_detection_gcode": ";======== H2D Pro 20250806 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 Y295 F30000\n G1 Y265 F18000\n \n M993 A3 B3 C3 ; nozzle cam detection allow status restore.\n {endif}\n M623\n{endif}\n", - "change_filament_gcode": ";======== H2D Pro filament ========\n;===== 20250725 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((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 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\"}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\n\nM400\n{if wipe_avoid_perimeter}\nG1 Y320 F30000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG1 Y295 F30000\nG1 Y265 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\nM1002 gcode_claim_action : 0" + "change_filament_gcode": ";======== H2D Pro filament ========\n;===== 20251031 =====\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\n{if ((filament_type[current_extruder] == \"PLA\") || (filament_type[current_extruder] == \"PLA-CF\") || (filament_type[current_extruder] == \"PETG\")) && (nozzle_diameter[current_extruder] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[current_extruder]} T{flush_temperatures[current_extruder]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60*0.8} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{endif}\n\n{if long_retraction_when_cut}\nM620.11 P1 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] R0\n{endif}\n\nM628 S1\n{if filament_type[current_extruder] == \"TPU\"}\nM620.11 S0 L0 I[current_extruder] E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\n{if (filament_type[current_extruder] == \"PA\") || (filament_type[current_extruder] == \"PA-GF\")}\nM620.11 S1 L0 I[current_extruder] R4 D2 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 S1 L0 I[current_extruder] R10 D8 E-{retraction_distances_when_cut[current_extruder]} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{endif}\n{endif}\nM629\n\n{if filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\"}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\nT[next_extruder]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if (filament_type[next_extruder] == \"PA\") || (filament_type[next_extruder] == \"PA-GF\")}\n;VG1 E1 F{max(new_filament_e_feedrate, 200)}\n;VG1 E1 F{max(new_filament_e_feedrate/2, 100)}\n{else}\n;VG1 E4 F{max(new_filament_e_feedrate, 200)}\n;VG1 E4 F{max(new_filament_e_feedrate/2, 100)}\n{endif}\n{endif}\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\n\nM400\n{if wipe_avoid_perimeter}\nG1 Y320 F30000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG1 Y295 F30000\nG1 Y265 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\nM1002 gcode_claim_action : 0", + "deretraction_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2", + "2" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1", + "1" + ], + "retraction_length": [ + "0.8", + "0.8", + "0.8", + "0.8", + "0.8" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow,Direct Drive TPU High Flow" + ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.6 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.6 nozzle.json index ad3162398d..218506fbfa 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.6 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.6 nozzle.json @@ -24,6 +24,7 @@ "1.4", "1.4", "1.4", + "1.4", "1.4" ], "upward_compatible_machine": [ diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.8 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.8 nozzle.json index 831155bd1b..6722650b46 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.8 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D Pro 0.8 nozzle.json @@ -31,5 +31,297 @@ ], "upward_compatible_machine": [ "Bambu Lab H2D 0.8 nozzle" + ], + "deretraction_speed": [ + "30", + "30", + "30", + "30" + ], + "hotend_cooling_rate": [ + "2", + "2", + "2", + "2" + ], + "hotend_heating_rate": [ + "3.6", + "3.6", + "3.6", + "3.6" + ], + "long_retractions_when_cut": [ + "0", + "0", + "0", + "0" + ], + "machine_max_acceleration_e": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_extruding": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_retracting": [ + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "machine_max_acceleration_travel": [ + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000", + "9000" + ], + "machine_max_acceleration_x": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_y": [ + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000", + "20000" + ], + "machine_max_acceleration_z": [ + "500", + "500", + "500", + "500", + "500", + "500", + "500", + "500" + ], + "machine_max_jerk_e": [ + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5", + "2.5" + ], + "machine_max_jerk_x": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_y": [ + "9", + "9", + "9", + "9", + "9", + "9", + "9", + "9" + ], + "machine_max_jerk_z": [ + "3", + "3", + "3", + "3", + "3", + "3", + "3", + "3" + ], + "machine_max_speed_e": [ + "50", + "50", + "50", + "50", + "50", + "50", + "50", + "50" + ], + "machine_max_speed_x": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_y": [ + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000", + "1000" + ], + "machine_max_speed_z": [ + "30", + "30", + "30", + "30", + "30", + "30", + "30", + "30" + ], + "nozzle_flush_dataset": [ + "1", + "2", + "1", + "2" + ], + "nozzle_type": [ + "hardened_steel", + "hardened_steel", + "hardened_steel", + "hardened_steel" + ], + "nozzle_volume": [ + "130", + "133", + "145", + "148" + ], + "printer_extruder_id": [ + "1", + "1", + "2", + "2" + ], + "printer_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow" + ], + "retract_before_wipe": [ + "0%", + "0%", + "0%", + "0%" + ], + "retract_length_toolchange": [ + "2", + "2", + "2", + "2" + ], + "retract_lift_above": [ + "0", + "0", + "0", + "0" + ], + "retract_lift_below": [ + "319", + "319", + "319", + "319" + ], + "retract_restart_extra": [ + "0", + "0", + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "0", + "0", + "0", + "0" + ], + "retract_when_changing_layer": [ + "1", + "1", + "1", + "1" + ], + "retraction_distances_when_cut": [ + "10", + "10", + "10", + "10" + ], + "retraction_minimum_travel": [ + "1", + "1", + "1", + "1" + ], + "retraction_speed": [ + "30", + "30", + "30", + "30" + ], + "wipe": [ + "1", + "1", + "1", + "1" + ], + "wipe_distance": [ + "2", + "2", + "2", + "2" + ], + "z_hop": [ + "0.4", + "0.4", + "0.4", + "0.4" + ], + "z_hop_types": [ + "Auto Lift", + "Auto Lift", + "Auto Lift", + "Auto Lift" + ], + "extruder_variant_list": [ + "Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow" ] } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D Pro.json b/resources/profiles/BBL/machine/Bambu Lab H2D Pro.json index 7d291dd8b8..8fd12972e7 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D Pro.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D Pro.json @@ -11,5 +11,5 @@ "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "O1E", - "default_materials": "Bambu PLA Basic @BBL H2DP;Bambu PLA-CF @BBL H2DP;Bambu PETG Basic @BBL H2DP;Bambu ABS @BBL H2DP;Bambu PETG HF @BBL H2DP;Bambu PLA Silk @BBL H2DP;Bambu PLA Matte @BBL H2DP;Bambu PC @BBL H2DP;Bambu PA-CF @BBL H2DP" + "default_materials": "Bambu PLA Basic @BBL H2DP;Bambu PLA-CF @BBL H2DP;Bambu PETG Basic @BBL H2DP;Bambu ABS @BBL H2DP;Bambu PETG HF @BBL H2DP;Bambu PLA Silk @BBL H2DP;Bambu PLA Matte @BBL H2DP;Bambu PC @BBL H2DP;Bambu PA-CF @BBL H2DP;Bambu PLA Pure @BBL H2DP" } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2D.json b/resources/profiles/BBL/machine/Bambu Lab H2D.json index 7b18cd2fe9..9a277c4b7e 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2D.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2D.json @@ -12,5 +12,5 @@ "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "O1D", - "default_materials": "Bambu PLA Basic @BBL H2D;Bambu PLA-CF @BBL H2D;Bambu PETG Basic @BBL H2D;Bambu ABS @BBL H2D;Bambu PETG HF @BBL H2D;Bambu PLA Silk @BBL H2D;Bambu PLA Matte @BBL H2D;Bambu PC @BBL H2D;Bambu PA-CF @BBL H2D" + "default_materials": "Bambu PLA Basic @BBL H2D;Bambu PLA-CF @BBL H2D;Bambu PETG Basic @BBL H2D;Bambu ABS @BBL H2D;Bambu PETG HF @BBL H2D;Bambu PLA Silk @BBL H2D;Bambu PLA Matte @BBL H2D;Bambu PC @BBL H2D;Bambu PA-CF @BBL H2D;Bambu PLA Pure @BBL H2D" } diff --git a/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle.json index f203e20683..0a02a254f1 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2S 0.4 nozzle.json @@ -210,6 +210,7 @@ ], "support_air_filtration": "1", "support_chamber_temp_control": "1", + "support_cooling_filter": "1", "support_object_skip_flush": "1", "wipe_distance": [ "2", @@ -227,7 +228,7 @@ "Auto Lift", "Auto Lift" ], - "machine_start_gcode": ";===== machine: H2S =========================\n;===== date: 2025/08/06 =====================\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z22 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.3 F18000\nT1000 O0 ;Preventing 3D Print Misalignment After Laser Operations\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\nM972 S41 P0 T5000; trash can anti-collision\n\nG90\nG1 X170 Y160 F30000\n\nG28 Z P0 T250\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n\n \n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} ; rise temp in advance\n\n M972 S19 P0 C0 ; heatbed detection\n\n M972 S31 P0 T5000; Toolhead camera detection\n M972 S34 P0 T5000; Plate offset detection\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} 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\nM620.11 P0 I[initial_no_support_extruder] E0\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M83\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X275 Y300 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\n\nM1002 gcode_claim_action : 0\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n", + "machine_start_gcode": ";===== machine: H2S =========================\n;===== date: 2025/08/06 =====================\n\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\nM400\n;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B9 L99 C61 D9 M99 E61 F9 N99 \nM1006 A53 B9 L99 C53 D9 M99 E53 F9 N99 \nM1006 A56 B9 L99 C56 D9 M99 E56 F9 N99 \nM1006 A61 B18 L99 C61 D18 M99 E61 F18 N99 \nM1006 W\n;=====printer start sound ===================\n\n;===== reset machine status =================\nM204 S10000\nM630 S0 P0\n\nG90\nM17 D ; reset motor current to default\nM960 S5 P1 ; turn on logo lamp\nG90\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\nM73.2 R1.0 ;Reset left time magnitude\nG29.1 Z{+0.0} ; clear z-trim value first\nM983.1 M1 \nM901 D4\nM481 S0 ; turn off cutter pos comp\n;===== reset machine status =================\n\nM620 M ;enable remap\n\n;===== avoid end stop =================\nG91\nG380 S2 Z22 F1200\nG380 S2 Z-12 F1200\nG90\n;===== avoid end stop =================\n\n;==== set airduct mode ==== \n\n{if (overall_chamber_temperature >= 40)}\n\n M145 P1 ; set airduct mode to heating mode for heating\n M106 P2 S0 ; turn off auxiliary fan\n M106 P3 S0 ; turn off chamber fan\n\n{else}\n M145 P0 ; set airduct mode to cooling mode for cooling\n M106 P2 S178 ; turn on auxiliary fan for cooling\n M106 P3 S127 ; turn on chamber fan for cooling\n M140 S0 ; stop heatbed from heating\n\n M1002 gcode_claim_action : 29\n M191 S0 ; wait for chamber temp\n M106 P2 S0 ; turn off auxiliary fan\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 T40 U0.3 V0.5 W0.8 O40 ; set PLA/TPU ND0.2 chamber autocooling\n {else}\n M142 P1 R30 S40 T45 U0.3 V0.5 W0.8 O45; set PLA/TPU ND0.4 chamber autocooling\n {endif}\n {else}\n {if (!is_all_bbl_filament)}\n M142 P1 R35 S40 T45 U0.3 V0.5 W0.8 O45 L1 ; set third-party PETG chamber autocooling\n {else}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 T50 U0.3 V0.5 W0.8 O50 L1 ; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 T55 U0.3 V0.5 W0.8 O55 L1 ; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{if(cooling_filter_enabled)}\nM145.2 P0 F0\n{else}\nM145.2 P0 F1\n{endif}\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n\n M104 S140\n M140 S[bed_temperature_initial_layer_single]\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n ;===== set chamber temperature ==========\n\n;===== start to heat heatbead & hotend==========\n\n;====== cog noise reduction=================\nM982.2 S1 ; turn on cog noise reduction\n\n;===== first homing start =====\nM1002 gcode_claim_action : 13\n\nG28 X T300\n\nG150.3 F18000\nT1000 O0 ;Preventing 3D Print Misalignment After Laser Operations\n\nG150.1 F18000 ; wipe mouth to avoid filament stick to heatbed\nG150.3 F18000\nM400 P200\nM972 S24 P0 T2000\n{if curr_bed_type==\"Textured PEI Plate\"}\nM972 S26 P0 C0\n{else}\nM972 S36 P0 C0 X1\n{endif}\nM972 S35 P0 C0\nM972 S41 P0 T5000; trash can anti-collision\n\nG90\nG1 X170 Y160 F30000\n\nG28 Z P0 T250\n\n;===== first homing end =====\n\nM400\n;M73 P99\n\n;===== detection start =====\n\n \n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} ; rise temp in advance\n\n M972 S19 P0 C0 ; heatbed detection\n\n M972 S31 P0 T5000; Toolhead camera detection\n M972 S34 P0 T5000; Plate offset detection\n;===== detection end =====\n\nM400\n;M73 P99\n\n;===== prepare print temperature and material ==========\nM400\nM211 X0 Y0 Z0 ;turn off soft endstop\nM975 S1 ; turn on input shaping\n\nG29.2 S0 ; avoid invalid abl data\n\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} 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\nM620.11 P0 I[initial_no_support_extruder] E0\n\nM620 S[initial_no_support_extruder]A ; switch material if AMS exist\nM1002 gcode_claim_action : 4\nM1002 set_filament_type:UNKNOWN\nM400\nT[initial_no_support_extruder]\nM400\nM628 S0\nM629\nM400\nM1002 set_filament_type:{filament_type[initial_no_support_extruder]}\nM621 S[initial_no_support_extruder]A\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\nM400\nM106 P1 S0\n\nG29.2 S1\n;===== prepare print temperature and material ==========\n\nM400\n;M73 P99\n\n;===== auto extrude cali start =========================\nM975 S1\nM1002 judge_flag extrude_cali_flag\n\nM622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\nM623\n\nM622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\nM622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\nM623\n\n;===== auto extrude cali end =========================\n\n{if filament_type[initial_no_support_extruder] == \"TPU\"}\n G150.2\n G150.1\n G150.2\n G150.1\n G150.2\n G150.1\n{else}\n M106 P1 S0\n M400 S2\n M83\n G1 E45 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4053*60}\n G1 E-3 F1800\n M400 P500\n G150.2\n G150.1\n{endif}\n\nG91\nG1 Y-16 F12000 ; move away from the trash bin\nG90\n\nM400\n;M73 P99\n\n;===== wipe right nozzle start =====\n\nM1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n {if (overall_chamber_temperature >= 40)}\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder] - 80}\n {endif}\nM106 S255 ; turn on fan to cool the nozzle\n\n;===== wipe left nozzle end =====\n\nM400\n;M73 P99\n\n{if (overall_chamber_temperature >= 40)}\n M1002 gcode_claim_action : 49\n M191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\nM400\n;M73 P99\n\n;===== bed leveling ==================================\n\nM1002 judge_flag g29_before_print_flag\n\nM190 S[bed_temperature_initial_layer_single]; ensure bed temp\nM109 S140\nM106 S0 ; turn off fan , too noisy\n\nG91\nG1 Z5 F1200\nG90\nG1 X275 Y300 F30000\n\nM622 J1\n M1002 gcode_claim_action : 1\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n M400\n M500 ; save cali data\nM623\n \nM622 J2\n M1002 gcode_claim_action : 1\n {if has_tpu_in_first_layer}\n G29.20 A3\n G29 A1 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {else}\n G29.20 A4\n G29 A2 O X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]}\n {endif}\n M400\n M500 ; save cali data\nM623\n\nM622 J0\n G28\nM623\n\n;===== bed leveling end ================================\n\nM400\n;M73 P99\n\nM141 S[overall_chamber_temperature]\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n\n G90\n G1 Z5 F1200\n G1 X187 Y160 F20000\n T1000\n M400 P200\n\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n\n M970.3 Q0 A5 K0 O1\n M974 Q0 S2 P0\n\n M970.2 Q2 K0 W38 Z0.01\n M974 Q2 S2 P0\n M500\n\n M975 S1\n;===== mech mode sweep end =====\n\nM400\n;M73 P99\n\nG150.3 ; move to garbage can to wait for temp\nM1026\n\nM1002 gcode_claim_action : 0\nM400\n;M73 P99\n\n;===== wait temperature reaching the reference value =======\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} ; rise to print tmpr\n\nM140 S[bed_temperature_initial_layer_single] \nM190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off fan\n M106 P2 S0 ; turn off big fan\n\n ;============set motor current==================\n M400 S1\n\n;===== wait temperature reaching the reference value =======\n\nM400\n;M73 P99\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.01} ; for Textured PEI Plate\n {endif}\n \nG150.1\n\nM975 S1 ; turn on mech mode supression\nM983.4 S1 ; turn on deformation compensation \nG29.2 S1 ; turn on pos comp\nG29.7 S1\n\nG90\nG1 Z5 F1200\nG1 Y295 F30000\nG1 Y265 F18000\n\n;===== nozzle load line ===============================\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n G1 Z5 F1200\n G1 X270 Y-0.5 F60000\n G28.14\n G29.2 S0\n G91\n G1 Z0.8 F1200\n G90\n G1 X250 F60000\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M83\n G1 E5 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G1 X290 E20 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053*60}\n G91\n G3 Z0.4 I1.217 J0 P1 F60000\n G90\n M83\n G29.2 S1 ; ensure z comp turn on\n;===== noozle load line end ===========================\n\nM400\n;M73 P99\n\nM993 A1 B1 C1 ; nozzle cam detection allowed.\n\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n\nM620.6 I[initial_no_support_extruder] W1 ;enable ams air printing detect\n\nM211 Z1\nG29.99\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1;enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n", "machine_end_gcode": ";===== date: 2025/02/05 =====================\n;===== H2S =====================\nG392 S0 ;turn off nozzle clog detect\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if timelapse_type == 2}\nM991 S0 P-1 ;end timelapse immediately\n{endif}\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nG1 E-0.8 F1800 ; retract\nG1 Z{max_layer_z + 0.5} F900 ; lower z a little\n\nG90\nG150.3\n\n{if timelapse_type == 1}\nM991 S0 P-1 ;end timelapse at safe pos\n{endif}\n\nM141 S0 ; turn off chamber heating\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\n\n; pull back filament to AMS\nM620 S65535\nT65535\nG150.2\nM621 S65535\n\nG150.3\n\nM104 S0; turn off hotend\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 (max_layer_z + 100.0) < 320}\n G1 Z{max_layer_z + 100.0} F600\n G1 Z{max_layer_z +98.0}\n{else}\n G1 Z320 F600\n G1 Z320\n{endif}\nM400 P100\nM17 R ; restore z current\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.4 S0 K0 ;disable air printing detect\n;=====printer finish sound=========\nM17\nM400 S1\nM1006 S1\nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A53 B10 L99 C53 D10 M99 E53 F10 N99 \nM1006 A57 B10 L99 C57 D10 M99 E57 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A48 B10 L99 C48 D10 M99 E48 F10 N99 \nM1006 A0 B15 L0 C0 D15 M0 E0 F15 N0 \nM1006 A60 B10 L99 C60 D10 M99 E60 F10 N99 \nM1006 W\n;=====printer finish sound=========\nM400\nM18\n\n", "time_lapse_gcode": ";========Date 20250611========\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\nM400\n\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\n G150.3 ; move to garbage can\n M400\n\n M1004 S5 P1 ; external shutter\n M400 P300\n\n M971 S11 C10 O0\n M400 P350\n\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G1 Y295 F30000\n G1 Y265 F18000\n{endif}\nM623\n\n; SKIPPABLE_END\n", "change_filament_gcode": ";===== machine: H2S filament_change =====\n;===== date: 2025/08/14 =====\n\nM993 A2 B2 C2 ; nozzle cam detection allow status save.\nM993 A0 B0 C0 ; nozzle cam detection not allowed.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K0 ;disable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620 S[next_extruder]A\nM1002 gcode_claim_action : 4\nM204 S9000\n\nG1 Z{max_layer_z + 3.0} F1200\n\nM400\nM106 P1 S0\nM106 P2 S0\n\n{if toolchange_count == 2}\n; get travel path for change filament\n;M620.1 X[travel_point_1_x] Y[travel_point_1_y] F21000 P0\n;M620.1 X[travel_point_2_x] Y[travel_point_2_y] F21000 P1\n;M620.1 X[travel_point_3_x] Y[travel_point_3_y] F21000 P2\n{endif}\n\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\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\n{if long_retraction_when_cut}\nM620.11 P1 I[current_extruder] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 I[current_extruder] E0\n{endif}\n\n\n{if filament_type[current_extruder] == \"TPU\" || filament_type[next_extruder] == \"TPU\"}\nM620.11 H2 C331\n{else}\nM620.11 H0\n{endif}\n\nT[next_extruder]\n\n\n; VFLUSH_START\n\n{if flush_length>41.5}\n;VG1 E41.5 F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n;VG1 E{flush_length-41.5} F{new_filament_e_feedrate}\n{else}\n;VG1 E{flush_length} F{min(old_filament_e_feedrate,new_filament_e_feedrate)}\n{endif}\n\nSYNC T{ceil(flush_length / 125) * 5}\n\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_extruder]}\n\nM400\nM83\n{if next_extruder < 255}\n\nM620.10 R{retract_length_toolchange[filament_map[next_extruder]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\n\nM629\nM400\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\n\nM400\n{if wipe_avoid_perimeter}\nG1 Y320 F30000\nG1 X{wipe_avoid_pos_x} F30000\n{endif}\nG1 Y295 F30000\nG1 Y265 F18000\nG1 Z{max_layer_z + 3.0} F3000\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[default_acceleration]\n{endif}\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\nM621 S[next_extruder]A\n\nM993 A3 B3 C3 ; nozzle cam detection allow status restore.\n\n{if (filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PETG\")\n || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 ; disable E air printing detect\n{endif}\n\nM620.6 I[next_extruder] W1 ;enable ams air printing detect\nM1002 gcode_claim_action : 0\n" diff --git a/resources/profiles/BBL/machine/Bambu Lab H2S.json b/resources/profiles/BBL/machine/Bambu Lab H2S.json index f4400a1c07..11c2cde471 100644 --- a/resources/profiles/BBL/machine/Bambu Lab H2S.json +++ b/resources/profiles/BBL/machine/Bambu Lab H2S.json @@ -14,5 +14,5 @@ "family": "BBL-3DP", "machine_tech": "FFF", "model_id": "O1S", - "default_materials": "Bambu PLA Basic @BBL H2S;Bambu PLA Matte @BBL H2S;Bambu PLA Tough @BBL H2S;Bambu PLA Marble @BBL H2S;Bambu PLA Metal @BBL H2S;Bambu PLA Silk @BBL H2S;Bambu TPU 95A HF @BBL H2S;Bambu PETG Basic @BBL H2S" + "default_materials": "Bambu PLA Basic @BBL H2S;Bambu PLA Matte @BBL H2S;Bambu PLA Tough @BBL H2S;Bambu PLA Marble @BBL H2S;Bambu PLA Metal @BBL H2S;Bambu PLA Silk @BBL H2S;Bambu TPU 95A HF @BBL H2S;Bambu PETG Basic @BBL H2S;Bambu PLA Pure @BBL H2S" } diff --git a/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json index 6d7efbb11b..e7d011aa54 100644 --- a/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab P1S 0.4 nozzle.json @@ -28,6 +28,7 @@ "extruder_variant_list": [ "Direct Drive Standard,Direct Drive High Flow" ], + "fan_direction": "left", "long_retractions_when_cut": [ "0", "0" diff --git a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json index a8e9871954..d56f1094f8 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1 0.4 nozzle.json @@ -34,6 +34,7 @@ "extruder_variant_list": [ "Direct Drive Standard,Direct Drive High Flow" ], + "fan_direction": "left", "long_retractions_when_cut": [ "0", "0" diff --git a/resources/profiles/BBL/machine/Bambu Lab X1E 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X1E 0.4 nozzle.json index 455469bab7..4b2fe3c755 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X1E 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X1E 0.4 nozzle.json @@ -28,6 +28,7 @@ "extruder_variant_list": [ "Direct Drive Standard,Direct Drive High Flow" ], + "fan_direction": "left", "long_retractions_when_cut": [ "0", "0" diff --git a/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle.json b/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle.json index e2979da215..0c79b7fed0 100644 --- a/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle.json +++ b/resources/profiles/BBL/machine/Bambu Lab X2D 0.4 nozzle.json @@ -5,11 +5,11 @@ "from": "system", "setting_id": "GM045", "instantiation": "true", - "change_filament_gcode": "======== X2D filament_change gcode ==========\n;===== 2026/04/08 =====\n\nM620 S[next_extruder]A B H[next_hotend]\n;M204 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[old_filament_temp] 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[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_extruder] == \"PLA\") || (filament_type[next_extruder] == \"PLA-CF\") || (filament_type[next_extruder] == \"PETG\")) && (nozzle_diameter[next_extruder] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_extruder]/2.4053*60} L[flush_length] H{nozzle_diameter[next_extruder]} T{flush_temperatures[next_extruder]} P[new_filament_temp] S1\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_extruder]}\n\n{if long_retraction_when_cut}\nM620.11 P1 L0 I[current_extruder] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 P0 L0 I[current_extruder] B[current_hotend] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_extruder] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_extruder]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_extruder] B[current_hotend] R0\n{endif}\n\nM620.22 I[next_extruder] P1 ; enable remote extruder runout auto purge.\n \nT[next_extruder] H[next_hotend]\n\n;deretract\n{if filament_type[next_extruder] == \"TPU\"}\n{else}\n{if filament_type[next_extruder] == \"PA\"}\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 / 125) * 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\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_extruder]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_extruder]-1]}\n\nM400\n\nG1 Z{max_layer_z + 3.0} F3000\n\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\n\n\nM621 S[next_extruder]A B\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\nM1002 set_flag powerloss_resume_flag=0\nM623\n\nM620.6 I[next_extruder] H[next_hotend] W1 ;enable ams air printing detect\n\n{if (filament_type[next_extruder] == \"TPU\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[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\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[travel_acceleration]\n{endif}\n\nG1 Y256 F18000\n\n\n{if (overall_chamber_temperature < 40)}\n{if (layer_num + 1 <= close_additional_fan_first_x_layers[next_extruder])}\n M106 P2 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer fan\n\tM106 P10 S{first_x_layer_fan_speed[next_extruder]*255.0/100.0 };set first x_layer fan\n{elsif (layer_num + 1 < additional_fan_full_speed_layer[next_extruder] && additional_fan_full_speed_layer[next_extruder] > close_additional_fan_first_x_layers[next_extruder])}\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_additional_fan_first_x_layers[next_extruder]) / (additional_fan_full_speed_layer[next_extruder] - close_additional_fan_first_x_layers[next_extruder])) * 255.0/100.0}\n\tM106 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_additional_fan_first_x_layers[next_extruder]) / (additional_fan_full_speed_layer[next_extruder] - close_additional_fan_first_x_layers[next_extruder])) * 255.0/100.0}\n{else}\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter == 0.2)}\n M142 P1 R30 S35 U{max_additional_fan/100.0} V1.0 O40; 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 {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n{endif}\n{endif}\n;not set fan changing filament", - "layer_change_gcode": ";======== X2D layer_change gcode ==========\n;===== 2025/04/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{endif}\n{endif}\n\n{if (layer_num + 1 <= close_additional_fan_first_x_layers[current_extruder])}\n{if (overall_chamber_temperature < 40)}\n M106 P2 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}\n\tM106 P10 S{first_x_layer_fan_speed[current_extruder]*255.0/100.0}\n{endif}\n;not reset fan\n{elsif (layer_num + 1 < additional_fan_full_speed_layer[current_extruder] && additional_fan_full_speed_layer[current_extruder] > close_additional_fan_first_x_layers[current_extruder])}\n{if (overall_chamber_temperature < 40)}\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_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}\n\tM106 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_additional_fan_first_x_layers[current_extruder]) / (additional_fan_full_speed_layer[current_extruder] - close_additional_fan_first_x_layers[current_extruder])) * 255.0/100.0}\n{endif}\n;not reset fan\n{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_extruder] + 1, additional_fan_full_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 S35 U{max_additional_fan/100.0} V1.0 O40; 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 {if (nozzle_diameter == 0.2)}\n M142 P1 R35 S45 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R35 S50 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n{else}\n ;not reset filter fan in Xth layer\n{endif}\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\n", - "machine_end_gcode": ";======== X2D end gcode ==========\n;===== 2026/03/30 =====\n\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\nM141 S0 ; turn off chamber heating\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 remote part1 cooling fan\n\n; pull back filament to AMS\nM620 S65279 B\n; M620.11 P1 L0 I65279 E-3\nT65279\nG150.1 F8000\nM621 S65279 B\n\nM620 S65535 B\n; M620.11 P1 L0 I65535 E-4\nT65535\nG150.1 F8000\nM621 S65535 B\n\nG150.3\n\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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\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\nM622 J1\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P10 S255\nM400 S180\nM106 P10 S0\nM623\n\nM622 J2\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S255\nM400 S180\nM106 P3 S0\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\n", - "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== X2D start gcode==========\n;===== 2026/05/08 =====\n\n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n ;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50 \nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50 \nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50 \nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50 \nM1006 W\n;=====printer start sound ===================\n\n M1012.1 T1100\n M620 M ;enable remap\n M622.1 S0\n G383.4\n \n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n;===== reset machine status =================\n\n;==== set airduct mode ==== \n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S0 ; turn off auxiliary fan\nM106 P10 S255 ; turn on filter fan\n{else}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P10 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\n;M140 S0 ; stop heatbed from heating\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on auxiliary fan\nM106 P10 S102 ; turn on chamber fan\nM142 P6 R30 S40 U0.6 V0.8 ; set PLA/TPU/PETG exhaust chamber autocooling\n{endif}\n;==== set airduct mode ==== \n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]} \n \n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n;===== set chamber temperature ==========\n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300 R\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n M972 S26 P0 C0\n G90\n M83\n G1 Y128 F30000\n G1 X128\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n\n M104 S0 T0\n M104 S0 T1\n M562 P1 E0 B1\n M562 P2 E0 B1\n M18 E\n M400 P200\n M1028 S1\n M972 S19 P0 ;heatbed detection\n M972 S31 P0 ;toolhead camera dirt detection\n M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 ;print plate deviation detection\n M1028 S0\n M562 P1 E1 B1\n M562 P2 E1 B1\n M17 D\n\n ;M400\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} T{filament_map[initial_no_support_extruder] % 2} ; rise temp in advance\n G151 P{filament_map[initial_no_support_extruder] % 2} M ; plug the heat nozzle\n {if max_print_z >= 145}\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-40} A ; rise temp in advance\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n \n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG\")) && (nozzle_diameter[initial_no_support_extruder] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_extruder]/2.4053*60} H{nozzle_diameter[initial_no_support_extruder]} T{flush_temperatures[initial_no_support_extruder]} P{nozzle_temperature_initial_layer[initial_no_support_extruder]} S1\n{endif}\n \n M620.11 P0 L0 I[initial_no_support_extruder] B[initial_no_support_hotend] E0\n M620.11 K0 I[initial_no_support_extruder] B[initial_no_support_hotend] R0\n\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B ; switch material if AMS exist\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M621 S[initial_no_support_extruder]A B\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n\n M622 J2\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_extruder]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_extruder]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n G150.3\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_extruder]}\n {if bed_temperature_initial_layer_single > 89}\n {if overall_chamber_temperature < 40}\n M1030 S1200\n SYNC R0 T1200\n {else}\n M1030 S600\n SYNC R0 T600\n {endif} \n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n\n {if filament_type[current_extruder] == \"TPU\" || filament_type[current_extruder] == \"PVA\"}\n {else}\n M83\n G1 E-3 F1800\n M400 P500\n {endif}\n G150.2\n G150.1 F8000\n G150.2\n G150.1 F8000\n\n G91\n G1 Y-16 F12000 ; move away from the trash bin\n G90\n M400\n\n M104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n M400\n;===== wipe left nozzle end =====\n\n{if filament_type[current_extruder] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n M106 S0 ; turn off fan , too noisy\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n\n{if (overall_chamber_temperature >= 40)}\nM1002 gcode_claim_action : 49\nM191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\n;===== z ofst cali start =====\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n G383 O0 M1 T140\n M400\n;===== z ofst cali end =====\nG90\nM83\nG0 Y200 F18000\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n \n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n\n M622 J0\n G28 R\n M623\n G29.2 S1\n;===== bed leveling end ================================\n\n; cali eddy z pos\n;G383.13 T1 C1\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_extruder]} A\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\nM104 S[nozzle_temperature_initial_layer] A\nG150.3\nM400 P50\n M500 D1\n M400 S3\n;===== xy ofst cali start =====\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : first_filaments[0])}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : first_filaments[1])}\n M620 D[initial_no_support_hotend]\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_extruder]} L{initial_no_support_extruder}\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\n M104 S[nozzle_temperature_initial_layer] A\n\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M140 S[bed_temperature_initial_layer_single] \n M190 S[bed_temperature_initial_layer_single] \n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n \n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n M983.4 S0 ; turn off deformation compensation \n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_extruder]}\n M620 S[initial_no_support_extruder]A H[initial_no_support_hotend] B\n M620.22 I[initial_no_support_extruder] P1 ; enable remote extruder runout auto purge.\n M400\n T[initial_no_support_extruder] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_extruder]A B\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 70}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.003} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.017}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.002} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.022}\n {endif}\n {endif}\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M109 S{nozzle_temperature_initial_layer[initial_no_support_extruder]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_extruder]/2/2.4053} L40 E12 D4\nG90\n G90\n M83\n G1 Z1\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n;M993 A1 B1 C1 ; nozzle cam detection allowed.\n\nM620.6 I[initial_no_support_extruder] H[initial_no_support_hotend] W1 ;enable ams air printing detect\n\n\n{if (filament_type[initial_no_support_extruder] == \"TPU\")}\nM1015.3 S1 H[nozzle_diameter];enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_extruder] == \"PLA\") || (filament_type[initial_no_support_extruder] == \"PETG\")\n || (filament_type[initial_no_support_extruder] == \"PLA-CF\") || (filament_type[initial_no_support_extruder] == \"PETG-CF\")}\nM1015.4 S1 K1 H[nozzle_diameter] ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H[nozzle_diameter] ;disable E air printing detect\n{endif}\n", - "time_lapse_gcode": ";======== X2D timelapse gcode ========\n;======== 2025/08/15 ========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firware, default turned on\n\nM1002 judge_flag timelapse_record_flag\n\nM622 J1\n\n{if !spiral_mode && !(has_timelapse_safe_pos && print_sequence != \"by object\") }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n{endif}\n\n{if has_timelapse_safe_pos && print_sequence != \"by object\"}\nM9711 M{timelapse_type} E{most_used_physical_extruder_id} X{timelapse_pos_x} Y{timelapse_pos_y} Z{layer_z + 0.4} S11 C10 O0 T3000\n{else}\nM9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + 0.4} S11 C10 O0 T3000\n{endif}\n\n{if !spiral_mode && !(has_timelapse_safe_pos && print_sequence != \"by object\") }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n M83\n G1 Z{max_layer_z + 3.0} F1200\n G0 F18000\n {endif}\n{endif}\n\nM623\n; SKIPPABLE_END\n", + "change_filament_gcode": "======== X2D filament_change gcode ==========\n;===== 2026/07/01 =====\n\nM620 S[next_filament_id]A B H[next_hotend]\n;M204 S9000\n{if toolchange_count > 1 && (z_hop_types[current_filament_id] == 0 || z_hop_types[current_filament_id] == 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_filament_id] == \"PLA\") || (filament_type[current_filament_id] == \"PLA-CF\") || (filament_type[current_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[current_filament_id]/2.4053*60} L[flush_length] H{nozzle_diameter_at_nozzle_id[current_nozzle_id]} T{flush_temperatures[current_filament_id]} P[old_filament_temp] S1\n{endif}\n\n{if ((filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[next_nozzle_id] == 0.2)}\nM620.10 A1 F74.8347 L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{else}\nM620.10 A1 F{flush_volumetric_speeds[next_filament_id]/2.4053*60} L[flush_length] H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} T{flush_temperatures[next_filament_id]} P[new_filament_temp] S1\n{endif}\n\nM620.15 C{new_filament_temp - filament_cooling_before_tower[next_filament_id]}\n\n{if long_retraction_when_cut}\nM620.11 P1 L0 I[current_filament_id] B[current_hotend] E-{retraction_distance_when_cut} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 P0 L0 I[current_filament_id] B[current_hotend] E0\n{endif}\n\n{if long_retraction_when_ec}\nM620.11 K1 I[current_filament_id] B[current_hotend] R{retraction_distance_when_ec} F{max((flush_volumetric_speeds[current_filament_id]/2.4053*60), 200)}\n{else}\nM620.11 K0 I[current_filament_id] B[current_hotend] R0\n{endif}\n\nM620.22 I[next_filament_id] P1 ; enable remote extruder runout auto purge.\n\nT[next_filament_id] H[next_hotend]\n\n;deretract\n{if filament_type[next_filament_id] == \"TPU\"}\n{else}\n{if filament_type[next_filament_id] == \"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 / 125) * 5}\n; VFLUSH_END\n\nM1002 set_filament_type:{filament_type[next_filament_id]}\n\nM400\nM83\n{if next_filament_id < 255}\nM620.10 R{retract_length_toolchange[filament_map[next_filament_id]-1]}\nM628 S0\n;VM109 S[new_filament_temp]\nM629\nM400\n\n;prime_tower_interface\n{if is_prime_tower_interface && filament_tower_interface_purge_volume !=0}\nG150.1\nM620.13 W0 L{filament_tower_interface_purge_volume} T{filament_tower_interface_print_temp} R0.0\n{endif}\n;prime_tower_interface\n\nM983.3 F{filament_max_volumetric_speed[next_filament_id]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_filament_id]-1]}\n\nM400\n\nG1 Z{max_layer_z + 3.0} F3000\n\n{else}\nG1 X[x_after_toolchange] Y[y_after_toolchange] Z[z_after_toolchange] F12000\n{endif}\n\n\nM621 S[next_filament_id]A B\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_filament_id]/2.4} A0.4 R{retract_length_toolchange[filament_map[next_filament_id]-1]}\nM400\nG1 Z{max_layer_z + 3.0} F3000\nM1002 set_flag powerloss_resume_flag=0\nM623\n\nM620.6 I[next_filament_id] H[next_hotend] W1 ;enable ams air printing detect\n\n{if (filament_type[next_filament_id] == \"TPU\")}\nM1015.3 S1 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]};enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[next_filament_id] == \"PLA\") || (filament_type[next_filament_id] == \"PETG\")\n || (filament_type[next_filament_id] == \"PLA-CF\") || (filament_type[next_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H{nozzle_diameter_at_nozzle_id[next_nozzle_id]} ;disable E air printing detect\n{endif}\n\n{if layer_z <= (initial_layer_print_height + 0.001)}\nM204 S[initial_layer_acceleration]\n{else}\nM204 S[travel_acceleration]\n{endif}\n\nG1 Y256 F18000\n\n\n{if (overall_chamber_temperature < 40)}\n{if (layer_num + 1 <= close_additional_fan_first_x_layers[next_filament_id])}\n M106 P2 S{first_x_layer_fan_speed[next_filament_id]*255.0/100.0 };set first x_layer fan\n\tM106 P10 S{first_x_layer_fan_speed[next_filament_id]*255.0/100.0 };set first x_layer fan\n{elsif (layer_num + 1 < additional_fan_full_speed_layer[next_filament_id] && additional_fan_full_speed_layer[next_filament_id] > close_additional_fan_first_x_layers[next_filament_id])}\n M106 P2 S{(first_x_layer_fan_speed[next_filament_id] + (additional_cooling_fan_speed[next_filament_id] - first_x_layer_fan_speed[next_filament_id]) * (layer_num + 1 - close_additional_fan_first_x_layers[next_filament_id]) / max(additional_fan_full_speed_layer[next_filament_id] - close_additional_fan_first_x_layers[next_filament_id], 1)) * 255.0/100.0}\n\tM106 P10 S{(first_x_layer_fan_speed[next_filament_id] + (additional_cooling_fan_speed[next_filament_id] - first_x_layer_fan_speed[next_filament_id]) * (layer_num + 1 - close_additional_fan_first_x_layers[next_filament_id]) / max(additional_fan_full_speed_layer[next_filament_id] - close_additional_fan_first_x_layers[next_filament_id], 1)) * 255.0/100.0}\n{else}\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 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 {if (!is_all_bbl_filament)}\n M142 P1 R40 S45 U{max_additional_fan/100.0} V0.5 O50; set third-party PETG chamber \n {else}\n {if (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 0.2)}\n M142 P1 R45 S50 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R50 S55 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{endif}\n{endif}\n;not set fan changing filament", + "layer_change_gcode": ";======== X2D layer_change gcode ==========\n;===== 2026/07/01 =====\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{endif}\n{endif}\n\n{if (layer_num + 1 <= close_additional_fan_first_x_layers[current_filament_id])}\n{if (overall_chamber_temperature < 40)}\n M106 P2 S{first_x_layer_fan_speed[current_filament_id]*255.0/100.0}\n\tM106 P10 S{first_x_layer_fan_speed[current_filament_id]*255.0/100.0}\n{endif}\n;not reset fan\n{elsif (layer_num + 1 < additional_fan_full_speed_layer[current_filament_id] && additional_fan_full_speed_layer[current_filament_id] > close_additional_fan_first_x_layers[current_filament_id])}\n{if (overall_chamber_temperature < 40)}\n M106 P2 S{(first_x_layer_fan_speed[current_filament_id] + (additional_cooling_fan_speed[current_filament_id] - first_x_layer_fan_speed[current_filament_id]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_filament_id]) / max(additional_fan_full_speed_layer[current_filament_id] - close_additional_fan_first_x_layers[current_filament_id], 1)) * 255.0/100.0}\n\tM106 P10 S{(first_x_layer_fan_speed[current_filament_id] + (additional_cooling_fan_speed[current_filament_id] - first_x_layer_fan_speed[current_filament_id]) * (layer_num + 1 - close_additional_fan_first_x_layers[current_filament_id]) / max(additional_fan_full_speed_layer[current_filament_id] - close_additional_fan_first_x_layers[current_filament_id], 1)) * 255.0/100.0}\n{endif}\n;not reset fan\n{elsif (layer_num + 1 == max(close_additional_fan_first_x_layers[current_filament_id] + 1, additional_fan_full_speed_layer[current_filament_id]))}\n{if (overall_chamber_temperature < 40)}\n ;updata chamber autocooling in Xth layer\n {if (min_vitrification_temperature <= 50)}\n {if (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 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 {if (!is_all_bbl_filament)}\n M142 P1 R40 S45 U{max_additional_fan/100.0} V0.5 O50; set third-party PETG chamber \n {else}\n {if (nozzle_diameter_at_nozzle_id[current_nozzle_id] == 0.2)}\n M142 P1 R45 S50 U{max_additional_fan/100.0} V0.5 O50; set PETG ND0.2 chamber autocooling\n {else}\n M142 P1 R50 S55 U{max_additional_fan/100.0} V0.5 O55; set PETG ND0.4 chamber autocooling\n {endif}\n {endif}\n {endif}\n{else}\n ;not reset filter fan in Xth layer\n{endif}\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\n", + "machine_end_gcode": ";======== X2D end gcode ==========\n;===== 2026/05/18 =====\n\nM400 ; wait for buffer to clear\nG92 E0 ; zero the extruder\nM211 Z1\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\nM141 S0 ; turn off chamber heating\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 remote part1 cooling fan\n\n; pull back filament to AMS\nM620 S65279 B\n; M620.11 P1 L0 I65279 E-3\nT65279\nG150.1 F8000\nM621 S65279 B\n\nM620 S65535 B\n; M620.11 P1 L0 I65535 E-4\nT65535\nG150.1 F8000\nM621 S65535 B\n\nG150.3\n\nM104 S0 T0; turn off hotend\nM104 S0 T1; turn off hotend\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\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\nM622 J1\nM1002 gcode_claim_action : 66\nM145 P1\nM106 P10 S255\nM400 S180\nM106 P10 S0\nM623\n\nM622 J2\nM1002 gcode_claim_action : 66\nM145 P0\nM106 P3 S255\nM400 S180\nM106 P3 S0\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\n", + "machine_start_gcode": ";M1002 set_flag extrude_cali_flag=1\n;M1002 set_flag g29_before_print_flag=1\n;M1002 set_flag auto_cali_toolhead_offset_flag=1\n;M1002 set_flag build_plate_detect_flag=1\n\n;======== X2D start gcode==========\n;===== 2026/06/05 =====\n\n M140 S[bed_temperature_initial_layer_single] ; heat heatbed first\n M993 A0 B0 C0 ; nozzle cam detection not allowed.\n M400\n ;M73 P99\n\n;=====printer start sound ===================\nM17\nM400 S1\nM1006 S1\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50\nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50\nM1006 A61 B9 L50 C61 D9 M50 E61 F9 N50\nM1006 A53 B9 L50 C53 D9 M50 E53 F9 N50\nM1006 A56 B9 L50 C56 D9 M50 E56 F9 N50\nM1006 A61 B18 L50 C61 D18 M50 E61 F18 N50\nM1006 W\n;=====printer start sound ===================\n\n M1012.1 T1100\n M620 M ;enable remap\n M622.1 S0\n G383.4\n\n;===== avoid end stop =================\n G91\n G380 S2 Z22 F1200\n G380 S2 Z-12 F1200\n G90\n;===== avoid end stop =================\n\n;===== reset machine status =================\n M204 S10000\n M630 S0 P1\n G90\n M17 D ; reset motor current to default\n M960 S5 P1 ; turn on logo lamp\n M220 S100 ;Reset Feedrate\n M1002 set_gcode_claim_speed_level: 5\n M221 S100 ;Reset Flowrate\n M73.2 R1.0 ;Reset left time magnitude\n G29.1 Z{+0.0} ; clear z-trim value first\n M983.1 M1\n M982.2 S1 ; turn on cog noise reduction\n;===== reset machine status =================\n\n;==== set airduct mode ====\n{if (overall_chamber_temperature >= 40)}\nM145 P1 ; set airduct mode to heating mode for heating\nM106 P2 S0 ; turn off auxiliary fan\nM106 P10 S255 ; turn on filter fan\n{else}\nM145 P0 ; set airduct mode to cooling mode for cooling\nM106 P2 S255 ; turn on auxiliary fan for cooling\nM106 P10 S255 ; turn on auxiliary fan for cooling\nM106 P3 S127 ; turn on chamber fan for cooling\n;M140 S0 ; stop heatbed from heating\nM1002 gcode_claim_action : 29\nM191 S0 ; wait for chamber temp\nM106 P2 S102 ; turn on auxiliary fan\nM106 P10 S102 ; turn on chamber fan\nM142 P6 R30 S40 U0.6 V0.8 ; set PLA/TPU/PETG exhaust chamber autocooling\n{endif}\n;==== set airduct mode ====\n\n;===== start to heat heatbed & hotend==========\n M1002 gcode_claim_action : 2\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n\n ;===== set chamber temperature ==========\n {if (overall_chamber_temperature >= 40)}\n M145 P1 ; set airduct mode to heating mode\n M141 S[overall_chamber_temperature] ; Let Chamber begin to heat\n {endif}\n;===== set chamber temperature ==========\n\n G29.2 S0 ; avoid invalid abl data\n\n;===== first homing start =====\n M1002 gcode_claim_action : 13\n G28 X T300 R\n G150.1 F8000 ; wipe mouth to avoid filament stick to heatbed\n G150.3\n M972 S24 P0\n M1002 gcode_claim_action : 74 ; Heatbed surface foreign object detection\n M972 S26 P0 C0\n G90\n M83\n G1 Y128 F30000\n G1 X128\n G28 Z P0 T400\n M400\n;===== first homign end =====\n\n;===== detection start =====\n M1002 gcode_claim_action : 11\n\n M104 S0 T0\n M104 S0 T1\n M562 P1 E0 B1\n M562 P2 E0 B1\n M18 E\n M400 P200\n M1028 S1\n M972 S19 P0 ;heatbed detection\n M972 S31 P0 ;toolhead camera dirt detection\n M1002 gcode_claim_action : 73 ; Build plate alignment detection\n M972 S34 P0 ;print plate deviation detection\n M1028 S0\n M562 P1 E1 B1\n M562 P2 E1 B1\n M17 D\n\n ;M400\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]} T{filament_map[initial_no_support_filament_id] % 2} ; rise temp in advance\n\n {if max_print_z >= 145}\n G151 P{filament_map[initial_no_support_filament_id] % 2} M ; plug the heat nozzle\n M1002 gcode_claim_action : 75 ; Detect obstacles at the botton of the heated bed\n G3811 Z{max_print_z} ; Detect obstacles at the bottom of the heated bed\n {endif}\n;===== detection end =====\n\n;===== prepare print temperature and material ==========\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]-40} A ; rise temp in advance\n M400\n M211 X0 Y0 Z0 ;turn off soft endstop\n M975 S1 ; turn on input shaping\n\n G29.2 S0 ; avoid invalid abl data\n G150.3\n{if ((filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG\")) && (nozzle_diameter_at_nozzle_id[initial_nozzle_id] == 0.2)}\nM620.10 A0 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F74.8347 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{else}\nM620.10 A0 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\nM620.10 A1 F{flush_volumetric_speeds[initial_no_support_filament_id]/2.4053*60} H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} T{flush_temperatures[initial_no_support_filament_id]} P{nozzle_temperature_initial_layer[initial_no_support_filament_id]} S1\n{endif}\n\n M620.11 P0 L0 I[initial_no_support_filament_id] B[initial_no_support_hotend] E0\n M620.11 K0 I[initial_no_support_filament_id] B[initial_no_support_hotend] R0\n\n M620 S[initial_no_support_filament_id]A H[initial_no_support_hotend] B ; switch material if AMS exist\n M620.22 I[initial_no_support_filament_id] P1 ; enable remote extruder runout auto purge.\n M1002 gcode_claim_action : 4\n M1002 set_filament_type:UNKNOWN\n M400\n T[initial_no_support_filament_id] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M621 S[initial_no_support_filament_id]A B\n M104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M400\n M106 P1 S0\n M400\n G29.2 S1\n;===== prepare print temperature and material ==========\n\n;===== auto extrude cali start =========================\n M975 S1\n M1002 judge_flag extrude_cali_flag\n M622 J0\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n M623\n\n M622 J1\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/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_filament_id]}\n M1002 gcode_claim_action : 8\n M109 S{nozzle_temperature[initial_no_support_filament_id]}\n G90\n M83\n M983.3 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2.4} A0.4 ; cali dynamic extrusion compensation\n M400\n M106 P1 S255\n M400 S5\n M106 P1 S0\n G150.3\n M623\n;===== auto extrude cali end =========================\n\n {if hold_chamber_temp_for_flat_print}\n G150.3\n M1002 gcode_claim_action : 58\n M104 S{first_layer_temperature[initial_no_support_filament_id]}\n {if bed_temperature_initial_layer_single > 89}\n {if overall_chamber_temperature < 40}\n M1030 S1200\n SYNC R0 T1200\n {else}\n M1030 S600\n SYNC R0 T600\n {endif}\n {else}\n M1030 S300\n SYNC R0 T300\n {endif}\n M1030 C\n {endif}\n\n {if filament_type[initial_filament_id] == \"TPU\" || filament_type[initial_filament_id] == \"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_filament_id]-80} A\n\n;===== wipe right nozzle start =====\n M1002 gcode_claim_action : 14\n G150 T{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n M400\n;===== wipe left nozzle end =====\n\n{if filament_type[initial_filament_id] == \"PC\"}\n M109 S170 A\n{else}\n M109 S140 A\n{endif}\n M106 S0 ; turn off fan , too noisy\n G91\n G1 Z5 F1200\n G90\n M400\n G150.1\n\n{if (overall_chamber_temperature >= 40)}\nM1002 gcode_claim_action : 49\nM191 S[overall_chamber_temperature] ; wait for chamber temp\n{endif}\n\n;===== z ofst cali start =====\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n G383 O0 M1 T140\n M400\n;===== z ofst cali end =====\nG90\nM83\nG0 Y200 F18000\n\n;===== bed leveling ==================================\n M1002 gcode_claim_action : 54\n M190 S[bed_temperature_initial_layer_single]; ensure bed temp\n M109 S140 A\n M106 S0 ; turn off fan , too noisy\n M1002 judge_flag g29_before_print_flag\n M622 J1\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A1 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n\n M622 J2\n M1002 gcode_claim_action : 1\n {if hold_chamber_temp_for_flat_print}\n G29 H R\n {else}\n G29 A2 X{first_layer_print_min[0]} Y{first_layer_print_min[1]} I{first_layer_print_size[0]} J{first_layer_print_size[1]} R\n {endif}\n M400\n M623\n\n M622 J0\n G28 R\n M623\n G29.2 S1\n;===== bed leveling end ================================\n\n; cali eddy z pos\n;G383.13 T1 C1\n\nM104 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]} A\n;===== mech mode sweep start =====\n M1002 gcode_claim_action : 3\n G90\n G1 X128 Y128 F20000\n G1 Z5 F1200\n M400 P200\n M970.3 Q1 A5 K0 O1\n M974 Q1 S2 P0\n M970.3 Q0 A7 K0 O1\n M970.2 Q0 W73 K1 Z0.01\n M974 Q0 S2 P0\n M975 S1\n M400\n;===== mech mode sweep end =====\n\nM104 S{nozzle_temperature_initial_layer[initial_filament_id]} A\nG150.3\n\n;===== xy ofst cali start =====\nM1002 judge_flag auto_cali_toolhead_offset_flag\n\nM622 J0\n M1012.5 N1 R1\nM623\n\nM622 J1\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : (first_filaments[0] != -1 ? first_filaments[0] : 0))]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : (first_filaments[0] != -1 ? first_filaments[0] : 0))}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : (first_filaments[1] != -1 ? first_filaments[1] : 0))]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : (first_filaments[1] != -1 ? first_filaments[1] : 0))}\n M620 D[initial_no_support_hotend]\n G383 O1 T{nozzle_temperature_initial_layer[initial_no_support_filament_id]} L{initial_no_support_filament_id}\n M141 S[overall_chamber_temperature]\nM623\n\nM622 J2\n M1002 gcode_claim_action : 39\n M141 S0\n M620.17 T0 S{nozzle_temperature_initial_layer[(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : (first_filaments[0] != -1 ? first_filaments[0] : 0))]} L{(first_non_support_filaments[0] != -1 ? first_non_support_filaments[0] : (first_filaments[0] != -1 ? first_filaments[0] : 0))}\n M620.17 T1 S{nozzle_temperature_initial_layer[(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : (first_filaments[1] != -1 ? first_filaments[1] : 0))]} L{(first_non_support_filaments[1] != -1 ? first_non_support_filaments[1] : (first_filaments[1] != -1 ? first_filaments[1] : 0))}\n M620 D[initial_no_support_hotend]\n G383.3 T{nozzle_temperature_initial_layer[initial_no_support_filament_id]} L{initial_no_support_filament_id}\n M141 S[overall_chamber_temperature]\nM623\n;===== xy ofst cali end =====\n\n M104 S{nozzle_temperature_initial_layer[initial_filament_id]} A\n\n G150.3 ; move to garbage can to wait for temp\n\n;===== wait temperature reaching the reference value =======\n M140 S[bed_temperature_initial_layer_single]\n M190 S[bed_temperature_initial_layer_single]\n\n ;========turn off light and fans =============\n M960 S1 P0 ; turn off laser\n M960 S2 P0 ; turn off laser\n M106 S0 ; turn off cooling fan\n\n;===== wait temperature reaching the reference value =======\n\n M1002 gcode_claim_action : 255\n M400\n M975 S1 ; turn on mech mode supression\n M983.4 S0 ; turn off deformation compensation\n\n;============switch again==================\n M211 X0 Y0 Z0 ;turn off soft endstop\n G91\n G1 Z6 F1200\n G90\n M1002 set_filament_type:{filament_type[initial_no_support_filament_id]}\n M620 S[initial_no_support_filament_id]A H[initial_no_support_hotend] B\n M620.22 I[initial_no_support_filament_id] P1 ; enable remote extruder runout auto purge.\n M400\n T[initial_no_support_filament_id] H[initial_no_support_hotend]\n M400\n M628 S0\n M629\n M400\n M621 S[initial_no_support_filament_id]A B\n;============switch again==================\n\n;===== for Textured PEI Plate , lower the nozzle as the nozzle was touching topmost of the texture when homing ==\n {if bed_temperature_initial_layer_single > 70}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{-0.003} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.017}\n {endif}\n {else}\n {if curr_bed_type==\"Textured PEI Plate\"}\n G29.1 Z{0.002} ; for Textured PEI Plate\n {else}\n G29.1 Z{0.022}\n {endif}\n {endif}\n\n;===== nozzle load line ===============================\nM1002 gcode_claim_action : 51\n G29.2 S1 ; ensure z comp turn on\n G90\n M83\n M400 P50\n M500 D1\n M400 S3\n M109 S{nozzle_temperature_initial_layer[initial_no_support_filament_id]}\n G0 X100 Y0 F24000\n M400\n ;G130 O0 X100 Y-0.4 Z0.6 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2/2.4053} L40 E20 D5\n G130 O0 X100 Y-0.2 Z0.6 F{filament_max_volumetric_speed[initial_no_support_filament_id]/2/2.4053} L40 E12 D4\nG90\n G90\n M83\n G1 Z1\n M400\n;===== noozle load line end ===========================\nM1002 gcode_claim_action : 0\n G29.99\n\n;M993 A1 B1 C1 ; nozzle cam detection allowed.\n\nM620.6 I[initial_no_support_filament_id] H[initial_no_support_hotend] W1 ;enable ams air printing detect\n\n\n{if (filament_type[initial_no_support_filament_id] == \"TPU\")}\nM1015.3 S1 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]};enable tpu clog detect\n{else}\nM1015.3 S0;disable tpu clog detect\n{endif}\n\n{if (filament_type[initial_no_support_filament_id] == \"PLA\") || (filament_type[initial_no_support_filament_id] == \"PETG\")\n || (filament_type[initial_no_support_filament_id] == \"PLA-CF\") || (filament_type[initial_no_support_filament_id] == \"PETG-CF\")}\nM1015.4 S1 K1 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;enable E air printing detect\n{else}\nM1015.4 S0 K0 H{nozzle_diameter_at_nozzle_id[initial_nozzle_id]} ;disable E air printing detect\n{endif}\n\n", + "time_lapse_gcode": ";======== X2D timelapse gcode ========\n;======== 2026/06/03 ========\n; SKIPPABLE_START\n; SKIPTYPE: timelapse\nM622.1 S1 ; for prev firware, default turned on\n\nM1002 judge_flag timelapse_record_flag\n\nM622 J1\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n M83\n G1 Z{max_layer_z + 0.4} F1200\n M400\n {endif}\n {endif}\n\n {if timelapse_inline_photo}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {elsif has_timelapse_safe_pos && !spiral_mode}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} U{timelapse_pos_x} V{timelapse_pos_y} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {else}\n {if spiral_mode}\n M971 S11 C10 O0\n M1004 S5 P1 ; external shutter\n {else}\n M9711 M{timelapse_type} E{most_used_physical_extruder_id} Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} S11 C10 O0 T3000\n {endif}\n {endif}\n\n {if !spiral_mode && !(has_timelapse_safe_pos) }\n {if most_used_physical_extruder_id!= curr_physical_extruder_id || timelapse_type == 1}\n G90\n G1 Z{max_layer_z + 3.0} F1200\n G91\n G0 Y-20 F18000\n G90\n M83\n {endif}\n {endif}\nM623\n; SKIPPABLE_END\n", "nozzle_diameter": [ "0.4", "0.4" diff --git a/resources/profiles/BBL/machine/fdm_machine_common.json b/resources/profiles/BBL/machine/fdm_machine_common.json index ed8e87d18d..f793f3bc1d 100644 --- a/resources/profiles/BBL/machine/fdm_machine_common.json +++ b/resources/profiles/BBL/machine/fdm_machine_common.json @@ -140,7 +140,10 @@ "silent_mode": "0", "single_extruder_multi_material": "1", "support_air_filtration": "0", + "support_cooling_filter": "0", + "cooling_filter_enabled": "0", "support_chamber_temp_control": "0", + "support_fast_purge_mode": "0", "support_object_skip_flush": "0", "wipe": [ "1" diff --git a/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2D.json b/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2D.json index 206abab7e0..64624b0bec 100644 --- a/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2D.json +++ b/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2D.json @@ -9,66 +9,77 @@ "4000", "4000", "4000", + "4000", "4000" ], "gap_infill_speed": [ "50", "50", "50", + "50", "50" ], "initial_layer_infill_speed": [ "70", "70", "70", + "70", "70" ], "initial_layer_speed": [ "40", "40", "40", + "40", "40" ], "inner_wall_speed": [ "120", "120", "120", + "120", "120" ], "internal_solid_infill_speed": [ "120", "120", "120", + "120", "120" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_brim_width": "-1", @@ -78,15 +89,136 @@ "100", "100", "100", + "100", "100" ], "top_surface_speed": [ "120", "120", "120", + "120", "120" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2DP.json b/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2DP.json index c88ec99c75..122190afd4 100644 --- a/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.08mm Extra Fine @BBL H2DP.json @@ -9,66 +9,77 @@ "4000", "4000", "4000", + "4000", "4000" ], "gap_infill_speed": [ "50", "50", "50", + "50", "50" ], "initial_layer_speed": [ "40", "40", "40", + "40", "40" ], "inner_wall_speed": [ "120", "120", "120", + "120", "120" ], "internal_solid_infill_speed": [ "120", "120", "120", + "120", "120" ], "initial_layer_infill_speed": [ "70", "70", "70", + "70", "70" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_width": "60", @@ -78,15 +89,136 @@ "100", "100", "100", + "100", "100" ], "top_surface_speed": [ "120", "120", "120", + "120", "120" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..18c97c02a0 --- /dev/null +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L 0.2 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "process", + "name": "0.08mm High Quality @BBL A2L 0.2 nozzle", + "inherits": "fdm_process_single_0.08_nozzle_0.2", + "from": "system", + "setting_id": "GP178", + "instantiation": "true", + "description": "Compared with the default profile of a 0.2 mm nozzle, it has a smaller layer lines, lower speeds and acceleration, and the sparse infill pattern is Gyroid. So, it results in almost invisible layer lines and much higher printing quality, but much longer printing time.", + "default_acceleration": [ + "4000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "initial_layer_infill_speed": [ + "28" + ], + "initial_layer_speed": [ + "16" + ], + "outer_wall_acceleration": [ + "2000" + ], + "outer_wall_speed": [ + "60" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "sparse_infill_pattern": "gyroid", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L.json new file mode 100644 index 0000000000..1c1c67efdd --- /dev/null +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL A2L.json @@ -0,0 +1,65 @@ +{ + "type": "process", + "name": "0.08mm High Quality @BBL A2L", + "inherits": "fdm_process_single_0.08", + "from": "system", + "setting_id": "GP179", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has a smaller layer height, lower speeds and acceleration, and the sparse infill pattern is Gyroid. So, it results in almost negligible layer lines and much higher printing quality, but much longer printing time.", + "default_acceleration": [ + "4000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "gap_infill_speed": [ + "210" + ], + "inner_wall_speed": [ + "120" + ], + "internal_solid_infill_speed": [ + "150" + ], + "outer_wall_acceleration": [ + "2000" + ], + "outer_wall_speed": [ + "60" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "150" + ], + "top_surface_speed": [ + "150" + ], + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..6552d7b47e --- /dev/null +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C 0.2 nozzle.json @@ -0,0 +1,45 @@ +{ + "type": "process", + "name": "0.08mm High Quality @BBL H2C 0.2 nozzle", + "inherits": "fdm_process_dual_0.08_nozzle_0.2", + "from": "system", + "setting_id": "GP243", + "instantiation": "true", + "description": "High quality profile for 0.2mm nozzle, prioritizing print quality.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "40", + "40", + "40", + "40" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "outer_wall_speed": [ + "100", + "100", + "100", + "100" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C.json b/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C.json new file mode 100644 index 0000000000..be2c204f08 --- /dev/null +++ b/resources/profiles/BBL/process/0.08mm High Quality @BBL H2C.json @@ -0,0 +1,93 @@ +{ + "type": "process", + "name": "0.08mm High Quality @BBL H2C", + "inherits": "fdm_process_dual_0.08_nozzle_0.4", + "from": "system", + "setting_id": "GP244", + "instantiation": "true", + "default_acceleration": [ + "4000", + "4000", + "4000", + "4000" + ], + "enable_tower_interface_features": "1", + "gap_infill_speed": [ + "50", + "50", + "50", + "50" + ], + "initial_layer_infill_speed": [ + "70", + "70", + "70", + "70" + ], + "initial_layer_speed": [ + "40", + "40", + "40", + "40" + ], + "inner_wall_speed": [ + "120", + "120", + "120", + "120" + ], + "internal_solid_infill_speed": [ + "120", + "120", + "120", + "120" + ], + "outer_wall_acceleration": [ + "2000", + "2000", + "2000", + "2000" + ], + "outer_wall_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_2_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_3_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "100", + "100", + "100", + "100" + ], + "top_surface_speed": [ + "120", + "120", + "120", + "120" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.10mm Standard @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/process/0.10mm Standard @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..3eeeae65e0 --- /dev/null +++ b/resources/profiles/BBL/process/0.10mm Standard @BBL A2L 0.2 nozzle.json @@ -0,0 +1,51 @@ +{ + "type": "process", + "name": "0.10mm Standard @BBL A2L 0.2 nozzle", + "inherits": "fdm_process_single_0.10_nozzle_0.2", + "from": "system", + "setting_id": "GP182", + "instantiation": "true", + "description": "It has a small layer height, and results in almost negligible layer lines and high printing quality. It is suitable for most general printing cases.", + "bridge_flow": "1.5", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "initial_layer_infill_speed": [ + "28" + ], + "initial_layer_speed": [ + "16" + ], + "overhang_2_4_speed": [ + "60" + ], + "overhang_3_4_speed": [ + "60" + ], + "overhang_4_4_speed": [ + "35" + ], + "overhang_totally_speed": [ + "25" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "support_line_width": "0.4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.10mm Standard @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/process/0.10mm Standard @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..2139246636 --- /dev/null +++ b/resources/profiles/BBL/process/0.10mm Standard @BBL H2C 0.2 nozzle.json @@ -0,0 +1,46 @@ +{ + "type": "process", + "name": "0.10mm Standard @BBL H2C 0.2 nozzle", + "inherits": "fdm_process_dual_0.10_nozzle_0.2", + "from": "system", + "setting_id": "GP245", + "instantiation": "true", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "40", + "40", + "40", + "40" + ], + "ironing_speed": "20", + "ironing_flow": "20%", + "outer_wall_speed": [ + "100", + "100", + "100", + "100" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL A2L 0.2 nozzle.json b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL A2L 0.2 nozzle.json new file mode 100644 index 0000000000..e1fbd88049 --- /dev/null +++ b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL A2L 0.2 nozzle.json @@ -0,0 +1,37 @@ +{ + "type": "process", + "name": "0.12mm Balanced Quality @BBL A2L 0.2 nozzle", + "inherits": "fdm_process_single_0.12_nozzle_0.2", + "from": "system", + "setting_id": "GP183", + "instantiation": "true", + "description": "Compared with the default profile of a 0.2 mm nozzle, it has a slightly bigger layer height, and results in almost negligible layer lines, and slightly shorter printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "initial_layer_infill_speed": [ + "28" + ], + "initial_layer_speed": [ + "16" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL H2C 0.2 nozzle.json b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL H2C 0.2 nozzle.json new file mode 100644 index 0000000000..33691925f0 --- /dev/null +++ b/resources/profiles/BBL/process/0.12mm Balanced Quality @BBL H2C 0.2 nozzle.json @@ -0,0 +1,44 @@ +{ + "type": "process", + "name": "0.12mm Balanced Quality @BBL H2C 0.2 nozzle", + "inherits": "fdm_process_dual_0.12_nozzle_0.2", + "from": "system", + "setting_id": "GP246", + "instantiation": "true", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "40", + "40", + "40", + "40" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "outer_wall_speed": [ + "100", + "100", + "100", + "100" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.2 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.12mm Fine @BBL H2D.json b/resources/profiles/BBL/process/0.12mm Fine @BBL H2D.json index 621958730a..e9251415b4 100644 --- a/resources/profiles/BBL/process/0.12mm Fine @BBL H2D.json +++ b/resources/profiles/BBL/process/0.12mm Fine @BBL H2D.json @@ -10,66 +10,77 @@ "4000", "4000", "4000", + "4000", "4000" ], "gap_infill_speed": [ "50", "50", "50", + "50", "50" ], "initial_layer_infill_speed": [ "70", "70", "70", + "70", "70" ], "initial_layer_speed": [ "40", "40", "40", + "40", "40" ], "inner_wall_speed": [ "120", "120", "120", + "120", "120" ], "internal_solid_infill_speed": [ "150", "150", "150", + "150", "150" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_brim_width": "-1", @@ -79,6 +90,7 @@ "100", "100", "100", + "100", "100" ], "top_color_penetration_layers": "7", @@ -88,9 +100,129 @@ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.12mm Fine @BBL H2DP.json b/resources/profiles/BBL/process/0.12mm Fine @BBL H2DP.json index 6268d48a51..3bb1e99970 100644 --- a/resources/profiles/BBL/process/0.12mm Fine @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.12mm Fine @BBL H2DP.json @@ -10,66 +10,77 @@ "4000", "4000", "4000", + "4000", "4000" ], "gap_infill_speed": [ "50", "50", "50", + "50", "50" ], "initial_layer_speed": [ "40", "40", "40", + "40", "40" ], "inner_wall_speed": [ "120", "120", "120", + "120", "120" ], "internal_solid_infill_speed": [ "150", "150", "150", + "150", "150" ], "initial_layer_infill_speed": [ "70", "70", "70", + "70", "70" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_width": "60", @@ -79,6 +90,7 @@ "100", "100", "100", + "100", "100" ], "top_shell_layers": "9", @@ -88,9 +100,129 @@ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.12mm High Quality @BBL A2L.json b/resources/profiles/BBL/process/0.12mm High Quality @BBL A2L.json new file mode 100644 index 0000000000..dd64b185c9 --- /dev/null +++ b/resources/profiles/BBL/process/0.12mm High Quality @BBL A2L.json @@ -0,0 +1,65 @@ +{ + "type": "process", + "name": "0.12mm High Quality @BBL A2L", + "inherits": "fdm_process_single_0.12", + "from": "system", + "setting_id": "GP185", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has a smaller layer height, lower speeds and acceleration, and the sparse infill pattern is Gyroid. So, it results in almost negligible layer lines and much higher printing quality, but much longer printing time.", + "default_acceleration": [ + "4000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "gap_infill_speed": [ + "230" + ], + "inner_wall_speed": [ + "150" + ], + "internal_solid_infill_speed": [ + "180" + ], + "outer_wall_acceleration": [ + "2000" + ], + "outer_wall_speed": [ + "60" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "180" + ], + "top_surface_speed": [ + "150" + ], + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.12mm High Quality @BBL H2C.json b/resources/profiles/BBL/process/0.12mm High Quality @BBL H2C.json new file mode 100644 index 0000000000..c6155c7395 --- /dev/null +++ b/resources/profiles/BBL/process/0.12mm High Quality @BBL H2C.json @@ -0,0 +1,97 @@ +{ + "type": "process", + "name": "0.12mm High Quality @BBL H2C", + "inherits": "fdm_process_dual_0.12_nozzle_0.4", + "from": "system", + "setting_id": "GP247", + "instantiation": "true", + "bottom_shell_layers": "7", + "default_acceleration": [ + "4000", + "4000", + "4000", + "4000" + ], + "enable_tower_interface_features": "1", + "gap_infill_speed": [ + "50", + "50", + "50", + "50" + ], + "initial_layer_infill_speed": [ + "70", + "70", + "70", + "70" + ], + "initial_layer_speed": [ + "40", + "40", + "40", + "40" + ], + "inner_wall_speed": [ + "120", + "120", + "120", + "120" + ], + "internal_solid_infill_speed": [ + "150", + "150", + "150", + "150" + ], + "outer_wall_acceleration": [ + "2000", + "2000", + "2000", + "2000" + ], + "outer_wall_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_2_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_3_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "100", + "100", + "100", + "100" + ], + "top_color_penetration_layers": "7", + "top_shell_layers": "9", + "top_shell_thickness": "0.8", + "top_surface_speed": [ + "150", + "150", + "150", + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2D.json b/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2D.json index 40b5457668..e1196f39ed 100644 --- a/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2D.json +++ b/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2D.json @@ -10,54 +10,63 @@ "4000", "4000", "4000", + "4000", "4000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "150", "150", "150", + "150", "150" ], "internal_solid_infill_speed": [ "180", "180", "180", + "180", "180" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_brim_width": "-1", @@ -67,15 +76,150 @@ "180", "180", "180", + "180", "180" ], "top_surface_speed": [ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2DP.json b/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2DP.json index 129c9ce49e..a759744dac 100644 --- a/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.16mm Balanced Quality @BBL H2DP.json @@ -10,54 +10,63 @@ "4000", "4000", "4000", + "4000", "4000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "150", "150", "150", + "150", "150" ], "internal_solid_infill_speed": [ "180", "180", "180", + "180", "180" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_width": "60", @@ -67,15 +76,150 @@ "180", "180", "180", + "180", "180" ], "top_surface_speed": [ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.16mm High Quality @BBL A2L.json b/resources/profiles/BBL/process/0.16mm High Quality @BBL A2L.json new file mode 100644 index 0000000000..9b6218b86c --- /dev/null +++ b/resources/profiles/BBL/process/0.16mm High Quality @BBL A2L.json @@ -0,0 +1,65 @@ +{ + "type": "process", + "name": "0.16mm High Quality @BBL A2L", + "inherits": "fdm_process_single_0.16", + "from": "system", + "setting_id": "GP187", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has a smaller layer height, lower speeds and acceleration, and the sparse infill pattern is Gyroid. So, it results in less apparent layer lines and much higher printing quality, but much longer printing time.", + "default_acceleration": [ + "4000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "gap_infill_speed": [ + "250" + ], + "inner_wall_speed": [ + "150" + ], + "internal_solid_infill_speed": [ + "200" + ], + "outer_wall_acceleration": [ + "2000" + ], + "outer_wall_speed": [ + "60" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "200" + ], + "top_surface_speed": [ + "150" + ], + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.16mm High Quality @BBL H2C.json b/resources/profiles/BBL/process/0.16mm High Quality @BBL H2C.json new file mode 100644 index 0000000000..c5b4a93f93 --- /dev/null +++ b/resources/profiles/BBL/process/0.16mm High Quality @BBL H2C.json @@ -0,0 +1,84 @@ +{ + "type": "process", + "name": "0.16mm High Quality @BBL H2C", + "inherits": "fdm_process_dual_0.16_nozzle_0.4", + "from": "system", + "setting_id": "GP248", + "instantiation": "true", + "description": "High quality profile for 0.16mm layer height, prioritizing print quality and strength.", + "default_acceleration": [ + "4000", + "4000", + "4000", + "4000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "150", + "150", + "150", + "150" + ], + "internal_solid_infill_speed": [ + "180", + "180", + "180", + "180" + ], + "ironing_speed": "20", + "ironing_flow": "25%", + "outer_wall_acceleration": [ + "2000", + "2000", + "2000", + "2000" + ], + "outer_wall_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_2_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_3_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_pattern": "gyroid", + "sparse_infill_speed": [ + "180", + "180", + "180", + "180" + ], + "top_surface_speed": [ + "150", + "150", + "150", + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.16mm Standard @BBL A2L.json b/resources/profiles/BBL/process/0.16mm Standard @BBL A2L.json new file mode 100644 index 0000000000..cfe8b823aa --- /dev/null +++ b/resources/profiles/BBL/process/0.16mm Standard @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "process", + "name": "0.16mm Standard @BBL A2L", + "inherits": "fdm_process_single_0.16", + "from": "system", + "setting_id": "GP188", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has a smaller layer height, and results in less apparent layer lines and higher printing quality, but longer printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.16mm Standard @BBL H2C.json b/resources/profiles/BBL/process/0.16mm Standard @BBL H2C.json new file mode 100644 index 0000000000..6c532d3d77 --- /dev/null +++ b/resources/profiles/BBL/process/0.16mm Standard @BBL H2C.json @@ -0,0 +1,69 @@ +{ + "type": "process", + "name": "0.16mm Standard @BBL H2C", + "inherits": "fdm_process_dual_0.16_nozzle_0.4", + "from": "system", + "setting_id": "GP249", + "instantiation": "true", + "description": "Standard profile for 0.16mm layer height, prioritizing speed.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "internal_solid_infill_speed": [ + "250", + "300", + "250", + "300" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_2_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_3_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.16mm Standard @BBL H2D.json b/resources/profiles/BBL/process/0.16mm Standard @BBL H2D.json index 7eb36b1c40..3bf6f6ae7f 100644 --- a/resources/profiles/BBL/process/0.16mm Standard @BBL H2D.json +++ b/resources/profiles/BBL/process/0.16mm Standard @BBL H2D.json @@ -10,30 +10,35 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "prime_tower_brim_width": "-1", @@ -42,15 +47,178 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300", + "300" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.16mm Standard @BBL H2DP.json b/resources/profiles/BBL/process/0.16mm Standard @BBL H2DP.json index 878a961494..fa625ded59 100644 --- a/resources/profiles/BBL/process/0.16mm Standard @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.16mm Standard @BBL H2DP.json @@ -10,30 +10,35 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_1_4_speed": [ "60", "60", "60", + "60", "60" ], "prime_tower_width": "60", @@ -42,15 +47,178 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300", + "300" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..2a76dd472d --- /dev/null +++ b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL A2L 0.6 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "process", + "name": "0.18mm Balanced Quality @BBL A2L 0.6 nozzle", + "inherits": "fdm_process_single_0.18_nozzle_0.6", + "from": "system", + "setting_id": "GP189", + "instantiation": "true", + "description": "Compared with the default profile of a 0.6 mm nozzle, it has a smaller layer height, and results in less apparent layer lines and higher printing quality, but longer printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..4c0bebdccc --- /dev/null +++ b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2C 0.6 nozzle.json @@ -0,0 +1,75 @@ +{ + "type": "process", + "name": "0.18mm Balanced Quality @BBL H2C 0.6 nozzle", + "inherits": "fdm_process_dual_0.18_nozzle_0.6", + "from": "system", + "setting_id": "GP250", + "instantiation": "true", + "description": "High quality profile for 0.6mm nozzle, prioritizing print quality and strength.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300" + ], + "internal_solid_infill_speed": [ + "250", + "250", + "250", + "250" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "350", + "350", + "350" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2D 0.6 nozzle.json index 57a8117032..8acb76fa22 100644 --- a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2D 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_brim_width": "-1", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2DP 0.6 nozzle.json index 8d20f165d7..617f91bb1a 100644 --- a/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.18mm Balanced Quality @BBL H2DP 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_width": "60", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2D.json b/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2D.json index 92143c2c9e..a58086b7ec 100644 --- a/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2D.json +++ b/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2D.json @@ -11,48 +11,56 @@ "4000", "4000", "4000", + "4000", "4000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "150", "150", "150", + "150", "150" ], "internal_solid_infill_speed": [ "200", "200", "200", + "200", "200" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_brim_width": "-1", @@ -61,6 +69,7 @@ "200", "200", "200", + "200", "200" ], "top_shell_layers": "6", @@ -68,9 +77,150 @@ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2DP.json b/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2DP.json index 5a5a368942..4f5abb11f2 100644 --- a/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.20mm Balanced Strength @BBL H2DP.json @@ -11,48 +11,56 @@ "4000", "4000", "4000", + "4000", "4000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "150", "150", "150", + "150", "150" ], "internal_solid_infill_speed": [ "200", "200", "200", + "200", "200" ], "outer_wall_speed": [ "60", "60", "60", + "60", "60" ], "outer_wall_acceleration": [ "2000", "2000", "2000", + "2000", "2000" ], "overhang_2_4_speed": [ "30", "30", "30", + "30", "30" ], "overhang_3_4_speed": [ "10", "10", "10", + "10", "10" ], "prime_tower_width": "60", @@ -61,6 +69,7 @@ "200", "200", "200", + "200", "200" ], "top_shell_layers": "6", @@ -68,9 +77,150 @@ "150", "150", "150", + "150", "150" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed": [ + "500", + "500", + "500", + "500", + "500" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.20mm High Quality @BBL A2L.json b/resources/profiles/BBL/process/0.20mm High Quality @BBL A2L.json new file mode 100644 index 0000000000..86e4fdd103 --- /dev/null +++ b/resources/profiles/BBL/process/0.20mm High Quality @BBL A2L.json @@ -0,0 +1,68 @@ +{ + "type": "process", + "name": "0.20mm High Quality @BBL A2L", + "inherits": "fdm_process_single_0.20", + "from": "system", + "setting_id": "GP191", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has more wall loops and a higher sparse infill density. So, it results in higher strength of the prints, but more filament consumption and longer printing time.", + "default_acceleration": [ + "4000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "inner_wall_speed": [ + "150" + ], + "internal_solid_infill_speed": [ + "200" + ], + "outer_wall_speed": [ + "60" + ], + "overhang_1_4_speed": [ + "60" + ], + "overhang_2_4_speed": [ + "30" + ], + "overhang_3_4_speed": [ + "10" + ], + "prime_tower_brim_width": "-1", + "skeleton_infill_density": "25%", + "skin_infill_density": "25%", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "sparse_infill_density": "25%", + "sparse_infill_speed": [ + "200" + ], + "travel_acceleration": [ + "8000" + ], + "wall_loops": "6", + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.20mm High Quality @BBL H2C.json b/resources/profiles/BBL/process/0.20mm High Quality @BBL H2C.json new file mode 100644 index 0000000000..720e1cbcc7 --- /dev/null +++ b/resources/profiles/BBL/process/0.20mm High Quality @BBL H2C.json @@ -0,0 +1,83 @@ +{ + "type": "process", + "name": "0.20mm High Quality @BBL H2C", + "inherits": "fdm_process_dual_0.20_nozzle_0.4", + "from": "system", + "setting_id": "GP251", + "instantiation": "true", + "description": "High quality profile for 0.2mm layer height, prioritizing strength and print quality.", + "bottom_shell_layers": "4", + "default_acceleration": [ + "4000", + "4000", + "4000", + "4000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "150", + "150", + "150", + "150" + ], + "internal_solid_infill_speed": [ + "200", + "200", + "200", + "200" + ], + "outer_wall_acceleration": [ + "2000", + "2000", + "2000", + "2000" + ], + "outer_wall_speed": [ + "60", + "60", + "60", + "60" + ], + "overhang_2_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_3_4_speed": [ + "10", + "10", + "10", + "10" + ], + "overhang_1_4_speed": [ + "60", + "60", + "60", + "60" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "200", + "200", + "200", + "200" + ], + "top_shell_layers": "6", + "top_surface_speed": [ + "150", + "150", + "150", + "150" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.20mm Standard @BBL A2L.json b/resources/profiles/BBL/process/0.20mm Standard @BBL A2L.json new file mode 100644 index 0000000000..b26ff6f9e6 --- /dev/null +++ b/resources/profiles/BBL/process/0.20mm Standard @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "process", + "name": "0.20mm Standard @BBL A2L", + "inherits": "fdm_process_single_0.20", + "from": "system", + "setting_id": "GP190", + "instantiation": "true", + "description": "It has a general layer height, and results in general layer lines and printing quality. It is suitable for most general printing cases.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.20mm Standard @BBL H2C.json b/resources/profiles/BBL/process/0.20mm Standard @BBL H2C.json new file mode 100644 index 0000000000..b50064fe34 --- /dev/null +++ b/resources/profiles/BBL/process/0.20mm Standard @BBL H2C.json @@ -0,0 +1,64 @@ +{ + "type": "process", + "name": "0.20mm Standard @BBL H2C", + "inherits": "fdm_process_dual_0.20_nozzle_0.4", + "from": "system", + "setting_id": "GP252", + "instantiation": "true", + "description": "Standard profile for 0.4mm nozzle, prioritizing speed.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "gap_infill_speed": [ + "250", + "150", + "250", + "150" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "internal_solid_infill_speed": [ + "250", + "600", + "250", + "600" + ], + "inner_wall_speed": [ + "300", + "600", + "300", + "600" + ], + "ironing_flow": "15%", + "outer_wall_speed": [ + "200", + "500", + "200", + "500" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.20mm Standard @BBL H2D.json b/resources/profiles/BBL/process/0.20mm Standard @BBL H2D.json index f6de64ae2b..967cec907a 100644 --- a/resources/profiles/BBL/process/0.20mm Standard @BBL H2D.json +++ b/resources/profiles/BBL/process/0.20mm Standard @BBL H2D.json @@ -10,30 +10,35 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "600", "250", + "600", "600" ], "inner_wall_speed": [ "300", "600", "300", + "600", "600" ], "outer_wall_speed": [ "200", "500", "200", + "500", "500" ], "prime_tower_brim_width": "-1", @@ -42,15 +47,178 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.20mm Standard @BBL H2DP.json b/resources/profiles/BBL/process/0.20mm Standard @BBL H2DP.json index 8ab7dedf25..da67bb2b18 100644 --- a/resources/profiles/BBL/process/0.20mm Standard @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.20mm Standard @BBL H2DP.json @@ -10,24 +10,28 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "prime_tower_width": "60", @@ -36,15 +40,185 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300", + "300" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json b/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json new file mode 100644 index 0000000000..d41f51faf1 --- /dev/null +++ b/resources/profiles/BBL/process/0.20mm Steady @BBL A2L.json @@ -0,0 +1,180 @@ +{ + "type": "process", + "name": "0.20mm Steady @BBL A2L", + "inherits": "fdm_process_single_0.20", + "from": "system", + "setting_id": "GP195", + "instantiation": "true", + "description": "Lower-acceleration profile for the 0.4mm nozzle. Use it when the printer sits on a wobbly desk or shelf", + "bridge_speed": [ + "50", + "50" + ], + "default_acceleration": [ + "3500", + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1", + "1" + ], + "enable_overhang_speed": [ + "1", + "1" + ], + "gap_infill_speed": [ + "150", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "100" + ], + "initial_layer_travel_acceleration": [ + "5000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0" + ], + "inner_wall_speed": [ + "150", + "300" + ], + "internal_solid_infill_speed": [ + "150", + "250" + ], + "outer_wall_acceleration": [ + "3500", + "5000" + ], + "outer_wall_speed": [ + "150", + "200" + ], + "overhang_1_4_speed": [ + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10" + ], + "overhang_totally_speed": [ + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "print_extruder_id": [ + "1", + "1" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive TPU285" + ], + "slowdown_end_acc": [ + "2000", + "2000" + ], + "slowdown_end_height": [ + "325", + "325" + ], + "slowdown_end_speed": [ + "500", + "500" + ], + "slowdown_start_acc": [ + "8000", + "8000" + ], + "slowdown_start_height": [ + "150", + "150" + ], + "slowdown_start_speed": [ + "500", + "500" + ], + "small_perimeter_speed": [ + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0" + ], + "smooth_coefficient": "4", + "sparse_infill_acceleration": [ + "100%", + "100%" + ], + "sparse_infill_speed": [ + "150", + "270" + ], + "support_interface_speed": [ + "80", + "80" + ], + "support_speed": [ + "150", + "150" + ], + "top_solid_infill_flow_ratio": [ + "1", + "1" + ], + "top_surface_acceleration": [ + "2000", + "2000" + ], + "top_surface_speed": [ + "150", + "200" + ], + "travel_acceleration": [ + "4000", + "8000" + ], + "travel_short_distance_acceleration": [ + "250", + "250" + ], + "travel_speed": [ + "300", + "500" + ], + "travel_speed_z": [ + "0", + "0" + ], + "vertical_shell_speed": [ + "80%", + "80%" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..74c9994732 --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.6 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "process", + "name": "0.24mm Balanced Quality @BBL A2L 0.6 nozzle", + "inherits": "fdm_process_single_0.24_nozzle_0.6", + "from": "system", + "setting_id": "GP194", + "instantiation": "true", + "description": "Compared with the default profile of a 0.6 mm nozzle, it has a smaller layer height, and results in less apparent layer lines and slight higher printing quality, but longer printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..83900ad084 --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL A2L 0.8 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "process", + "name": "0.24mm Balanced Quality @BBL A2L 0.8 nozzle", + "inherits": "fdm_process_single_0.24_nozzle_0.8", + "from": "system", + "setting_id": "GP193", + "instantiation": "true", + "description": "Compared with the default profile of a 0.8 mm nozzle, it has a smaller layer height, and results in less but still apparent layer lines and slightly higher printing quality, but longer printing time in some printing cases.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..0a32a82a86 --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Balanced Quality @BBL H2C 0.8 nozzle.json @@ -0,0 +1,81 @@ +{ + "type": "process", + "name": "0.24mm Balanced Quality @BBL H2C 0.8 nozzle", + "inherits": "fdm_process_dual_0.24_nozzle_0.8", + "from": "system", + "setting_id": "GP253", + "instantiation": "true", + "description": "High quality profile for 0.8mm nozzle, prioritizing print quality.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300" + ], + "internal_solid_infill_speed": [ + "250", + "250", + "250", + "250" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "350", + "350", + "350" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..e66b7ee039 --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2C 0.6 nozzle.json @@ -0,0 +1,87 @@ +{ + "type": "process", + "name": "0.24mm Balanced Strength @BBL H2C 0.6 nozzle", + "inherits": "fdm_process_dual_0.24_nozzle_0.6", + "from": "system", + "setting_id": "GP254", + "instantiation": "true", + "description": "Strength profile for 0.6mm nozzle, prioritizing strength.", + "bridge_speed": [ + "50", + "50", + "50", + "50" + ], + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "gap_infill_speed": [ + "250", + "250", + "250", + "250" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300" + ], + "internal_solid_infill_speed": [ + "250", + "300", + "250", + "300" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2D 0.6 nozzle.json index 484b8f8071..63063d0d3c 100644 --- a/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2D 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_brim_width": "-1", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2DP 0.6 nozzle.json index 9a47ad23ae..0f138b0cc6 100644 --- a/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.24mm Balanced Strength @BBL H2DP 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_width": "60", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.24mm Standard @BBL A2L.json b/resources/profiles/BBL/process/0.24mm Standard @BBL A2L.json new file mode 100644 index 0000000000..f99e4ec24f --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Standard @BBL A2L.json @@ -0,0 +1,43 @@ +{ + "type": "process", + "name": "0.24mm Standard @BBL A2L", + "inherits": "fdm_process_single_0.24", + "from": "system", + "setting_id": "GP192", + "instantiation": "true", + "description": "Compared with the default profile of a 0.4 mm nozzle, it has a bigger layer height, and results in more apparent layer lines and lower printing quality, but slightly shorter printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_height": [ + "0" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Standard @BBL H2C.json b/resources/profiles/BBL/process/0.24mm Standard @BBL H2C.json new file mode 100644 index 0000000000..3f58cdbc04 --- /dev/null +++ b/resources/profiles/BBL/process/0.24mm Standard @BBL H2C.json @@ -0,0 +1,50 @@ +{ + "type": "process", + "name": "0.24mm Standard @BBL H2C", + "inherits": "fdm_process_dual_0.24_nozzle_0.4", + "from": "system", + "setting_id": "GP255", + "instantiation": "true", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "internal_solid_infill_speed": [ + "250", + "300", + "250", + "300" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.4 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.24mm Standard @BBL H2D.json b/resources/profiles/BBL/process/0.24mm Standard @BBL H2D.json index 640a0e2150..b01b963193 100644 --- a/resources/profiles/BBL/process/0.24mm Standard @BBL H2D.json +++ b/resources/profiles/BBL/process/0.24mm Standard @BBL H2D.json @@ -9,24 +9,28 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "prime_tower_brim_width": "-1", @@ -35,15 +39,185 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300", + "300" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.24mm Standard @BBL H2DP.json b/resources/profiles/BBL/process/0.24mm Standard @BBL H2DP.json index 0e48acebb2..fb06e53278 100644 --- a/resources/profiles/BBL/process/0.24mm Standard @BBL H2DP.json +++ b/resources/profiles/BBL/process/0.24mm Standard @BBL H2DP.json @@ -9,24 +9,28 @@ "8000", "8000", "8000", + "8000", "8000" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "prime_tower_width": "60", @@ -35,15 +39,185 @@ "350", "600", "350", + "600", "600" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.4 nozzle" + ], + "bridge_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "gap_infill_speed": [ + "250", + "250", + "250", + "250", + "250" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105", + "105" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300", + "300" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200", + "200" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL A2L 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL A2L 0.6 nozzle.json new file mode 100644 index 0000000000..4fa0523bb4 --- /dev/null +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL A2L 0.6 nozzle.json @@ -0,0 +1,40 @@ +{ + "type": "process", + "name": "0.30mm Standard @BBL A2L 0.6 nozzle", + "inherits": "fdm_process_single_0.30_nozzle_0.6", + "from": "system", + "setting_id": "GP196", + "instantiation": "true", + "description": "It has a big layer height, and results in apparent layer lines and ordinary printing quality and printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "slowdown_end_speed": [ + "500" + ], + "slowdown_start_acc": [ + "8000" + ], + "slowdown_start_speed": [ + "500" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL H2C 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL H2C 0.6 nozzle.json new file mode 100644 index 0000000000..b86a58762a --- /dev/null +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL H2C 0.6 nozzle.json @@ -0,0 +1,76 @@ +{ + "type": "process", + "name": "0.30mm Standard @BBL H2C 0.6 nozzle", + "inherits": "fdm_process_dual_0.30_nozzle_0.6", + "from": "system", + "setting_id": "GP256", + "instantiation": "true", + "description": "Standard profile for 0.6mm nozzle, prioritizing speed.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "600", + "300", + "600" + ], + "internal_solid_infill_speed": [ + "250", + "600", + "250", + "600" + ], + "outer_wall_speed": [ + "200", + "500", + "200", + "500" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "top_shell_layers": "4", + "compatible_printers": [ + "Bambu Lab H2C 0.6 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL H2D 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL H2D 0.6 nozzle.json index 98d7ebcc3f..ce7e10a14d 100644 --- a/resources/profiles/BBL/process/0.30mm Standard @BBL H2D 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL H2D 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_brim_width": "-1", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.30mm Standard @BBL H2DP 0.6 nozzle.json b/resources/profiles/BBL/process/0.30mm Standard @BBL H2DP 0.6 nozzle.json index 81c95e2d63..c141b81adf 100644 --- a/resources/profiles/BBL/process/0.30mm Standard @BBL H2DP 0.6 nozzle.json +++ b/resources/profiles/BBL/process/0.30mm Standard @BBL H2DP 0.6 nozzle.json @@ -10,54 +10,63 @@ "50", "50", "50", + "50", "50" ], "default_acceleration": [ "8000", "8000", "8000", + "8000", "8000" ], "gap_infill_speed": [ "250", "250", "250", + "250", "250" ], "initial_layer_speed": [ "50", "50", "50", + "50", "50" ], "inner_wall_speed": [ "300", "300", "300", + "300", "300" ], "internal_solid_infill_speed": [ "250", "300", "250", + "300", "300" ], "initial_layer_infill_speed": [ "105", "105", "105", + "105", "105" ], "outer_wall_speed": [ "200", "200", "200", + "200", "200" ], "overhang_3_4_speed": [ "30", "30", "30", + "30", "30" ], "prime_tower_width": "60", @@ -66,21 +75,150 @@ "350", "600", "350", + "600", "600" ], "top_surface_speed": [ "200", "200", "200", + "200", "200" ], "travel_speed": [ "1000", "1000", "1000", + "1000", "1000" ], "compatible_printers": [ "Bambu Lab H2D Pro 0.6 nozzle" + ], + "enable_overhang_speed": [ + "1", + "1", + "1", + "1", + "1" + ], + "initial_layer_acceleration": [ + "500", + "500", + "500", + "500", + "500" + ], + "initial_layer_travel_acceleration": [ + "6000", + "6000", + "6000", + "6000", + "6000" + ], + "inner_wall_acceleration": [ + "0", + "0", + "0", + "0", + "0" + ], + "outer_wall_acceleration": [ + "5000", + "5000", + "5000", + "5000", + "5000" + ], + "overhang_1_4_speed": [ + "0", + "0", + "0", + "0", + "0" + ], + "overhang_2_4_speed": [ + "50", + "50", + "50", + "50", + "50" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10", + "10" + ], + "print_extruder_id": [ + "1", + "1", + "2", + "2", + "2" + ], + "print_extruder_variant": [ + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive Standard", + "Direct Drive High Flow", + "Direct Drive TPU High Flow" + ], + "small_perimeter_speed": [ + "50%", + "50%", + "50%", + "50%", + "50%" + ], + "small_perimeter_threshold": [ + "0", + "0", + "0", + "0", + "0" + ], + "sparse_infill_acceleration": [ + "100%", + "100%", + "100%", + "100%", + "100%" + ], + "support_interface_speed": [ + "80", + "80", + "80", + "80", + "80" + ], + "support_speed": [ + "150", + "150", + "150", + "150", + "150" + ], + "top_surface_acceleration": [ + "2000", + "2000", + "2000", + "2000", + "2000" + ], + "travel_acceleration": [ + "10000", + "10000", + "10000", + "10000", + "10000" + ], + "travel_speed_z": [ + "0", + "0", + "0", + "0", + "0" ] } diff --git a/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..20b865e2cd --- /dev/null +++ b/resources/profiles/BBL/process/0.32mm Balanced Quality @BBL A2L 0.8 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "process", + "name": "0.32mm Balanced Quality @BBL A2L 0.8 nozzle", + "inherits": "fdm_process_single_0.32_nozzle_0.8", + "from": "system", + "setting_id": "GP198", + "instantiation": "true", + "description": "Compared with the default profile of a 0.8 mm nozzle, it has a slightly smaller layer height, and results in slightly less but still apparent layer lines and slightly higher printing quality, but longer printing time in some printing cases.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.32mm Balanced Strength @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/process/0.32mm Balanced Strength @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..512bd79982 --- /dev/null +++ b/resources/profiles/BBL/process/0.32mm Balanced Strength @BBL H2C 0.8 nozzle.json @@ -0,0 +1,93 @@ +{ + "type": "process", + "name": "0.32mm Balanced Strength @BBL H2C 0.8 nozzle", + "inherits": "fdm_process_dual_0.32_nozzle_0.8", + "from": "system", + "setting_id": "GP257", + "instantiation": "true", + "description": "Strength profile for 0.8mm nozzle, prioritizing strength.", + "bridge_speed": [ + "50", + "50", + "50", + "50" + ], + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "gap_infill_speed": [ + "250", + "250", + "250", + "250" + ], + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "300", + "300", + "300" + ], + "internal_solid_infill_speed": [ + "250", + "300", + "250", + "300" + ], + "outer_wall_speed": [ + "200", + "200", + "200", + "200" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.40mm Standard @BBL A2L 0.8 nozzle.json b/resources/profiles/BBL/process/0.40mm Standard @BBL A2L 0.8 nozzle.json new file mode 100644 index 0000000000..c0af67dba9 --- /dev/null +++ b/resources/profiles/BBL/process/0.40mm Standard @BBL A2L 0.8 nozzle.json @@ -0,0 +1,31 @@ +{ + "type": "process", + "name": "0.40mm Standard @BBL A2L 0.8 nozzle", + "inherits": "fdm_process_single_0.40_nozzle_0.8", + "from": "system", + "setting_id": "GP200", + "instantiation": "true", + "description": "It has a very big layer height, and results in very apparent layer lines, low printing quality and general printing time.", + "default_acceleration": [ + "6000" + ], + "elefant_foot_compensation": "0.075", + "enable_arc_fitting": "0", + "enable_height_slowdown": [ + "1" + ], + "prime_tower_brim_width": "-1", + "slowdown_end_acc": [ + "1000" + ], + "slowdown_end_height": [ + "225" + ], + "smooth_coefficient": "4", + "travel_acceleration": [ + "8000" + ], + "compatible_printers": [ + "Bambu Lab A2L 0.8 nozzle" + ] +} diff --git a/resources/profiles/BBL/process/0.40mm Standard @BBL H2C 0.8 nozzle.json b/resources/profiles/BBL/process/0.40mm Standard @BBL H2C 0.8 nozzle.json new file mode 100644 index 0000000000..535f1f1a2f --- /dev/null +++ b/resources/profiles/BBL/process/0.40mm Standard @BBL H2C 0.8 nozzle.json @@ -0,0 +1,82 @@ +{ + "type": "process", + "name": "0.40mm Standard @BBL H2C 0.8 nozzle", + "inherits": "fdm_process_dual_0.40_nozzle_0.8", + "from": "system", + "setting_id": "GP258", + "instantiation": "true", + "description": "Standard profile for 0.8mm nozzle, prioritizing speed.", + "default_acceleration": [ + "8000", + "8000", + "8000", + "8000" + ], + "enable_tower_interface_features": "1", + "initial_layer_infill_speed": [ + "105", + "105", + "105", + "105" + ], + "initial_layer_speed": [ + "50", + "50", + "50", + "50" + ], + "inner_wall_speed": [ + "300", + "600", + "300", + "600" + ], + "internal_solid_infill_speed": [ + "250", + "600", + "250", + "600" + ], + "outer_wall_speed": [ + "200", + "500", + "200", + "500" + ], + "overhang_3_4_speed": [ + "30", + "30", + "30", + "30" + ], + "overhang_4_4_speed": [ + "10", + "10", + "10", + "10" + ], + "prime_tower_brim_width": "-1", + "prime_tower_width": "60", + "sparse_infill_speed": [ + "350", + "600", + "350", + "600" + ], + "top_surface_speed": [ + "200", + "200", + "200", + "200" + ], + "travel_speed": [ + "1000", + "1000", + "1000", + "1000" + ], + "top_shell_layers": "4", + "compatible_printers": [ + "Bambu Lab H2C 0.8 nozzle" + ] +} diff --git a/resources/profiles/Creality.json b/resources/profiles/Creality.json index f90648d256..8e91974b9c 100644 --- a/resources/profiles/Creality.json +++ b/resources/profiles/Creality.json @@ -1230,6 +1230,10 @@ "name": "0.40mm Standard @Creality K1C", "sub_path": "process/0.40mm Standard @Creality K1C 0.8 nozzle.json" }, + { + "name": "0.40mm Standard @Creality K1 SE 0.8 nozzle", + "sub_path": "process/0.40mm Standard @Creality K1 SE 0.8 nozzle.json" + }, { "name": "0.40mm Standard @Creality K1Max (0.8 nozzle)", "sub_path": "process/0.40mm Standard @Creality K1Max (0.8 nozzle).json" diff --git a/resources/profiles/Creality/machine/Creality CR-6 Max 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality CR-6 Max 0.2 nozzle.json index 35d77612c2..1a91139859 100644 --- a/resources/profiles/Creality/machine/Creality CR-6 Max 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-6 Max 0.2 nozzle.json @@ -11,7 +11,7 @@ "Creality Generic PLA" ], "printer_variant": "0.2", - "default_print_profile": "0.16mm Opitmal @Creality CR-6 0.2", + "default_print_profile": "0.16mm Optimal @Creality CR-6 0.2", "nozzle_diameter": [ "0.2" ], diff --git a/resources/profiles/Creality/machine/Creality CR-6 SE 0.2 nozzle.json b/resources/profiles/Creality/machine/Creality CR-6 SE 0.2 nozzle.json index c04b78dfa1..757ee910bf 100644 --- a/resources/profiles/Creality/machine/Creality CR-6 SE 0.2 nozzle.json +++ b/resources/profiles/Creality/machine/Creality CR-6 SE 0.2 nozzle.json @@ -11,7 +11,7 @@ "Creality Generic PLA" ], "printer_variant": "0.2", - "default_print_profile": "0.16mm Opitmal @Creality CR-6 0.2", + "default_print_profile": "0.16mm Optimal @Creality CR-6 0.2", "nozzle_diameter": [ "0.2" ], diff --git a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 0.2.json b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 0.2.json index 8d7d9c44a6..84722ac71c 100644 --- a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 0.2.json +++ b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 0.2.json @@ -69,7 +69,7 @@ "support_on_build_plate_only": "0", "support_top_z_distance": "0.15", "support_filament": "0", - "support_line_width": "0.18", + "support_line_width": "0.22", "support_interface_loop_pattern": "0", "support_interface_filament": "0", "support_interface_top_layers": "3", @@ -85,7 +85,7 @@ "tree_support_wall_count": "0", "detect_thin_wall": "1", "top_surface_pattern": "monotonicline", - "top_surface_line_width": "0.2", + "top_surface_line_width": "0.25", "top_shell_layers": "5", "top_shell_thickness": "0.8", "initial_layer_speed": "35%", diff --git a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 Pro 0.2.json b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 Pro 0.2.json index 9e5461dbee..6912aaebab 100644 --- a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 Pro 0.2.json +++ b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3 Pro 0.2.json @@ -69,7 +69,7 @@ "support_on_build_plate_only": "0", "support_top_z_distance": "0.15", "support_filament": "0", - "support_line_width": "0.18", + "support_line_width": "0.22", "support_interface_loop_pattern": "0", "support_interface_filament": "0", "support_interface_top_layers": "3", @@ -85,7 +85,7 @@ "tree_support_wall_count": "0", "detect_thin_wall": "1", "top_surface_pattern": "monotonicline", - "top_surface_line_width": "0.2", + "top_surface_line_width": "0.25", "top_shell_layers": "5", "top_shell_thickness": "0.8", "initial_layer_speed": "35%", diff --git a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1Plus 0.2.json b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1Plus 0.2.json index 5ac0c2cc46..9aba5bb71d 100644 --- a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1Plus 0.2.json +++ b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3S1Plus 0.2.json @@ -59,7 +59,7 @@ "skirt_height": "2", "skirt_loops": "2", "minimum_sparse_infill_area": "10", - "internal_solid_infill_line_width": "0.2", + "internal_solid_infill_line_width": "0.25", "spiral_mode": "0", "standby_temperature_delta": "-5", "enable_support": "0", @@ -69,7 +69,7 @@ "support_on_build_plate_only": "0", "support_top_z_distance": "0.15", "support_filament": "0", - "support_line_width": "0.18", + "support_line_width": "0.22", "support_interface_loop_pattern": "0", "support_interface_filament": "0", "support_interface_top_layers": "3", @@ -85,7 +85,7 @@ "tree_support_wall_count": "0", "detect_thin_wall": "1", "top_surface_pattern": "monotonicline", - "top_surface_line_width": "0.2", + "top_surface_line_width": "0.25", "top_shell_layers": "7", "top_shell_thickness": "0.8", "initial_layer_speed": "35%", diff --git a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3V3SE 0.2.json b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3V3SE 0.2.json index a1672739e3..cdd841907d 100644 --- a/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3V3SE 0.2.json +++ b/resources/profiles/Creality/process/0.20mm Standard @Creality Ender3V3SE 0.2.json @@ -71,7 +71,7 @@ "support_on_build_plate_only": "0", "support_top_z_distance": "0.15", "support_filament": "0", - "support_line_width": "0.18", + "support_line_width": "0.22", "support_interface_loop_pattern": "0", "support_interface_filament": "0", "support_interface_top_layers": "2", diff --git a/resources/profiles/Creality/process/0.40mm Standard @Creality K1 SE 0.8 nozzle.json b/resources/profiles/Creality/process/0.40mm Standard @Creality K1 SE 0.8 nozzle.json new file mode 100644 index 0000000000..88bc46add2 --- /dev/null +++ b/resources/profiles/Creality/process/0.40mm Standard @Creality K1 SE 0.8 nozzle.json @@ -0,0 +1,264 @@ +{ + "type": "process", + "name": "0.40mm Standard @Creality K1 SE 0.8 nozzle", + "inherits": "fdm_process_creality_common", + "from": "system", + "setting_id": "5mfhrVJYlK4lWDUs", + "instantiation": "true", + "reduce_crossing_wall": "0", + "max_travel_detour_distance": "0", + "bottom_surface_pattern": "monotonic", + "bottom_shell_layers": "3", + "bottom_shell_thickness": "0", + "bridge_flow": "0.8", + "bridge_speed": "10", + "brim_width": "5", + "brim_object_gap": "0.1", + "print_sequence": "by layer", + "default_acceleration": "10000", + "bridge_no_support": "0", + "draft_shield": "disabled", + "elefant_foot_compensation": "0.15", + "outer_wall_line_width": "0.82", + "outer_wall_speed": "100", + "outer_wall_acceleration": "2000", + "inner_wall_acceleration": "2000", + "line_width": "0.82", + "infill_direction": "45", + "sparse_infill_density": "15%", + "sparse_infill_pattern": "grid", + "initial_layer_acceleration": "500", + "initial_layer_line_width": "0.82", + "initial_layer_print_height": "0.4", + "initial_layer_speed": "40", + "gap_infill_speed": "50", + "infill_combination": "0", + "sparse_infill_line_width": "0.82", + "infill_wall_overlap": "30", + "sparse_infill_speed": "150", + "interface_shells": "0", + "ironing_flow": "10%", + "ironing_spacing": "0.15", + "ironing_speed": "30", + "ironing_type": "no ironing", + "layer_height": "0.4", + "reduce_infill_retraction": "1", + "filename_format": "{input_filename_base}_{filament_type[initial_tool]}_{print_time}.gcode", + "detect_overhang_wall": "1", + "overhang_1_4_speed": "50", + "overhang_2_4_speed": "35", + "overhang_3_4_speed": "20", + "overhang_4_4_speed": "10", + "only_one_wall_top": "1", + "inner_wall_line_width": "0.82", + "inner_wall_speed": "150", + "wall_loops": "2", + "raft_layers": "0", + "seam_position": "aligned", + "seam_slope_conditional": "0", + "seam_slope_inner_walls": "0", + "seam_slope_entire_loop": "0", + "skirt_distance": "2", + "skirt_height": "1", + "skirt_loops": "0", + "minimum_sparse_infill_area": "15", + "internal_solid_infill_line_width": "0.82", + "internal_solid_infill_speed": "150", + "spiral_mode": "0", + "initial_layer_infill_speed": "60", + "standby_temperature_delta": "-5", + "enable_support": "0", + "resolution": "0.012", + "support_type": "normal(auto)", + "support_style": "default", + "support_on_build_plate_only": "0", + "support_top_z_distance": "0.2", + "support_bottom_z_distance": "0.2", + "support_filament": "0", + "support_line_width": "0.82", + "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_expansion": "0", + "support_interface_speed": "80", + "support_base_pattern": "rectilinear", + "support_base_pattern_spacing": "2.5", + "support_speed": "150", + "support_threshold_angle": "30", + "support_object_xy_distance": "0.35", + "tree_support_branch_diameter": "2", + "tree_support_branch_angle": "45", + "tree_support_wall_count": "0", + "detect_thin_wall": "0", + "top_surface_pattern": "monotonicline", + "top_surface_line_width": "0.82", + "top_surface_acceleration": "2000", + "top_surface_speed": "100", + "top_shell_layers": "3", + "top_shell_thickness": "0.8", + "travel_acceleration": "10000", + "travel_speed": "500", + "enable_prime_tower": "0", + "wipe_tower_no_sparse_layers": "0", + "prime_tower_width": "60", + "xy_hole_compensation": "0", + "xy_contour_compensation": "0", + "gcode_label_objects": "0", + "compatible_printers": [ + "Creality K1 SE 0.8 nozzle" + ], + "accel_to_decel_enable": "1", + "accel_to_decel_factor": "50", + "acceleration_limit_mess_enable": "0", + "ai_infill": "0", + "alternate_extra_wall": "0", + "bottom_solid_infill_flow_ratio": "1", + "bridge_acceleration": "50%", + "bridge_angle": "0", + "bridge_density": "100%", + "brim_ears_detection_length": "1", + "brim_ears_max_angle": "125", + "brim_type": "auto_brim", + "counterbore_hole_bridging": "none", + "default_jerk": "6", + "detect_narrow_internal_solid_infill": "1", + "dont_filter_internal_bridges": "disabled", + "elefant_foot_compensation_layers": "1", + "enable_arc_fitting": "1", + "enable_overhang_speed": "1", + "enforce_support_layers": "0", + "ensure_vertical_shell_thickness": "ensure_all", + "exclude_object": "1", + "extra_perimeters_on_overhangs": "0", + "filter_out_gap_fill": "0", + "flush_into_infill": "0", + "flush_into_objects": "0", + "flush_into_support": "1", + "fuzzy_skin": "none", + "fuzzy_skin_first_layer": "0", + "fuzzy_skin_point_distance": "0.8", + "fuzzy_skin_thickness": "0.3", + "gap_fill_target": "everywhere", + "gcode_add_line_number": "0", + "gcode_comments": "0", + "hole_to_polyhole": "0", + "hole_to_polyhole_threshold": "0.01", + "hole_to_polyhole_twisted": "1", + "independent_support_layer_height": "1", + "infill_anchor": "400%", + "infill_anchor_max": "20", + "infill_jerk": "6", + "initial_layer_jerk": "6", + "initial_layer_min_bead_width": "85%", + "initial_layer_travel_speed": "100%", + "inner_wall_jerk": "6", + "internal_bridge_flow": "1", + "internal_bridge_speed": "70", + "internal_solid_infill_acceleration": "100%", + "internal_solid_infill_pattern": "zig-zag", + "ironing_angle": "90", + "ironing_pattern": "zig-zag", + "ironing_support_layer": "0", + "is_infill_first": "0", + "make_overhang_printable": "0", + "make_overhang_printable_angle": "55", + "make_overhang_printable_hole_size": "0", + "max_bridge_length": "10", + "max_volumetric_extrusion_rate_slope": "0", + "max_volumetric_extrusion_rate_slope_segment_length": "3", + "min_bead_width": "85%", + "min_feature_size": "25%", + "min_length_factor": "0.5", + "min_width_top_surface": "300%", + "minimum_support_area": "5", + "mmu_segmented_region_interlocking_depth": "0", + "mmu_segmented_region_max_width": "0", + "only_one_wall_first_layer": "0", + "ooze_prevention": "0", + "outer_wall_jerk": "6", + "overhang_reverse": "0", + "overhang_reverse_internal_only": "0", + "overhang_reverse_threshold": "50%", + "overhang_speed_classic": "0", + "precise_outer_wall": "0", + "prime_tower_brim_width": "3", + "prime_tower_enhance_type": "chamfer", + "prime_volume": "45", + "print_flow_ratio": "1", + "print_order": "default", + "raft_contact_distance": "0.1", + "raft_expansion": "1.5", + "raft_first_layer_density": "90%", + "raft_first_layer_expansion": "2", + "role_based_wipe_speed": "1", + "scarf_angle_threshold": "155", + "scarf_joint_flow_ratio": "1", + "scarf_joint_speed": "100%", + "scarf_overhang_threshold": "40%", + "seam_gap": "10%", + "seam_slope_min_length": "20", + "seam_slope_start_height": "0", + "seam_slope_steps": "10", + "seam_slope_type": "none", + "single_extruder_multi_material_priming": "0", + "skirt_speed": "50", + "slice_closing_radius": "0.049", + "slicing_mode": "regular", + "slow_down_layers": "0", + "slowdown_for_curled_perimeters": "0", + "small_area_infill_flow_compensation": "0", + "small_area_infill_flow_compensation_model": "0,0;\n0.2,0.4444;\n0.4,0.6145;\n0.6,0.7059;\n0.8,0.7619;\n1.5,0.8571;\n2,0.8889;\n3,0.9231;\n5,0.9520;\n10,1", + "small_perimeter_speed": "30%", + "small_perimeter_threshold": "20", + "solid_infill_filament": "1", + "sparse_infill_acceleration": "100%", + "sparse_infill_filament": "1", + "speed_limit_to_height_enable": "0", + "spiral_mode_max_xy_smoothing": "200%", + "spiral_mode_smooth": "0", + "staggered_inner_seams": "1", + "support_angle": "0", + "support_bottom_interface_spacing": "0.5", + "support_critical_regions_only": "0", + "support_interface_not_for_body": "1", + "support_interface_pattern": "auto", + "support_remove_small_overhang": "1", + "support_xy_overrides_z": "xy_overrides_z", + "thick_bridges": "0", + "thick_internal_bridges": "0", + "timelapse_type": "0", + "top_solid_infill_flow_ratio": "1", + "top_surface_jerk": "6", + "travel_jerk": "6", + "travel_speed_z": "0", + "tree_support_adaptive_layer_height": "1", + "tree_support_angle_slow": "25", + "tree_support_auto_brim": "1", + "tree_support_branch_angle_organic": "40", + "tree_support_branch_diameter_angle": "5", + "tree_support_branch_diameter_double_wall": "3", + "tree_support_branch_diameter_organic": "2", + "tree_support_branch_distance": "5", + "tree_support_branch_distance_organic": "1", + "tree_support_brim_width": "3", + "tree_support_tip_diameter": "0.82", + "tree_support_top_rate": "30%", + "wall_direction": "auto", + "wall_distribution_count": "1", + "wall_filament": "1", + "wall_generator": "classic", + "wall_sequence": "inner wall/outer wall", + "wall_transition_angle": "10", + "wall_transition_filter_deviation": "25%", + "wall_transition_length": "100%", + "wipe_before_external_loop": "0", + "wipe_on_loops": "0", + "wipe_speed": "80%", + "wipe_tower_bridging": "10", + "wipe_tower_cone_angle": "0", + "wipe_tower_extra_spacing": "100%", + "wipe_tower_rotation_angle": "0", + "wiping_volumes_extruders": "70,70,70,70,70,70,70,70,70,70" +} diff --git a/resources/profiles/FLSun.json b/resources/profiles/FLSun.json index e0a9cfd88e..8e234dffca 100644 --- a/resources/profiles/FLSun.json +++ b/resources/profiles/FLSun.json @@ -1,6 +1,6 @@ { "name": "FLSun", - "version": "02.04.00.01", + "version": "02.04.00.02", "force_update": "0", "description": "FLSun configurations", "machine_model_list": [ diff --git a/resources/profiles/FLSun/machine/FLSun QQ-S Pro 0.4 nozzle.json b/resources/profiles/FLSun/machine/FLSun QQ-S Pro 0.4 nozzle.json index 02b345c4bf..ef1dd22c15 100644 --- a/resources/profiles/FLSun/machine/FLSun QQ-S Pro 0.4 nozzle.json +++ b/resources/profiles/FLSun/machine/FLSun QQ-S Pro 0.4 nozzle.json @@ -182,7 +182,7 @@ "default_filament_profile": [ "FLSun Generic PLA" ], - "machine_start_gcode": ";STARTGCODE\nM117 Initializing\n; Set coordinate modes\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\n; Reset speed and extrusion rates\nM200 D0 ; disable volumetric E\nM220 S100 ; reset speed\n; Set initial warmup temps\nM117 Nozzle preheat\nM104 S100 ; preheat extruder to no ooze temp\nM140 S[bed_temperature_initial_layer_single] ; set bed temp\nM190 S[bed_temperature_initial_layer_single] ; wait for bed final temp\nM300 S40 P10 ; Bip\n; Home\nM117 Homing\nG28 ; home all with default mesh bed level\n; For ABL users put G29 for a leveling request\n; Final warmup routine\nM117 Final warmup\nM104 S[nozzle_temperature_initial_layer] ; set extruder final temp\nM109 S[nozzle_temperature_initial_layer] ; wait for extruder final temp\nM190 S[bed_temperature_initial_layer_single] ; wait for bed final temp\nM300 S440 P200; 1st beep for printer ready and allow some time to clean nozzle\nM300 S0 P250; wait between dual beep\nM300 S440 P200; 2nd beep for printer ready\nG4 S10; wait to clean the nozzle\nM300 S440 P200; 3rd beep for ready to start printing\n; Prime line routine\nM117 Printing prime line\n;M900 K0; Disable Linear Advance (Marlin) for prime line\nG92 E0.0; reset extrusion distance\nG1 X-54.672 Y-95.203 Z0.3 F4000; go outside print area\nG92 E0.0; reset extrusion distance\nG1 E2 F1000 ; de-retract and push ooze\nG3 X38.904 Y-102.668 I54.672 J95.105 E20.999\nG3 X54.671 Y-95.203 I-38.815 J102.373 E5.45800\nG92 E0.0\nG1 E-5 F3000 ; retract 5mm\nG1 X52.931 Y-96.185 F1000 ; wipe\nG1 X50.985 Y-97.231 F1000 ; wipe\nG1 X49.018 Y-98.238 F1000 ; wipe\nG1 X0 Y-109.798 F1000\nG1 E4.8 F1500; de-retract\nG92 E0.0 ; reset extrusion distance\n; Final print adjustments\nM117 Preparing to print\n;M82 ; extruder absolute mode\nM221 S{if layer_height<0.075}100{else}95{endif}\nM300 S40 P10 ; chirp\nM117 Print [output_filename_format]; Display: Printing started...", + "machine_start_gcode": ";STARTGCODE\nM117 Initializing\n; Set coordinate modes\nG90 ; use absolute coordinates\nM83 ; extruder relative mode\n; Reset speed and extrusion rates\nM200 D0 ; disable volumetric E\nM220 S100 ; reset speed\n; Set initial warmup temps\nM117 Nozzle preheat\nM104 S100 ; preheat extruder to no ooze temp\nM140 S[bed_temperature_initial_layer_single] ; set bed temp\nM190 S[bed_temperature_initial_layer_single] ; wait for bed final temp\nM300 S40 P10 ; Bip\n; Home\nM117 Homing\nG28 ; home all with default mesh bed level\n; For ABL users put G29 for a leveling request\n; Final warmup routine\nM117 Final warmup\nM104 S[nozzle_temperature_initial_layer] ; set extruder final temp\nM109 S[nozzle_temperature_initial_layer] ; wait for extruder final temp\nM190 S[bed_temperature_initial_layer_single] ; wait for bed final temp\nM300 S440 P200; 1st beep for printer ready and allow some time to clean nozzle\nM300 S0 P250; wait between dual beep\nM300 S440 P200; 2nd beep for printer ready\nG4 S10; wait to clean the nozzle\nM300 S440 P200; 3rd beep for ready to start printing\n; Prime line routine\nM117 Printing prime line\n;M900 K0; Disable Linear Advance (Marlin) for prime line\nG92 E0.0; reset extrusion distance\nG1 X-54.672 Y-95.203 Z0.3 F4000; go outside print area\nG92 E0.0; reset extrusion distance\nG1 E2 F1000 ; de-retract and push ooze\nG3 X38.904 Y-102.668 I54.672 J95.105 E20.999\nG3 X54.671 Y-95.203 I-38.815 J102.373 E5.45800\nG92 E0.0\nG1 E-5 F3000 ; retract 5mm\nG1 X52.931 Y-96.185 F1000 ; wipe\nG1 X50.985 Y-97.231 F1000 ; wipe\nG1 X49.018 Y-98.238 F1000 ; wipe\nG1 X0 Y-109.798 F1000\nG1 E4.8 F1500; de-retract\nG92 E0.0 ; reset extrusion distance\n; Final print adjustments\nM117 Preparing to print\n;M82 ; extruder absolute mode\nM221 S{if layer_height<0.075}100{else}95{endif}\nM300 S40 P10 ; chirp\nM117 Print [input_filename_base]; Display: Printing started...", "machine_end_gcode": "; printing object ENDGCODE\nG92 E0.0 ; prepare to retract\nG1 E-6 F3000; retract to avoid stringing\n; Anti-stringing end wiggle\n{if layer_z < max_print_height}G1 Z{min(layer_z+100, max_print_height)}{endif} F4000 ; Move print head up\nG1 X0 Y120 F3000 ; present print\n; Reset print setting overrides\nG92 E0\nM200 D0 ; disable volumetric e\nM220 S100 ; reset speed factor to 100%\nM221 S100 ; reset extruder factor to 100%\n;M900 K0 ; reset linear acceleration(Marlin)\n; Shut down printer\nM104 S0 ; turn off temperature\nM140 S0 ; turn off heatbed\nM107 ; turn off fan\nM18 S180 ;disable motors after 180s\nM300 S40 P10 ; Bip\nM117 Print finish.", "scan_first_layer": "0" } diff --git a/resources/profiles/Ginger Additive.json b/resources/profiles/Ginger Additive.json index 6ca48c71ec..ff4c3bec09 100644 --- a/resources/profiles/Ginger Additive.json +++ b/resources/profiles/Ginger Additive.json @@ -1,6 +1,6 @@ { "name": "Ginger Additive", - "version": "02.04.00.02", + "version": "02.04.00.03", "force_update": "1", "description": "Ginger configuration", "machine_model_list": [ diff --git a/resources/profiles/Ginger Additive/filament/Ginger Generic PETG.json b/resources/profiles/Ginger Additive/filament/Ginger Generic PETG.json index 45c67d8876..a84183df4d 100644 --- a/resources/profiles/Ginger Additive/filament/Ginger Generic PETG.json +++ b/resources/profiles/Ginger Additive/filament/Ginger Generic PETG.json @@ -18,7 +18,6 @@ "enable_pressure_advance": [ "1" ], - "extruder_rotation_volume": "624", "fan_cooling_layer_time": [ "100" ], @@ -94,13 +93,6 @@ "hot_plate_temp_initial_layer": [ "75" ], - "mixing_stepper_rotation_volume": "8000", - "multi_zone_1_initial_layer": "240", - "multi_zone_1_temperature": "240", - "multi_zone_2_initial_layer": "240", - "multi_zone_2_temperature": "240", - "multi_zone_3_initial_layer": "220", - "multi_zone_3_temperature": "220", "nozzle_temperature_range_high": [ "260" ], diff --git a/resources/profiles/Ginger Additive/filament/Ginger Generic PLA.json b/resources/profiles/Ginger Additive/filament/Ginger Generic PLA.json index 8038a710c0..1aaacd7e1e 100644 --- a/resources/profiles/Ginger Additive/filament/Ginger Generic PLA.json +++ b/resources/profiles/Ginger Additive/filament/Ginger Generic PLA.json @@ -18,7 +18,6 @@ "enable_pressure_advance": [ "1" ], - "extruder_rotation_volume": "456", "fan_cooling_layer_time": [ "100" ], @@ -94,13 +93,6 @@ "hot_plate_temp_initial_layer": [ "50" ], - "mixing_stepper_rotation_volume": "8000", - "multi_zone_1_initial_layer": "200", - "multi_zone_1_temperature": "200", - "multi_zone_2_initial_layer": "200", - "multi_zone_2_temperature": "200", - "multi_zone_3_initial_layer": "200", - "multi_zone_3_temperature": "200", "nozzle_temperature_range_high": [ "220" ], diff --git a/resources/profiles/Ginger Additive/machine/Ginger_G1_common.json b/resources/profiles/Ginger Additive/machine/Ginger_G1_common.json index db19aebd19..8b218915d1 100644 --- a/resources/profiles/Ginger Additive/machine/Ginger_G1_common.json +++ b/resources/profiles/Ginger Additive/machine/Ginger_G1_common.json @@ -69,7 +69,7 @@ "12", "12" ], - "machine_start_gcode": "START_PRINT BED_TEMPERATURE=[bed_temperature_initial_layer] KAMP_LEVELING=1 EXTRUDER_ROTATION_VOLUME={extruder_rotation_volume[0]} MIXING_STEPPER_ROTATION_VOLUME={mixing_stepper_rotation_volume[0]} PURGE_LAYER_HEIGHT=2 PURGE_PARKING_SPEED=10000 PURGE_LENGHT=500 PURGE_SPEED=500 PURGE_MATERIAL_QUANTITY=10000 EXTRUDER_TEMPERATURE=[nozzle_temperature] EXTRUDER_TEMPERATURE_INITIAL_LAYER=[nozzle_temperature_initial_layer] PRESSURE_ADVANCE=0.2 PRESSURE_ADVANCE_SMOOTH_TIME=0.5 ZONE_1_TEMPERATURE={multi_zone_1_initial_layer[0]} ZONE_2_TEMPERATURE={multi_zone_2_initial_layer[0]} ZONE_3_TEMPERATURE={multi_zone_3_initial_layer[0]}", + "machine_start_gcode": "START_PRINT BED_TEMPERATURE=[bed_temperature_initial_layer] KAMP_LEVELING=1 PURGE_LAYER_HEIGHT=2 PURGE_PARKING_SPEED=10000 PURGE_LENGHT=500 PURGE_SPEED=500 PURGE_MATERIAL_QUANTITY=10000 EXTRUDER_TEMPERATURE=[nozzle_temperature] EXTRUDER_TEMPERATURE_INITIAL_LAYER=[nozzle_temperature_initial_layer] PRESSURE_ADVANCE=0.2 PRESSURE_ADVANCE_SMOOTH_TIME=0.5", "print_host": "G1OS.local", "printer_model": "Ginger G1", "retract_before_wipe": [ @@ -98,12 +98,5 @@ "z_hop_types": [ "Normal Lift" ], - "pellet_modded_printer": "1", - "use_extruder_rotation_volume": "1", - "use_active_pellet_feeding": "1", - "multi_zone": "1", - "multi_zone_number": "3", - "active_feeder_motor_name": [ - "mixing_stepper" - ] + "pellet_modded_printer": "1" } diff --git a/resources/profiles/Qidi.json b/resources/profiles/Qidi.json index 9b3eeedca3..9e7a290f96 100644 --- a/resources/profiles/Qidi.json +++ b/resources/profiles/Qidi.json @@ -1,6 +1,6 @@ { "name": "Qidi", - "version": "02.04.00.06", + "version": "02.04.00.08", "force_update": "0", "description": "Qidi configurations", "machine_model_list": [ diff --git a/resources/profiles/Qidi/machine/fdm_qidi_x3_common.json b/resources/profiles/Qidi/machine/fdm_qidi_x3_common.json index ada1be5d24..9796856379 100644 --- a/resources/profiles/Qidi/machine/fdm_qidi_x3_common.json +++ b/resources/profiles/Qidi/machine/fdm_qidi_x3_common.json @@ -10,36 +10,6 @@ "machine_pause_gcode": "M0", "support_chamber_temp_control": "1", "wipe_tower_type": "type1", - "filament_dev_ams_drying_ams_limitations": [ - "1" - ], - "filament_dev_ams_drying_temperature": [ - "40.0", - "40.0", - "40.0", - "40.0" - ], - "filament_dev_ams_drying_time": [ - "8.0", - "8.0", - "8.0", - "8.0" - ], - "filament_dev_drying_softening_temperature": [ - "40.0" - ], - "filament_dev_ams_drying_heat_distortion_temperature": [ - "45.0" - ], - "filament_dev_drying_cooling_temperature": [ - "35.0" - ], - "filament_dev_chamber_drying_bed_temperature": [ - "90.0" - ], - "filament_dev_chamber_drying_time": [ - "12.0" - ], "retraction_length": [ "1" ], diff --git a/resources/profiles/Qidi/process/fdm_process_n_common.json b/resources/profiles/Qidi/process/fdm_process_n_common.json index df7ff0f1a4..629d64338d 100644 --- a/resources/profiles/Qidi/process/fdm_process_n_common.json +++ b/resources/profiles/Qidi/process/fdm_process_n_common.json @@ -84,7 +84,6 @@ "locked_skin_infill_pattern": "crosszag", "locked_skeleton_infill_pattern": "zigzag", "max_travel_detour_distance": "0", - "machine_prepare_compensation_time": "260", "minimum_sparse_infill_area": "15", "only_one_wall_top": "1", "outer_wall_acceleration": [ diff --git a/resources/profiles/Ratrig.json b/resources/profiles/Ratrig.json index ce68226513..969794f578 100644 --- a/resources/profiles/Ratrig.json +++ b/resources/profiles/Ratrig.json @@ -206,6 +206,10 @@ "name": "0.30mm Big @RatRig V-Core 4 0.6", "sub_path": "process/0.30mm Big @RatRig V-Core 4 0.6.json" }, + { + "name": "0.30mm Big @RatRig V-Core 4 0.8", + "sub_path": "process/0.30mm Big @RatRig V-Core 4 0.8.json" + }, { "name": "0.30mm Big @RatRig V-Core 4 HYBRID 0.6", "sub_path": "process/0.30mm Big @RatRig V-Core 4 HYBRID 0.6.json" diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json index b6ef786ec4..28412dd804 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 300 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "RatRig V-Core 4 300 0.8 nozzle", "inherits": "fdm_klipper_common", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "feTeGuFkLzWFFSC4", "instantiation": "true", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json index f80890c099..a40343b574 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 400 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "RatRig V-Core 4 400 0.8 nozzle", "inherits": "fdm_klipper_common", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "DQ7Lzsuk87A4qtav", "instantiation": "true", diff --git a/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json b/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json index d6d1efa7e6..828b2d8711 100644 --- a/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json +++ b/resources/profiles/Ratrig/machine/RatRig V-Core 4 500 0.8 nozzle.json @@ -2,6 +2,7 @@ "type": "machine", "name": "RatRig V-Core 4 500 0.8 nozzle", "inherits": "fdm_klipper_common", + "default_print_profile": "0.30mm Big @RatRig V-Core 4 0.8", "from": "system", "setting_id": "VMKIyofeEpPvUvkY", "instantiation": "true", diff --git a/resources/profiles/Ratrig/process/0.30mm Big @RatRig V-Core 4 0.8.json b/resources/profiles/Ratrig/process/0.30mm Big @RatRig V-Core 4 0.8.json new file mode 100644 index 0000000000..9069167cde --- /dev/null +++ b/resources/profiles/Ratrig/process/0.30mm Big @RatRig V-Core 4 0.8.json @@ -0,0 +1,67 @@ +{ + "type": "process", + "name": "0.30mm Big @RatRig V-Core 4 0.8", + "inherits": "fdm_process_ratrig_common", + "from": "system", + "setting_id": "2tM04aSQ8NcTsmQo", + "instantiation": "true", + "layer_height": "0.3", + "inital_layer_height": "0.35", + "wall_count": "3", + "top_shell_layers": "4", + "bottom_shell_layers": "3", + "top_shell_thickness": "0", + "sparse_infill_density": "25%", + "infill_anchor": "600%", + "infill_anchor_max": "5", + "infill_combination": "1", + "skirt_loops": "2", + "skirt_distance": "10", + "support_threshold_angle": "65", + "support_bottom_z_distance": "0.2", + "support_on_build_plate_only": "1", + "support_object_xy_distance": "60%", + "inner_wall_speed": "300", + "small_perimeter_speed": "250", + "outer_wall_speed": "250", + "sparse_infill_speed": "400", + "internal_solid_infill_speed": "100%", + "top_surface_speed": "100%", + "support_speed": "50", + "support_interface_speed": "100%", + "bridge_speed": "50", + "gap_infill_speed": "200", + "travel_speed": "600", + "initial_layer_speed": "80", + "enable_overhang_speed": "1", + "overhang_1_4_speed": "20", + "overhang_2_4_speed": "45", + "overhang_3_4_speed": "80", + "overhang_4_4_speed": "100", + "outer_wall_acceleration": "8000", + "inner_wall_acceleration": "10000", + "top_surface_acceleration": "0", + "internal_solid_infill_acceleration": "0", + "sparse_infill_acceleration": "15000", + "bridge_acceleration": "5000", + "initial_layer_acceleration": "2500", + "travel_acceleration": "15000", + "default_acceleration": "15000", + "line_width": "0.75", + "initial_layer_line_width": "1.1", + "inner_wall_line_width": "0.75", + "outer_wall_line_width": "0.70", + "sparse_infill_line_width": "0.75", + "internal_solid_infill_line_width": "0.75", + "top_surface_line_width": "0.75", + "support_line_width": "0.75", + "infill_wall_overlap": "18%", + "bridge_flow": "0.85", + "resolution": "0.0125", + "elefant_foot_compensation": "0.1", + "compatible_printers": [ + "RatRig V-Core 4 300 0.8 nozzle", + "RatRig V-Core 4 400 0.8 nozzle", + "RatRig V-Core 4 500 0.8 nozzle" + ] +} diff --git a/resources/profiles/iQ.json b/resources/profiles/iQ.json index a0a64b3593..4afcb18328 100644 --- a/resources/profiles/iQ.json +++ b/resources/profiles/iQ.json @@ -75,6 +75,30 @@ { "name": "0.20mm Standard @iQ TiQ8 P1 - ABS Natur Material4Print (0.4 Nozzle)", "sub_path": "process/0.20mm Standard @iQ TiQ8 P1 - ABS Natur Material4Print (0.4 Nozzle).json" + }, + { + "name": "0.15mm Standard @iQ TiQ2 (0.25 Nozzle)", + "sub_path": "process/0.15mm Standard @iQ TiQ2 (0.25 Nozzle).json" + }, + { + "name": "0.30mm Standard @iQ TiQ2 (0.6 Nozzle)", + "sub_path": "process/0.30mm Standard @iQ TiQ2 (0.6 Nozzle).json" + }, + { + "name": "0.40mm Standard @iQ TiQ2 (0.8 Nozzle)", + "sub_path": "process/0.40mm Standard @iQ TiQ2 (0.8 Nozzle).json" + }, + { + "name": "0.15mm Standard @iQ TiQ8 (0.25 Nozzle)", + "sub_path": "process/0.15mm Standard @iQ TiQ8 (0.25 Nozzle).json" + }, + { + "name": "0.30mm Standard @iQ TiQ8 (0.6 Nozzle)", + "sub_path": "process/0.30mm Standard @iQ TiQ8 (0.6 Nozzle).json" + }, + { + "name": "0.40mm Standard @iQ TiQ8 (0.8 Nozzle)", + "sub_path": "process/0.40mm Standard @iQ TiQ8 (0.8 Nozzle).json" } ], "filament_list": [ diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json index 69ad99e3c4..d0150d76e4 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.25 nozzle.json @@ -1,134 +1,135 @@ -{ - "type": "machine", - "name": "iQ TiQ2 0.25 Nozzle", - "inherits": "fdm_tiq_common", - "from": "system", - "setting_id": "cIJ59rG6rulmYsqA", - "instantiation": "true", - "printer_settings_id": "iQ TiQ2 0.25 Nozzle", - "printer_model": "TiQ2", - "printer_variant": "0.25", - "printer_notes": "Machine file version 1.0 20251106", - "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", - "deretraction_speed": [ - "30", - "30" - ], - "disable_m73": "1", - "emit_machine_limits_to_gcode": "0", - "enable_filament_ramming": "0", - "extruder_colour": [ - "#FCE94F", - "#FCE94F" - ], - "extruder_offset": [ - "0x0", - "0x0" - ], - "gcode_flavor": "marlin", - "host_type": "simplyprint", - "long_retractions_when_cut": [ - "0", - "0" - ], - "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", - "machine_max_speed_z": [ - "15", - "12" - ], - "machine_pause_gcode": "M10710 S0", - "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", - "max_layer_height": [ - "0.2", - "0.2" - ], - "min_layer_height": [ - "0.08", - "0.08" - ], - "nozzle_diameter": [ - "0.25", - "0.25" - ], - "print_host": "https://simplyprint.io/panel", - "printable_area": [ - "0x0", - "330x0", - "330x330", - "0x330" - ], - "printable_height": "300", - "retract_before_wipe": [ - "70%", - "70%" - ], - "retract_length_toolchange": [ - "10", - "12" - ], - "retract_lift_above": [ - "0", - "0" - ], - "retract_lift_below": [ - "0", - "0" - ], - "retract_lift_enforce": [ - "All Surfaces", - "All Surfaces" - ], - "retract_on_top_layer": [ - "1", - "1" - ], - "retract_restart_extra": [ - "0", - "0" - ], - "retract_restart_extra_toolchange": [ - "-0.2", - "-0.2" - ], - "retract_when_changing_layer": [ - "1", - "1" - ], - "retraction_distances_when_cut": [ - "18", - "18" - ], - "retraction_length": [ - "0.8", - "0.9" - ], - "retraction_minimum_travel": [ - "1", - "1" - ], - "retraction_speed": [ - "30", - "30" - ], - "thumbnails": "", - "travel_slope": [ - "3", - "3" - ], - "wipe": [ - "1", - "1" - ], - "wipe_distance": [ - "1", - "1" - ], - "z_hop": [ - "0.25", - "0.25" - ], - "z_hop_types": [ - "Normal Lift", - "Normal Lift" - ] -} +{ + "type": "machine", + "name": "iQ TiQ2 0.25 Nozzle", + "inherits": "fdm_tiq_common", + "from": "system", + "setting_id": "cIJ59rG6rulmYsqA", + "instantiation": "true", + "printer_settings_id": "iQ TiQ2 0.25 Nozzle", + "printer_model": "TiQ2", + "printer_variant": "0.25", + "default_print_profile": "0.15mm Standard @iQ TiQ2 (0.25 Nozzle)", + "printer_notes": "Machine file version 1.0 20251106", + "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", + "deretraction_speed": [ + "30", + "30" + ], + "disable_m73": "1", + "emit_machine_limits_to_gcode": "0", + "enable_filament_ramming": "0", + "extruder_colour": [ + "#FCE94F", + "#FCE94F" + ], + "extruder_offset": [ + "0x0", + "0x0" + ], + "gcode_flavor": "marlin", + "host_type": "simplyprint", + "long_retractions_when_cut": [ + "0", + "0" + ], + "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_pause_gcode": "M10710 S0", + "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", + "max_layer_height": [ + "0.2", + "0.2" + ], + "min_layer_height": [ + "0.08", + "0.08" + ], + "nozzle_diameter": [ + "0.25", + "0.25" + ], + "print_host": "https://simplyprint.io/panel", + "printable_area": [ + "0x0", + "330x0", + "330x330", + "0x330" + ], + "printable_height": "300", + "retract_before_wipe": [ + "70%", + "70%" + ], + "retract_length_toolchange": [ + "10", + "12" + ], + "retract_lift_above": [ + "0", + "0" + ], + "retract_lift_below": [ + "0", + "0" + ], + "retract_lift_enforce": [ + "All Surfaces", + "All Surfaces" + ], + "retract_on_top_layer": [ + "1", + "1" + ], + "retract_restart_extra": [ + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "-0.2", + "-0.2" + ], + "retract_when_changing_layer": [ + "1", + "1" + ], + "retraction_distances_when_cut": [ + "18", + "18" + ], + "retraction_length": [ + "0.8", + "0.9" + ], + "retraction_minimum_travel": [ + "1", + "1" + ], + "retraction_speed": [ + "30", + "30" + ], + "thumbnails": "", + "travel_slope": [ + "3", + "3" + ], + "wipe": [ + "1", + "1" + ], + "wipe_distance": [ + "1", + "1" + ], + "z_hop": [ + "0.25", + "0.25" + ], + "z_hop_types": [ + "Normal Lift", + "Normal Lift" + ] +} diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json index 7ed46af6af..efb586ab4b 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.6 nozzle.json @@ -1,134 +1,135 @@ -{ - "type": "machine", - "name": "iQ TiQ2 0.6 Nozzle", - "inherits": "fdm_tiq_common", - "from": "system", - "setting_id": "U5GboRipEfd1fsBm", - "instantiation": "true", - "printer_settings_id": "iQ TiQ2 0.6 Nozzle", - "printer_model": "TiQ2", - "printer_variant": "0.6", - "printer_notes": "Machine file version 1.0 20251106", - "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", - "deretraction_speed": [ - "30", - "30" - ], - "disable_m73": "1", - "emit_machine_limits_to_gcode": "0", - "enable_filament_ramming": "0", - "extruder_colour": [ - "#FCE94F", - "#FCE94F" - ], - "extruder_offset": [ - "0x0", - "0x0" - ], - "gcode_flavor": "marlin", - "host_type": "simplyprint", - "long_retractions_when_cut": [ - "0", - "0" - ], - "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", - "machine_max_speed_z": [ - "15", - "12" - ], - "machine_pause_gcode": "M10710 S0", - "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", - "max_layer_height": [ - "0.6", - "0.6" - ], - "min_layer_height": [ - "0.08", - "0.08" - ], - "nozzle_diameter": [ - "0.6", - "0.6" - ], - "print_host": "https://simplyprint.io/panel", - "printable_area": [ - "0x0", - "330x0", - "330x330", - "0x330" - ], - "printable_height": "300", - "retract_before_wipe": [ - "70%", - "70%" - ], - "retract_length_toolchange": [ - "10", - "12" - ], - "retract_lift_above": [ - "0", - "0" - ], - "retract_lift_below": [ - "0", - "0" - ], - "retract_lift_enforce": [ - "All Surfaces", - "All Surfaces" - ], - "retract_on_top_layer": [ - "1", - "1" - ], - "retract_restart_extra": [ - "0", - "0" - ], - "retract_restart_extra_toolchange": [ - "-0.2", - "-0.2" - ], - "retract_when_changing_layer": [ - "1", - "1" - ], - "retraction_distances_when_cut": [ - "18", - "18" - ], - "retraction_length": [ - "0.8", - "0.9" - ], - "retraction_minimum_travel": [ - "1", - "1" - ], - "retraction_speed": [ - "30", - "30" - ], - "thumbnails": "", - "travel_slope": [ - "3", - "3" - ], - "wipe": [ - "1", - "1" - ], - "wipe_distance": [ - "1", - "1" - ], - "z_hop": [ - "0.6", - "0.6" - ], - "z_hop_types": [ - "Normal Lift", - "Normal Lift" - ] -} +{ + "type": "machine", + "name": "iQ TiQ2 0.6 Nozzle", + "inherits": "fdm_tiq_common", + "from": "system", + "setting_id": "U5GboRipEfd1fsBm", + "instantiation": "true", + "printer_settings_id": "iQ TiQ2 0.6 Nozzle", + "printer_model": "TiQ2", + "printer_variant": "0.6", + "default_print_profile": "0.30mm Standard @iQ TiQ2 (0.6 Nozzle)", + "printer_notes": "Machine file version 1.0 20251106", + "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", + "deretraction_speed": [ + "30", + "30" + ], + "disable_m73": "1", + "emit_machine_limits_to_gcode": "0", + "enable_filament_ramming": "0", + "extruder_colour": [ + "#FCE94F", + "#FCE94F" + ], + "extruder_offset": [ + "0x0", + "0x0" + ], + "gcode_flavor": "marlin", + "host_type": "simplyprint", + "long_retractions_when_cut": [ + "0", + "0" + ], + "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_pause_gcode": "M10710 S0", + "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", + "max_layer_height": [ + "0.6", + "0.6" + ], + "min_layer_height": [ + "0.08", + "0.08" + ], + "nozzle_diameter": [ + "0.6", + "0.6" + ], + "print_host": "https://simplyprint.io/panel", + "printable_area": [ + "0x0", + "330x0", + "330x330", + "0x330" + ], + "printable_height": "300", + "retract_before_wipe": [ + "70%", + "70%" + ], + "retract_length_toolchange": [ + "10", + "12" + ], + "retract_lift_above": [ + "0", + "0" + ], + "retract_lift_below": [ + "0", + "0" + ], + "retract_lift_enforce": [ + "All Surfaces", + "All Surfaces" + ], + "retract_on_top_layer": [ + "1", + "1" + ], + "retract_restart_extra": [ + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "-0.2", + "-0.2" + ], + "retract_when_changing_layer": [ + "1", + "1" + ], + "retraction_distances_when_cut": [ + "18", + "18" + ], + "retraction_length": [ + "0.8", + "0.9" + ], + "retraction_minimum_travel": [ + "1", + "1" + ], + "retraction_speed": [ + "30", + "30" + ], + "thumbnails": "", + "travel_slope": [ + "3", + "3" + ], + "wipe": [ + "1", + "1" + ], + "wipe_distance": [ + "1", + "1" + ], + "z_hop": [ + "0.6", + "0.6" + ], + "z_hop_types": [ + "Normal Lift", + "Normal Lift" + ] +} diff --git a/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json index d019b20c24..3758f03508 100644 --- a/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ2 0.8 nozzle.json @@ -1,134 +1,135 @@ -{ - "type": "machine", - "name": "iQ TiQ2 0.8 Nozzle", - "inherits": "fdm_tiq_common", - "from": "system", - "setting_id": "Hnv1OfrxjIFdQTpK", - "instantiation": "true", - "printer_settings_id": "iQ TiQ2 0.8 Nozzle", - "printer_model": "TiQ2", - "printer_variant": "0.8", - "printer_notes": "Machine file version 1.0 20251106", - "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", - "deretraction_speed": [ - "30", - "30" - ], - "disable_m73": "1", - "emit_machine_limits_to_gcode": "0", - "enable_filament_ramming": "0", - "extruder_colour": [ - "#FCE94F", - "#FCE94F" - ], - "extruder_offset": [ - "0x0", - "0x0" - ], - "gcode_flavor": "marlin", - "host_type": "simplyprint", - "long_retractions_when_cut": [ - "0", - "0" - ], - "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", - "machine_max_speed_z": [ - "15", - "12" - ], - "machine_pause_gcode": "M10710 S0", - "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", - "max_layer_height": [ - "0.8", - "0.8" - ], - "min_layer_height": [ - "0.08", - "0.08" - ], - "nozzle_diameter": [ - "0.8", - "0.8" - ], - "print_host": "https://simplyprint.io/panel", - "printable_area": [ - "0x0", - "330x0", - "330x330", - "0x330" - ], - "printable_height": "300", - "retract_before_wipe": [ - "70%", - "70%" - ], - "retract_length_toolchange": [ - "10", - "12" - ], - "retract_lift_above": [ - "0", - "0" - ], - "retract_lift_below": [ - "0", - "0" - ], - "retract_lift_enforce": [ - "All Surfaces", - "All Surfaces" - ], - "retract_on_top_layer": [ - "1", - "1" - ], - "retract_restart_extra": [ - "0", - "0" - ], - "retract_restart_extra_toolchange": [ - "-0.2", - "-0.2" - ], - "retract_when_changing_layer": [ - "1", - "1" - ], - "retraction_distances_when_cut": [ - "18", - "18" - ], - "retraction_length": [ - "0.8", - "0.9" - ], - "retraction_minimum_travel": [ - "1", - "1" - ], - "retraction_speed": [ - "30", - "30" - ], - "thumbnails": "", - "travel_slope": [ - "3", - "3" - ], - "wipe": [ - "1", - "1" - ], - "wipe_distance": [ - "1", - "1" - ], - "z_hop": [ - "0.8", - "0.8" - ], - "z_hop_types": [ - "Normal Lift", - "Normal Lift" - ] -} +{ + "type": "machine", + "name": "iQ TiQ2 0.8 Nozzle", + "inherits": "fdm_tiq_common", + "from": "system", + "setting_id": "Hnv1OfrxjIFdQTpK", + "instantiation": "true", + "printer_settings_id": "iQ TiQ2 0.8 Nozzle", + "printer_model": "TiQ2", + "printer_variant": "0.8", + "default_print_profile": "0.40mm Standard @iQ TiQ2 (0.8 Nozzle)", + "printer_notes": "Machine file version 1.0 20251106", + "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\nG1 X32 Y3 F3000\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing\n", + "deretraction_speed": [ + "30", + "30" + ], + "disable_m73": "1", + "emit_machine_limits_to_gcode": "0", + "enable_filament_ramming": "0", + "extruder_colour": [ + "#FCE94F", + "#FCE94F" + ], + "extruder_offset": [ + "0x0", + "0x0" + ], + "gcode_flavor": "marlin", + "host_type": "simplyprint", + "long_retractions_when_cut": [ + "0", + "0" + ], + "machine_end_gcode": "G1 X-19 F3000 ; home X axis\nG1 Y1 F3000 ; home Y axis\nM104 S0 T0 ; turn off extruder\nM104 S0 T1 ; turn off extruder\nM104 S0 T2 ; turn off extruder\nM140 S0 ; turn off bed\nM106 S0 ; turn off fan\nM806 S0 ; turn of housing fan\nM84 ; disable motor\n", + "machine_max_speed_z": [ + "15", + "12" + ], + "machine_pause_gcode": "M10710 S0", + "machine_start_gcode": "T[initial_extruder]\nM109 S{nozzle_temperature_initial_layer[current_extruder]}\nG1 Z15 F900\nG1 X-19 Y1 F9000\nG1 X-19 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 Y1 F9000\nG1 Y45 F9000\nG1 X0", + "max_layer_height": [ + "0.8", + "0.8" + ], + "min_layer_height": [ + "0.08", + "0.08" + ], + "nozzle_diameter": [ + "0.8", + "0.8" + ], + "print_host": "https://simplyprint.io/panel", + "printable_area": [ + "0x0", + "330x0", + "330x330", + "0x330" + ], + "printable_height": "300", + "retract_before_wipe": [ + "70%", + "70%" + ], + "retract_length_toolchange": [ + "10", + "12" + ], + "retract_lift_above": [ + "0", + "0" + ], + "retract_lift_below": [ + "0", + "0" + ], + "retract_lift_enforce": [ + "All Surfaces", + "All Surfaces" + ], + "retract_on_top_layer": [ + "1", + "1" + ], + "retract_restart_extra": [ + "0", + "0" + ], + "retract_restart_extra_toolchange": [ + "-0.2", + "-0.2" + ], + "retract_when_changing_layer": [ + "1", + "1" + ], + "retraction_distances_when_cut": [ + "18", + "18" + ], + "retraction_length": [ + "0.8", + "0.9" + ], + "retraction_minimum_travel": [ + "1", + "1" + ], + "retraction_speed": [ + "30", + "30" + ], + "thumbnails": "", + "travel_slope": [ + "3", + "3" + ], + "wipe": [ + "1", + "1" + ], + "wipe_distance": [ + "1", + "1" + ], + "z_hop": [ + "0.8", + "0.8" + ], + "z_hop_types": [ + "Normal Lift", + "Normal Lift" + ] +} diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json index 6a9864b7ac..7409d9e6c6 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.25 nozzle.json @@ -8,6 +8,7 @@ "printer_settings_id": "iQ TiQ8 0.25 Nozzle", "printer_model": "TiQ8", "printer_variant": "0.25", + "default_print_profile": "0.15mm Standard @iQ TiQ8 (0.25 Nozzle)", "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\n{if next_extruder==0}G1 X30 Y-12 F9000{endif}\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing", "deretraction_speed": [ "30", diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json index 4d0cd06612..484f9275bf 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.4 nozzle.json @@ -8,6 +8,7 @@ "printer_settings_id": "iQ TiQ8 0.4 Nozzle", "printer_model": "TiQ8", "printer_variant": "0.4", + "default_print_profile": "0.20mm Standard @iQ TiQ8 P1 - ABS Natur Material4Print (0.4 Nozzle)", "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\n{if next_extruder==0}G1 X30 Y-12 F9000{endif}\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing", "deretraction_speed": [ "30", diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json index 33b9495ea0..6a12dcaaa0 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.6 nozzle.json @@ -8,6 +8,7 @@ "printer_settings_id": "iQ TiQ8 0.6 Nozzle", "printer_model": "TiQ8", "printer_variant": "0.6", + "default_print_profile": "0.30mm Standard @iQ TiQ8 (0.6 Nozzle)", "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\n{if next_extruder==0}G1 X30 Y-12 F9000{endif}\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing", "deretraction_speed": [ "30", diff --git a/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json b/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json index 411aaf2f5b..76fe177a16 100644 --- a/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json +++ b/resources/profiles/iQ/machine/iQ TiQ8 0.8 nozzle.json @@ -8,6 +8,7 @@ "printer_settings_id": "iQ TiQ8 0.8 Nozzle", "printer_model": "TiQ8", "printer_variant": "0.8", + "default_print_profile": "0.40mm Standard @iQ TiQ8 (0.8 Nozzle)", "change_filament_gcode": "G1 Z{layer_z+2} F900 ; safe distance while tool change\n{if next_extruder==0}G1 X30 Y-12 F9000{endif}\nM109 S{nozzle_temperature[next_extruder]} T[next_extruder] ; set new tool temperature so it can start heating while changing", "deretraction_speed": [ "30", diff --git a/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ2 (0.25 Nozzle).json b/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ2 (0.25 Nozzle).json new file mode 100644 index 0000000000..1791058107 --- /dev/null +++ b/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ2 (0.25 Nozzle).json @@ -0,0 +1,26 @@ +{ + "type": "process", + "name": "0.15mm Standard @iQ TiQ2 (0.25 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "PNxZXC0peOlGlKwG", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ2 0.25 Nozzle" + ], + "layer_height": "0.15", + "line_width": "0.25", + "outer_wall_line_width": "0.25", + "inner_wall_line_width": "0.25", + "sparse_infill_line_width": "0.25", + "internal_solid_infill_line_width": "0.25", + "top_surface_line_width": "0.25", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.15mm Standard @iQ TiQ2 (0.25 Nozzle)" +} diff --git a/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ8 (0.25 Nozzle).json b/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ8 (0.25 Nozzle).json new file mode 100644 index 0000000000..b643441055 --- /dev/null +++ b/resources/profiles/iQ/process/0.15mm Standard @iQ TiQ8 (0.25 Nozzle).json @@ -0,0 +1,26 @@ +{ + "type": "process", + "name": "0.15mm Standard @iQ TiQ8 (0.25 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "K0Ybw0qUqEIL05PY", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ8 0.25 Nozzle" + ], + "layer_height": "0.15", + "line_width": "0.25", + "outer_wall_line_width": "0.25", + "inner_wall_line_width": "0.25", + "sparse_infill_line_width": "0.25", + "internal_solid_infill_line_width": "0.25", + "top_surface_line_width": "0.25", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.15mm Standard @iQ TiQ8 (0.25 Nozzle)" +} diff --git a/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ2 (0.6 Nozzle).json b/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ2 (0.6 Nozzle).json new file mode 100644 index 0000000000..6a71a4ba84 --- /dev/null +++ b/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ2 (0.6 Nozzle).json @@ -0,0 +1,28 @@ +{ + "type": "process", + "name": "0.30mm Standard @iQ TiQ2 (0.6 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "IGN3ZUR73J0veLrE", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ2 0.6 Nozzle" + ], + "layer_height": "0.3", + "initial_layer_print_height": "0.3", + "line_width": "0.6", + "outer_wall_line_width": "0.6", + "inner_wall_line_width": "0.6", + "sparse_infill_line_width": "0.6", + "internal_solid_infill_line_width": "0.6", + "top_surface_line_width": "0.6", + "wall_loops": "2", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.30mm Standard @iQ TiQ2 (0.6 Nozzle)" +} diff --git a/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ8 (0.6 Nozzle).json b/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ8 (0.6 Nozzle).json new file mode 100644 index 0000000000..0c8a567846 --- /dev/null +++ b/resources/profiles/iQ/process/0.30mm Standard @iQ TiQ8 (0.6 Nozzle).json @@ -0,0 +1,28 @@ +{ + "type": "process", + "name": "0.30mm Standard @iQ TiQ8 (0.6 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "QEODQzrO9UZEgrtB", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ8 0.6 Nozzle" + ], + "layer_height": "0.3", + "initial_layer_print_height": "0.3", + "line_width": "0.6", + "outer_wall_line_width": "0.6", + "inner_wall_line_width": "0.6", + "sparse_infill_line_width": "0.6", + "internal_solid_infill_line_width": "0.6", + "top_surface_line_width": "0.6", + "wall_loops": "2", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.30mm Standard @iQ TiQ8 (0.6 Nozzle)" +} diff --git a/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ2 (0.8 Nozzle).json b/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ2 (0.8 Nozzle).json new file mode 100644 index 0000000000..5dba6b07c2 --- /dev/null +++ b/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ2 (0.8 Nozzle).json @@ -0,0 +1,28 @@ +{ + "type": "process", + "name": "0.40mm Standard @iQ TiQ2 (0.8 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "ZoiYkGXOTBh39HTB", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ2 0.8 Nozzle" + ], + "layer_height": "0.4", + "initial_layer_print_height": "0.4", + "line_width": "0.8", + "outer_wall_line_width": "0.8", + "inner_wall_line_width": "0.8", + "sparse_infill_line_width": "0.8", + "internal_solid_infill_line_width": "0.8", + "top_surface_line_width": "0.8", + "wall_loops": "2", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.40mm Standard @iQ TiQ2 (0.8 Nozzle)" +} diff --git a/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ8 (0.8 Nozzle).json b/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ8 (0.8 Nozzle).json new file mode 100644 index 0000000000..5cd189771f --- /dev/null +++ b/resources/profiles/iQ/process/0.40mm Standard @iQ TiQ8 (0.8 Nozzle).json @@ -0,0 +1,28 @@ +{ + "type": "process", + "name": "0.40mm Standard @iQ TiQ8 (0.8 Nozzle)", + "inherits": "fdm_process_tiq_common", + "from": "system", + "setting_id": "C7TZWdCzQroB8pKL", + "instantiation": "true", + "compatible_printers": [ + "iQ TiQ8 0.8 Nozzle" + ], + "layer_height": "0.4", + "initial_layer_print_height": "0.4", + "line_width": "0.8", + "outer_wall_line_width": "0.8", + "inner_wall_line_width": "0.8", + "sparse_infill_line_width": "0.8", + "internal_solid_infill_line_width": "0.8", + "top_surface_line_width": "0.8", + "wall_loops": "2", + "inner_wall_speed": "150", + "internal_solid_infill_speed": "150", + "sparse_infill_speed": "100", + "gap_infill_speed": "50", + "initial_layer_speed": "35", + "initial_layer_infill_speed": "55", + "bridge_speed": "30", + "print_settings_id": "0.40mm Standard @iQ TiQ8 (0.8 Nozzle)" +} diff --git a/resources/shaders/110/gouraud.fs b/resources/shaders/110/gouraud.fs index e602d6067d..59c4e4d410 100644 --- a/resources/shaders/110/gouraud.fs +++ b/resources/shaders/110/gouraud.fs @@ -46,10 +46,24 @@ uniform vec2 screen_size; #endif // ENABLE_ENVIRONMENT_MAP uniform PrintVolumeDetection print_volume; +// BBS H2D/H2C per-extruder printable height (3DScene.cpp): .x = flag (>=1 active), .y/.z = the two +// extruders' Z limits. Inert unless the CPU sets .x >= 1.0 (multi-extruder printers only), so the +// shared object shader stays pixel-identical for single-extruder printers. See 3DScene.cpp. +uniform vec3 extruder_printable_heights; +const float ONE_OVER_EPSILON = 1e4; uniform float z_far; uniform float z_near; +// Depth-based shadow map (object-on-object and self shadows). shadow_intensity == 0 disables it. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + +// LIGHT_TOP_DIR in eye space (matches the diffuse light used for shading in gouraud.vs). +const vec3 SHADOW_LIGHT_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); + varying vec3 clipping_planes_dots; varying float color_clip_plane_dot; @@ -125,6 +139,35 @@ float DetectSilho(vec2 fragCoord) ); } +// Returns a lighting multiplier in [1 - shadow_intensity, 1]: < 1 where the fragment is +// occluded from the light in the shadow map. 3x3 PCF softens the edges. +float shadow_shade() +{ + if (shadow_intensity <= 0.0) + return 1.0; + + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 1.0; + + // Slope-scaled depth bias: larger where the surface grazes / faces away from the light. This + // suppresses self-shadow acne without discarding real shadows cast by other objects onto + // back-facing surfaces (e.g. the shaded back/tip of a cone sitting inside a larger shadow). + float NdotL = dot(normalize(eye_normal), SHADOW_LIGHT_DIR); + float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0)); + // 5x5 PCF: softens shadow edges into a smooth penumbra and blurs residual facet acne. + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture2D(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return 1.0 - shadow_intensity * (sum / 25.0); +} + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) @@ -166,9 +209,20 @@ void main() } color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb; + // BBS per-extruder printable-height shading (H2D/H2C). Gated on the flag so it is inert for + // single-extruder printers. Darkens the band between the two extruders' Z limits inside the bed + // rect (the zone only the taller extruder can reach). Math kept byte-identical to BBS gouraud.fs. + if (extruder_printable_heights.x >= 1.0) { + vec3 eph_check_min = (world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, extruder_printable_heights.y)) * ONE_OVER_EPSILON; + vec3 eph_check_max = (world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, extruder_printable_heights.z)) * ONE_OVER_EPSILON; + bool is_out_printable_height = (all(greaterThan(eph_check_min, vec3(1.0))) && all(lessThan(eph_check_max, vec3(1.0)))); + color.rgb = is_out_printable_height ? mix(color.rgb, ZERO, 0.7) : color.rgb; + } + float shade = shadow_shade(); + //BBS: add outline_color if (is_outline) { - color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a); + color = vec4((vec3(intensity.y) + color.rgb * intensity.x) * shade, color.a); vec2 fragCoord = gl_FragCoord.xy; float s = DetectSilho(fragCoord); // Makes silhouettes thicker. @@ -176,13 +230,15 @@ void main() { s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0))); s = max(s, DetectSilho(fragCoord.xy + vec2(0, i))); - } + } + if (s < 0.01) + discard; gl_FragColor = vec4(mix(color.rgb, getBackfaceColor(color.rgb), s), color.a); } #ifdef ENABLE_ENVIRONMENT_MAP else if (use_environment_tex) - gl_FragColor = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a); + gl_FragColor = vec4((0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x) * shade, color.a); #endif else - gl_FragColor = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a); + gl_FragColor = vec4((vec3(intensity.y) + color.rgb * intensity.x) * shade, color.a); } \ No newline at end of file diff --git a/resources/shaders/110/gouraud.vs b/resources/shaders/110/gouraud.vs index ff3a190c79..184529be82 100644 --- a/resources/shaders/110/gouraud.vs +++ b/resources/shaders/110/gouraud.vs @@ -30,6 +30,8 @@ uniform mat4 projection_matrix; uniform mat3 view_normal_matrix; uniform mat4 volume_world_matrix; uniform SlopeDetection slope; +uniform bool is_outline; +uniform vec2 screen_size; // Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. uniform vec2 z_range; @@ -75,6 +77,15 @@ void main() world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; gl_Position = projection_matrix * position; + if (is_outline) { + vec3 n = normalize((view_normal_matrix * v_normal).xyz); + vec2 dir = normalize(n.xy); + if (dot(dir, dir) > 0.0) { + //set outline thickness + float px = 3.0; + gl_Position.xy += dir * (px * 2.0 / screen_size) * gl_Position.w; + } + } // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); color_clip_plane_dot = dot(world_pos, color_clip_plane); diff --git a/resources/shaders/110/imgui.fs b/resources/shaders/110/imgui.fs index 4b0e27ce9d..3af9c82653 100644 --- a/resources/shaders/110/imgui.fs +++ b/resources/shaders/110/imgui.fs @@ -1,11 +1,11 @@ #version 110 -uniform sampler2D Texture; +uniform sampler2D s_texture; varying vec2 Frag_UV; varying vec4 Frag_Color; void main() { - gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st); + gl_FragColor = Frag_Color * texture2D(s_texture, Frag_UV.st); } \ No newline at end of file diff --git a/resources/shaders/110/phong.fs b/resources/shaders/110/phong.fs index a0c6372ca5..5fedf7edff 100644 --- a/resources/shaders/110/phong.fs +++ b/resources/shaders/110/phong.fs @@ -65,6 +65,12 @@ uniform float z_far; uniform float z_near; uniform bool enable_ssao; +// Depth-based shadow map (object-on-object and self shadows). shadow_intensity == 0 disables it. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + varying vec3 clipping_planes_dots; varying float color_clip_plane_dot; @@ -167,10 +173,39 @@ vec3 compute_window_reflection(vec3 normal, vec3 view_dir) float intensity = window_light * bars * (0.15 + 0.15 * fresnel) * facing; intensity = clamp(intensity, 0.0, 0.25); - + return vec3(intensity); } +// Returns a lighting multiplier in [1 - shadow_intensity, 1]: < 1 where the fragment is +// occluded from the light in the shadow map. 3x3 PCF softens the edges. +float shadow_shade() +{ + if (shadow_intensity <= 0.0) + return 1.0; + + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 1.0; + + // Slope-scaled depth bias: larger where the surface grazes / faces away from the light. This + // suppresses self-shadow acne without discarding real shadows cast by other objects onto + // back-facing surfaces (e.g. the shaded back/tip of a cone sitting inside a larger shadow). + float NdotL = dot(normalize(eye_normal), LIGHT_TOP_DIR); + float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0)); + // 5x5 PCF: softens shadow edges into a smooth penumbra and blurs residual facet acne. + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture2D(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return 1.0 - shadow_intensity * (sum / 25.0); +} + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) @@ -226,8 +261,10 @@ void main() // SSAO is applied in post-process pass. Keep base lighting unchanged here. + float shade = shadow_shade(); + if (is_outline) { - vec3 shaded_rgb = (vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS; + vec3 shaded_rgb = (vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS * shade; vec4 shaded_color = vec4(clamp(shaded_rgb, vec3(0.0), vec3(1.0)), color.a); vec2 fragCoord = gl_FragCoord.xy; float s = DetectSilho(fragCoord); @@ -236,12 +273,14 @@ void main() s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0))); s = max(s, DetectSilho(fragCoord.xy + vec2(0, i))); } + if (s < 0.01) + discard; gl_FragColor = vec4(mix(shaded_color.rgb, getBackfaceColor(shaded_color.rgb), s), shaded_color.a); } #ifdef ENABLE_ENVIRONMENT_MAP else if (use_environment_tex) - gl_FragColor = vec4(clamp((0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + window_reflection + 0.8 * color.rgb * diffuse) * PHONG_BRIGHTNESS, vec3(0.0), vec3(1.0)), color.a); + gl_FragColor = vec4(clamp((0.45 * texture2D(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + window_reflection + 0.8 * color.rgb * diffuse) * PHONG_BRIGHTNESS * shade, vec3(0.0), vec3(1.0)), color.a); #endif else - gl_FragColor = vec4(clamp((vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS, vec3(0.0), vec3(1.0)), color.a); + gl_FragColor = vec4(clamp((vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS * shade, vec3(0.0), vec3(1.0)), color.a); } \ No newline at end of file diff --git a/resources/shaders/110/phong.vs b/resources/shaders/110/phong.vs index b9e90e7cc2..10d36e233f 100644 --- a/resources/shaders/110/phong.vs +++ b/resources/shaders/110/phong.vs @@ -14,6 +14,8 @@ uniform mat4 projection_matrix; uniform mat3 view_normal_matrix; uniform mat4 volume_world_matrix; uniform SlopeDetection slope; +uniform bool is_outline; +uniform vec2 screen_size; // Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. uniform vec2 z_range; @@ -48,6 +50,15 @@ void main() world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; gl_Position = projection_matrix * position; + if (is_outline) { + vec3 n = normalize((view_normal_matrix * v_normal).xyz); + vec2 dir = normalize(n.xy); + if (dot(dir, dir) > 0.0) { + //set outline thickness + float px = 3.0; + gl_Position.xy += dir * (px * 2.0 / screen_size) * gl_Position.w; + } + } // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); color_clip_plane_dot = dot(world_pos, color_clip_plane); diff --git a/resources/shaders/110/printbed_shadow.fs b/resources/shaders/110/printbed_shadow.fs new file mode 100644 index 0000000000..a4fd6801dd --- /dev/null +++ b/resources/shaders/110/printbed_shadow.fs @@ -0,0 +1,40 @@ +#version 110 + +// Draws the build-plate as a receiver of the same depth shadow map used for object/self shadows, +// so the plate, objects, and self-shadows all come from one unified technique. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + +varying vec4 world_pos; + +// Fraction of the 5x5 PCF kernel occluded from the light. Matches the object shadow shader. +float shadow_occlusion() +{ + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 0.0; + + // The plate is a pure receiver (never rendered into the shadow map), so a tiny constant + // bias for numerical safety is enough here. + float bias = 0.0004; + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture2D(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return sum / 25.0; +} + +void main() +{ + float occ = shadow_occlusion(); + if (occ <= 0.0) + discard; + gl_FragColor = vec4(0.0, 0.0, 0.0, shadow_intensity * occ); +} diff --git a/resources/shaders/110/printbed_shadow.vs b/resources/shaders/110/printbed_shadow.vs new file mode 100644 index 0000000000..d004fac7c9 --- /dev/null +++ b/resources/shaders/110/printbed_shadow.vs @@ -0,0 +1,16 @@ +#version 110 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +attribute vec3 v_position; + +// The plate mask quad is authored directly in world coordinates (z = 0 plane), +// so v_position is already the world position of the fragment. +varying vec4 world_pos; + +void main() +{ + world_pos = vec4(v_position, 1.0); + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/110/ssao.fs b/resources/shaders/110/ssao.fs index 43b52a3f29..5aada05883 100644 --- a/resources/shaders/110/ssao.fs +++ b/resources/shaders/110/ssao.fs @@ -11,6 +11,7 @@ uniform sampler2D normal_texture; uniform vec2 inv_tex_size; uniform float z_near; uniform float z_far; +uniform bool is_outline; varying vec2 tex_coord; @@ -22,6 +23,10 @@ float linearize_depth(float depth) void main() { + if (is_outline) { + gl_FragColor = vec4(texture2D(color_texture, tex_coord).rgb, 1.0); + return; + } vec3 base = texture2D(color_texture, tex_coord).rgb; float depth_center = linearize_depth(texture2D(depth_texture, tex_coord).r); diff --git a/resources/shaders/140/gouraud.fs b/resources/shaders/140/gouraud.fs index bbfb76f7a1..728b7f942c 100644 --- a/resources/shaders/140/gouraud.fs +++ b/resources/shaders/140/gouraud.fs @@ -45,10 +45,24 @@ uniform vec2 screen_size; #endif // ENABLE_ENVIRONMENT_MAP uniform PrintVolumeDetection print_volume; +// BBS H2D/H2C per-extruder printable height (3DScene.cpp): .x = flag (>=1 active), .y/.z = the two +// extruders' Z limits. Inert unless the CPU sets .x >= 1.0 (multi-extruder printers only), so the +// shared object shader stays pixel-identical for single-extruder printers. See 3DScene.cpp. +uniform vec3 extruder_printable_heights; +const float ONE_OVER_EPSILON = 1e4; uniform float z_far; uniform float z_near; +// Depth-based shadow map (object-on-object and self shadows). shadow_intensity == 0 disables it. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + +// LIGHT_TOP_DIR in eye space (matches the diffuse light used for shading in gouraud.vs). +const vec3 SHADOW_LIGHT_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); + in vec3 clipping_planes_dots; in float color_clip_plane_dot; @@ -124,6 +138,35 @@ float DetectSilho(vec2 fragCoord) ); } +// Returns a lighting multiplier in [1 - shadow_intensity, 1]: < 1 where the fragment is +// occluded from the light in the shadow map. 3x3 PCF softens the edges. +float shadow_shade() +{ + if (shadow_intensity <= 0.0) + return 1.0; + + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 1.0; + + // Slope-scaled depth bias: larger where the surface grazes / faces away from the light. This + // suppresses self-shadow acne without discarding real shadows cast by other objects onto + // back-facing surfaces (e.g. the shaded back/tip of a cone sitting inside a larger shadow). + float NdotL = dot(normalize(eye_normal), SHADOW_LIGHT_DIR); + float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0)); + // 5x5 PCF: softens shadow edges into a smooth penumbra and blurs residual facet acne. + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return 1.0 - shadow_intensity * (sum / 25.0); +} + out vec4 out_color; void main() @@ -167,9 +210,20 @@ void main() } color.rgb = (any(lessThan(pv_check_min, ZERO)) || any(greaterThan(pv_check_max, ZERO))) ? mix(color.rgb, ZERO, 0.3333) : color.rgb; + // BBS per-extruder printable-height shading (H2D/H2C). Gated on the flag so it is inert for + // single-extruder printers. Darkens the band between the two extruders' Z limits inside the bed + // rect (the zone only the taller extruder can reach). Math kept byte-identical to BBS gouraud.fs. + if (extruder_printable_heights.x >= 1.0) { + vec3 eph_check_min = (world_pos.xyz - vec3(print_volume.xy_data.x, print_volume.xy_data.y, extruder_printable_heights.y)) * ONE_OVER_EPSILON; + vec3 eph_check_max = (world_pos.xyz - vec3(print_volume.xy_data.z, print_volume.xy_data.w, extruder_printable_heights.z)) * ONE_OVER_EPSILON; + bool is_out_printable_height = (all(greaterThan(eph_check_min, vec3(1.0))) && all(lessThan(eph_check_max, vec3(1.0)))); + color.rgb = is_out_printable_height ? mix(color.rgb, ZERO, 0.7) : color.rgb; + } + float shade = shadow_shade(); + //BBS: add outline_color if (is_outline) { - color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a); + color = vec4((vec3(intensity.y) + color.rgb * intensity.x) * shade, color.a); vec2 fragCoord = gl_FragCoord.xy; float s = DetectSilho(fragCoord); // Makes silhouettes thicker. @@ -177,13 +231,15 @@ void main() { s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0))); s = max(s, DetectSilho(fragCoord.xy + vec2(0, i))); - } + } + if (s < 0.01) + discard; out_color = vec4(mix(color.rgb, getBackfaceColor(color.rgb), s), color.a); } #ifdef ENABLE_ENVIRONMENT_MAP else if (use_environment_tex) - out_color = vec4(0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x, color.a); + out_color = vec4((0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + 0.8 * color.rgb * intensity.x) * shade, color.a); #endif else - out_color = vec4(vec3(intensity.y) + color.rgb * intensity.x, color.a); + out_color = vec4((vec3(intensity.y) + color.rgb * intensity.x) * shade, color.a); } \ No newline at end of file diff --git a/resources/shaders/140/gouraud.vs b/resources/shaders/140/gouraud.vs index 72dd4ff1bf..a31e751964 100644 --- a/resources/shaders/140/gouraud.vs +++ b/resources/shaders/140/gouraud.vs @@ -30,6 +30,8 @@ uniform mat4 projection_matrix; uniform mat3 view_normal_matrix; uniform mat4 volume_world_matrix; uniform SlopeDetection slope; +uniform bool is_outline; +uniform vec2 screen_size; // Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. uniform vec2 z_range; @@ -75,6 +77,15 @@ void main() world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; gl_Position = projection_matrix * position; + if (is_outline) { + vec3 n = normalize((view_normal_matrix * v_normal).xyz); + vec2 dir = normalize(n.xy); + if (dot(dir, dir) > 0.0) { + //set outline thickness + float px = 3.0; + gl_Position.xy += dir * (px * 2.0 / screen_size) * gl_Position.w; + } + } // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); color_clip_plane_dot = dot(world_pos, color_clip_plane); diff --git a/resources/shaders/140/imgui.fs b/resources/shaders/140/imgui.fs index 1666c814eb..daebb189de 100644 --- a/resources/shaders/140/imgui.fs +++ b/resources/shaders/140/imgui.fs @@ -1,6 +1,6 @@ #version 140 -uniform sampler2D Texture; +uniform sampler2D s_texture; in vec2 Frag_UV; in vec4 Frag_Color; @@ -9,5 +9,5 @@ out vec4 out_color; void main() { - out_color = Frag_Color * texture(Texture, Frag_UV.st); + out_color = Frag_Color * texture(s_texture, Frag_UV.st); } \ No newline at end of file diff --git a/resources/shaders/140/phong.fs b/resources/shaders/140/phong.fs index d7456663ec..bbde72592c 100644 --- a/resources/shaders/140/phong.fs +++ b/resources/shaders/140/phong.fs @@ -65,6 +65,12 @@ uniform float z_far; uniform float z_near; uniform bool enable_ssao; +// Depth-based shadow map (object-on-object and self shadows). shadow_intensity == 0 disables it. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + in vec3 clipping_planes_dots; in float color_clip_plane_dot; @@ -170,11 +176,40 @@ vec3 compute_window_reflection(vec3 normal, vec3 view_dir) float intensity = window_light * bars * (0.15 + 0.15 * fresnel) * facing; - intensity = clamp(intensity, 0.0, 0.25); - + intensity = clamp(intensity, 0.0, 0.25); + return vec3(intensity); } +// Returns a lighting multiplier in [1 - shadow_intensity, 1]: < 1 where the fragment is +// occluded from the light in the shadow map. 3x3 PCF softens the edges. +float shadow_shade() +{ + if (shadow_intensity <= 0.0) + return 1.0; + + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 1.0; + + // Slope-scaled depth bias: larger where the surface grazes / faces away from the light. This + // suppresses self-shadow acne without discarding real shadows cast by other objects onto + // back-facing surfaces (e.g. the shaded back/tip of a cone sitting inside a larger shadow). + float NdotL = dot(normalize(eye_normal), LIGHT_TOP_DIR); + float bias = mix(0.0004, 0.004, clamp(1.0 - NdotL, 0.0, 1.0)); + // 5x5 PCF: softens shadow edges into a smooth penumbra and blurs residual facet acne. + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return 1.0 - shadow_intensity * (sum / 25.0); +} + void main() { if (any(lessThan(clipping_planes_dots, ZERO))) @@ -230,8 +265,10 @@ void main() // SSAO is applied in post-process pass. Keep base lighting unchanged here. + float shade = shadow_shade(); + if (is_outline) { - vec3 shaded_rgb = (vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS; + vec3 shaded_rgb = (vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS * shade; vec4 shaded_color = vec4(clamp(shaded_rgb, vec3(0.0), vec3(1.0)), color.a); vec2 fragCoord = gl_FragCoord.xy; float s = DetectSilho(fragCoord); @@ -240,12 +277,14 @@ void main() s = max(s, DetectSilho(fragCoord.xy + vec2(i, 0))); s = max(s, DetectSilho(fragCoord.xy + vec2(0, i))); } + if (s < 0.01) + discard; out_color = vec4(mix(shaded_color.rgb, getBackfaceColor(shaded_color.rgb), s), shaded_color.a); } #ifdef ENABLE_ENVIRONMENT_MAP else if (use_environment_tex) - out_color = vec4(clamp((0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + window_reflection + 0.8 * color.rgb * diffuse) * PHONG_BRIGHTNESS, vec3(0.0), vec3(1.0)), color.a); + out_color = vec4(clamp((0.45 * texture(environment_tex, normalize(eye_normal).xy * 0.5 + 0.5).xyz + window_reflection + 0.8 * color.rgb * diffuse) * PHONG_BRIGHTNESS * shade, vec3(0.0), vec3(1.0)), color.a); #endif else - out_color = vec4(clamp((vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS, vec3(0.0), vec3(1.0)), color.a); + out_color = vec4(clamp((vec3(specular) + window_reflection + color.rgb * diffuse) * PHONG_BRIGHTNESS * shade, vec3(0.0), vec3(1.0)), color.a); } \ No newline at end of file diff --git a/resources/shaders/140/phong.vs b/resources/shaders/140/phong.vs index 2ccbaf16ee..c7570edb95 100644 --- a/resources/shaders/140/phong.vs +++ b/resources/shaders/140/phong.vs @@ -14,6 +14,8 @@ uniform mat4 projection_matrix; uniform mat3 view_normal_matrix; uniform mat4 volume_world_matrix; uniform SlopeDetection slope; +uniform bool is_outline; +uniform vec2 screen_size; // Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. uniform vec2 z_range; @@ -48,6 +50,15 @@ void main() world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; gl_Position = projection_matrix * position; + if (is_outline) { + vec3 n = normalize((view_normal_matrix * v_normal).xyz); + vec2 dir = normalize(n.xy); + if (dot(dir, dir) > 0.0) { + //set outline thickness + float px = 3.0; + gl_Position.xy += dir * (px * 2.0 / screen_size) * gl_Position.w; + } + } // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); color_clip_plane_dot = dot(world_pos, color_clip_plane); diff --git a/resources/shaders/140/printbed_shadow.fs b/resources/shaders/140/printbed_shadow.fs new file mode 100644 index 0000000000..650d88950e --- /dev/null +++ b/resources/shaders/140/printbed_shadow.fs @@ -0,0 +1,42 @@ +#version 140 + +// Draws the build-plate as a receiver of the same depth shadow map used for object/self shadows, +// so the plate, objects, and self-shadows all come from one unified technique. +uniform sampler2D shadow_map; +uniform mat4 shadow_light_vp; +uniform float shadow_intensity; +uniform float shadow_map_texel; + +in vec4 world_pos; + +out vec4 out_color; + +// Fraction of the 5x5 PCF kernel occluded from the light. Matches the object shadow shader. +float shadow_occlusion() +{ + vec4 lp = shadow_light_vp * world_pos; + vec3 proj = lp.xyz / lp.w; + proj = proj * 0.5 + 0.5; + if (proj.z > 1.0) + return 0.0; + + // The plate is a pure receiver (never rendered into the shadow map), so a tiny constant + // bias for numerical safety is enough here. + float bias = 0.0004; + float sum = 0.0; + for (int x = -2; x <= 2; ++x) { + for (int y = -2; y <= 2; ++y) { + float closest = texture(shadow_map, proj.xy + vec2(float(x), float(y)) * shadow_map_texel).r; + sum += (proj.z - bias > closest) ? 1.0 : 0.0; + } + } + return sum / 25.0; +} + +void main() +{ + float occ = shadow_occlusion(); + if (occ <= 0.0) + discard; + out_color = vec4(0.0, 0.0, 0.0, shadow_intensity * occ); +} diff --git a/resources/shaders/140/printbed_shadow.vs b/resources/shaders/140/printbed_shadow.vs new file mode 100644 index 0000000000..297e9e9a12 --- /dev/null +++ b/resources/shaders/140/printbed_shadow.vs @@ -0,0 +1,16 @@ +#version 140 + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; + +in vec3 v_position; + +// The plate mask quad is authored directly in world coordinates (z = 0 plane), +// so v_position is already the world position of the fragment. +out vec4 world_pos; + +void main() +{ + world_pos = vec4(v_position, 1.0); + gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); +} diff --git a/resources/shaders/140/ssao.fs b/resources/shaders/140/ssao.fs index 86ea6a54bf..b3b6df6877 100644 --- a/resources/shaders/140/ssao.fs +++ b/resources/shaders/140/ssao.fs @@ -10,6 +10,7 @@ uniform sampler2D depth_texture; uniform sampler2D normal_texture; uniform float z_near; uniform float z_far; +uniform bool is_outline; in vec2 tex_coord; out vec4 frag_color; @@ -22,6 +23,10 @@ float linearize_depth(float depth) void main() { + if (is_outline) { + frag_color = vec4(texture(color_texture, tex_coord).rgb, 1.0); + return; + } ivec2 pixel = ivec2(gl_FragCoord.xy); float center_depth = linearize_depth(texelFetch(depth_texture, pixel, 0).r); diff --git a/resources/web/flush/NozzleListTable.html b/resources/web/flush/NozzleListTable.html new file mode 100644 index 0000000000..51da2cbd52 --- /dev/null +++ b/resources/web/flush/NozzleListTable.html @@ -0,0 +1,287 @@ + + + + + + 喷嘴选择表格 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
选用的喷嘴直径可用喷嘴
左边右边
+ + + 不可用2个
+ + + ✔️3个
+ + + 不可用1个
+ + + + diff --git a/scripts/run_unit_tests.sh b/scripts/run_unit_tests.sh index bd9e969227..f6a01dd3e0 100755 --- a/scripts/run_unit_tests.sh +++ b/scripts/run_unit_tests.sh @@ -4,11 +4,21 @@ # It should only require the directories build/tests, scripts/, and tests/ to function, # and cmake (with ctest) installed. # (otherwise, update the workflow too, but try to avoid to keep things self-contained) +# +# Usage: run_unit_tests.sh [TEST_DIR] [BUILD_CONFIG] +# TEST_DIR directory containing the built tests (default: build/tests) +# BUILD_CONFIG configuration to run; required for multi-config generators +# (Windows/macOS), harmless/omitted for single-config (Linux). ROOT_DIR="$(dirname "$0")/.." cd "${ROOT_DIR}" || exit 1 +TEST_DIR="${1:-build/tests}" +BUILD_CONFIG="${2:-}" + # Run the whole suite, excluding tests tagged [NotWorking]. # --no-tests=error fails the job if the filter matches nothing (instead of passing green). -ctest --test-dir build/tests -LE "NotWorking" --no-tests=error --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j +args=(--test-dir "${TEST_DIR}" -LE "NotWorking" --no-tests=error --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j) +[ -n "${BUILD_CONFIG}" ] && args+=(--build-config "${BUILD_CONFIG}") +ctest "${args[@]}" diff --git a/src/OrcaSlicer.cpp b/src/OrcaSlicer.cpp index 7e1341ac18..211459cec4 100644 --- a/src/OrcaSlicer.cpp +++ b/src/OrcaSlicer.cpp @@ -1326,6 +1326,14 @@ int CLI::run(int argc, char **argv) } set_temporary_dir(temp_path); + // The Filament Track Switch flags are live-device state with no meaning in headless slicing; + // default both off unless explicitly provided on the command line, so an old 3MF that had + // them enabled still slices without the switch behavior. + if (!m_extra_config.has("has_filament_switcher")) + m_extra_config.set_key_value("has_filament_switcher", new ConfigOptionBool(false)); + if (!m_extra_config.has("enable_filament_dynamic_map")) + m_extra_config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(false)); + m_extra_config.apply(m_config, true); m_extra_config.normalize_fdm(); @@ -1703,11 +1711,13 @@ int CLI::run(int argc, char **argv) const Vec3d &instance_offset = model_instance->get_offset(); BOOST_LOG_TRIVIAL(info) << boost::format("instance %1% transform {%2%,%3%,%4%} at %5%:%6%")% model_object->name % instance_offset.x() % instance_offset.y() %instance_offset.z() % __FUNCTION__ % __LINE__<< std::endl; }*/ - current_printer_name = config.option("printer_settings_id")->value; - current_process_name = config.option("print_settings_id")->value; + // Read defensively — a 3mf missing preset ids (e.g. one produced + // by a non-GUI writer) would otherwise crash here on the deref. + if (const auto *o = config.option("printer_settings_id")) current_printer_name = o->value; + if (const auto *o = config.option("print_settings_id")) current_process_name = o->value; current_printer_model = config.option("printer_model", true)->value; - current_filaments_name = config.option("filament_settings_id")->values; - current_extruder_count = config.option("nozzle_diameter")->values.size(); + if (const auto *o = config.option("filament_settings_id")) current_filaments_name = o->values; + if (const auto *o = config.option("nozzle_diameter")) current_extruder_count = o->values.size(); current_printer_variant_count = config.option("printer_extruder_variant", true)->values.size(); current_print_variant_count = config.option("print_extruder_variant", true)->values.size(); current_is_multi_extruder = current_extruder_count > 1; @@ -5937,6 +5947,72 @@ int CLI::run(int argc, char **argv) else filament_maps = part_plate->get_real_filament_maps(m_print_config); + // Multi-nozzle printers need the per-filament volume assignment as a grouping + // input in the manual modes: synthesize it from the per-extruder flow types when + // the caller did not provide one (an extruder whose nozzle stats span several + // volume types keeps the per-filament choice), and require explicit maps in + // nozzle-manual mode. + auto max_nozzle_counts_opt = m_print_config.option("extruder_max_nozzle_count"); + // Skip nil entries: a nullable-int nil is INT_MAX (> 1) and would otherwise falsely pass the gate. + bool support_multi_nozzle = + max_nozzle_counts_opt && + std::any_of(max_nozzle_counts_opt->values.begin(), max_nozzle_counts_opt->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); }); + if (support_multi_nozzle && (mode == fmmManual || mode == fmmNozzleManual) && (plate_to_slice != 0)) { + // Orca: the grouping result is reconstructed purely from the passed maps in + // nozzle-manual mode, so all of them must be present (there are no separate + // per-nozzle CLI parameters to rebuild them from). + if (mode == FilamentMapMode::fmmNozzleManual && + (!m_extra_config.has("filament_volume_map") || !m_extra_config.has("filament_nozzle_map") || + !m_extra_config.has("filament_map"))) { + BOOST_LOG_TRIVIAL(error) + << boost::format("%1%, can not find filament_volume_map/filament_nozzle_map/filament_map under Nozzle Manual mode") % __LINE__; + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, index + 1, cli_errors[CLI_INVALID_PARAMS], sliced_info); + flush_and_exit(CLI_INVALID_PARAMS); + } + + if (mode == fmmManual) { + // Build the volume map when absent: filaments on a single-volume extruder + // print with that extruder's volume; a mixed-volume extruder keeps the + // per-filament choice (default Standard). + std::vector using_nozzle_volume_type = new_nozzle_volume_type; + using_nozzle_volume_type.resize(new_extruder_count, nvtStandard); + if (auto extruder_nozzle_stats_opt = m_print_config.option("extruder_nozzle_stats")) { + auto nozzle_stats = get_extruder_nozzle_stats(extruder_nozzle_stats_opt->values); + for (int e_index = 0; e_index < new_extruder_count && e_index < (int) nozzle_stats.size(); e_index++) { + if (nozzle_stats[e_index].size() > 1) { + using_nozzle_volume_type[e_index] = nvtHybrid; + BOOST_LOG_TRIVIAL(info) << boost::format("%1% : extruder %2%, set nozzle_volume_type to hybrid ") % __LINE__ % (e_index + 1); + } + } + } + std::vector &manual_volume_maps = m_extra_config.option("filament_volume_map", true)->values; + // default to standard flow + manual_volume_maps.resize(filament_count, (int) (nvtStandard)); + for (int f_index = 0; f_index < filament_count && f_index < (int) filament_maps.size(); f_index++) { + int f_extruder_index = filament_maps[f_index] - 1; + if (f_extruder_index >= 0 && f_extruder_index < new_extruder_count && + using_nozzle_volume_type[f_extruder_index] != nvtHybrid) { + manual_volume_maps[f_index] = int(using_nozzle_volume_type[f_extruder_index]); + BOOST_LOG_TRIVIAL(info) << boost::format("%1% : filament %2% extruder %3%, set filament_volume_map to %4% ") % __LINE__ % (f_index + 1) % (f_extruder_index + 1) % manual_volume_maps[f_index]; + } + } + } + + if (m_extra_config.has("filament_volume_map")) { + part_plate->set_filament_volume_maps(m_extra_config.option("filament_volume_map")->values); + } + if (m_extra_config.has("filament_nozzle_map")) { + part_plate->set_filament_nozzle_maps(m_extra_config.option("filament_nozzle_map")->values); + } + } + else if (!support_multi_nozzle && (mode == fmmNozzleManual)) { + BOOST_LOG_TRIVIAL(error) + << boost::format("%1%, Nozzle Manual mode not supported for %2%") % __LINE__ % new_printer_name; + record_exit_reson(outfile_dir, CLI_INVALID_PARAMS, index + 1, cli_errors[CLI_INVALID_PARAMS], sliced_info); + flush_and_exit(CLI_INVALID_PARAMS); + } + for (int index = 0; index < filament_maps.size(); index++) { int filament_extruder = filament_maps[index]; @@ -6175,6 +6251,22 @@ int CLI::run(int argc, char **argv) BOOST_LOG_TRIVIAL(info) << "print::process: first time_using_cache is " << time_using_cache << " secs."; } if (printer_technology == ptFFF) { + // Read the engine's final grouping back onto the plate so an exported + // project (--export-3mf / gcode.3mf) carries the concrete maps in its + // plate settings, matching what a GUI slice persists. + // Orca: deliberately gated to multi-extruder printers so single-extruder + // exports keep their plate settings unchanged. + if (new_extruder_count > 1) { + FilamentMapMode current_map_mode = print_fff->config().filament_map_mode.value; + if (is_auto_filament_map_mode(current_map_mode)) { + part_plate->set_filament_maps(print_fff->get_filament_maps()); + part_plate->set_filament_volume_maps(print_fff->get_filament_volume_maps()); + } + if (current_map_mode != FilamentMapMode::fmmNozzleManual) { + part_plate->set_filament_nozzle_maps(print_fff->get_filament_nozzle_maps()); + } + } + std::string conflict_result = print_fff->get_conflict_string(); if (!conflict_result.empty()) { BOOST_LOG_TRIVIAL(error) << "plate "<< index+1<< ": found slicing result conflict!"<< std::endl; @@ -7359,7 +7451,7 @@ bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partpla bool success = false; StoreParams store_params; - store_params.path = path.c_str(); + store_params.path = path; store_params.model = model; store_params.plate_data_list = partplate_data; store_params.project_presets = project_presets; diff --git a/src/dev-utils/OrcaSlicer_profile_validator.cpp b/src/dev-utils/OrcaSlicer_profile_validator.cpp index 3208f55452..49a38cd1c4 100644 --- a/src/dev-utils/OrcaSlicer_profile_validator.cpp +++ b/src/dev-utils/OrcaSlicer_profile_validator.cpp @@ -1,12 +1,32 @@ +// This single-TU executable links libslic3r, whose SVG/emboss objects (pulled in by the slice mode +// below) reference the header-only nanosvg implementation. Provide it here BEFORE any libslic3r header: +// several of them transitively include nanosvg.h without the implementation macro, and its include +// guard would then suppress the implementation if the macro were defined afterwards. Same pattern as +// the test mains. +#define NANOSVG_IMPLEMENTATION +#include "nanosvg/nanosvg.h" +#define NANOSVGRAST_IMPLEMENTATION +#include "nanosvg/nanosvgrast.h" + #include "libslic3r/GCode.hpp" #include "libslic3r/Preset.hpp" #include "libslic3r/Config.hpp" #include "libslic3r/PresetBundle.hpp" #include "libslic3r/Print.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/TriangleMesh.hpp" #include "libslic3r/Utils.hpp" #include #include +#include +#include +#include +#include +#include +#include #include +#include +#include #include #include @@ -83,6 +103,270 @@ void generate_custom_presets(PresetBundle* preset_bundle, AppConfig& app_config) std::cout << "Custom presets generated successfully" << std::endl; } + +namespace { + +Vec2d printable_area_center(const DynamicPrintConfig &cfg) +{ + const auto *opt = cfg.option("printable_area"); + if (opt == nullptr || opt->values.empty()) + return Vec2d(100., 100.); + Vec2d lo = opt->values.front(), hi = opt->values.front(); + for (const Vec2d &p : opt->values) { lo = lo.cwiseMin(p); hi = hi.cwiseMax(p); } + return 0.5 * (lo + hi); +} + +// Slice one centered cube that switches from filament 1 to filament 2 partway up, so exactly one +// filament change fires, then export. The change drives the printer's own change_filament_gcode: on a +// single-nozzle machine it rides the AMS prime tower (append_tcr), on a multi-nozzle machine it routes +// through the nozzle swap (set_extruder / append_tcr2) - the engine picks the path from the printer's +// topology, so one model covers both. An undefined placeholder in any shipped custom g-code throws +// Slic3r::PlaceholderParserError from export. +std::string slice_two_color_cube_and_export(const DynamicPrintConfig &cfg, bool is_bbl) +{ + const Vec2d center = printable_area_center(cfg); + TriangleMesh m = make_cube(10, 10, 10); + m.translate(float(center.x() - 5.), float(center.y() - 5.), 0.f); + + Model model; + Print print; + ModelObject *obj = model.add_object(); + obj->name = "cube"; // populates [input_filename_base] the way a loaded model does + obj->add_volume(m); + obj->add_instance(); + // Filament 2 is used only above z=4, so the upper layers carry a single filament change. + DynamicPrintConfig range_config; + range_config.set_key_value("extruder", new ConfigOptionInt(2)); + // Every range must carry a layer_height; use the process's own so a fine nozzle (e.g. 0.15 mm + // printing ~0.1 mm layers) isn't forced to a height its extrusion width can't support - that + // trips Flow::with_spacing. + range_config.set_key_value("layer_height", new ConfigOptionFloat(cfg.opt_float("layer_height"))); + obj->layer_config_ranges[{4.0, 10.0}].assign_config(std::move(range_config)); + + print.is_BBL_printer() = is_bbl; + obj->ensure_on_bed(); + print.auto_assign_extruders(obj); + print.apply(model, cfg); + print.validate(); + + // Process + export to a temp file, then read it back (the app's own export path is where the + // custom *_gcode placeholders expand). + print.set_status_silent(); + print.process(); + const fs::path tmp = fs::temp_directory_path() / fs::unique_path("orca-validate-%%%%-%%%%.gcode"); + print.export_gcode(tmp.string(), nullptr, nullptr); + std::ifstream in(tmp.string()); + std::string out((std::istreambuf_iterator(in)), std::istreambuf_iterator()); + in.close(); + boost::system::error_code ec; + fs::remove(tmp, ec); + return out; +} + +// Select the printer's OWN default process + filament (as the app does on a printer change) so we +// slice with settings the printer actually ships, not the generic "Default Setting" that stays +// selected because it is compatible with every printer. +void select_printer_default_presets(PresetBundle &bundle) +{ + const Preset &printer_preset = bundle.printers.get_selected_preset(); + const std::string def_print = printer_preset.config.opt_string("default_print_profile"); + if (!def_print.empty()) + bundle.prints.select_preset_by_name(def_print, /*force=*/true); + if (const auto *def_fil = printer_preset.config.option("default_filament_profile"); + def_fil != nullptr && !def_fil->values.empty()) + bundle.filaments.select_preset_by_name(def_fil->values.front(), /*force=*/true); +} + +// The vendor/printer currently being sliced, stamped onto every engine log record by the sink below so +// the interleaved [error] lines can be attributed to a profile. Updated once per loop iteration; safe as +// a plain global because the sweep is single-threaded and synchronous (see slice_all_printers). +static std::string g_slice_context; + +// Route Boost.Log through a sink that prefixes every record with g_slice_context. Without this the +// engine's [error] lines (emitted deep inside process()/export_gcode()) carry no printer context, so a +// failing profile cannot be told apart from the ~1000 others in the sweep. Drops the default trivial +// sink's timestamp/thread columns - noise here - in favour of the vendor/printer tag. +void install_slice_context_log_sink() +{ + namespace logging = boost::log; + namespace sinks = boost::log::sinks; + namespace expr = boost::log::expressions; + + auto backend = boost::make_shared(); + backend->add_stream(boost::shared_ptr(&std::clog, boost::null_deleter())); + backend->auto_flush(true); + + auto sink = boost::make_shared>(backend); + sink->set_formatter([](const logging::record_view &rec, logging::formatting_ostream &strm) { + strm << "[" << rec[logging::trivial::severity] << "]"; + if (!g_slice_context.empty()) + strm << " [" << g_slice_context << "]"; + strm << " " << rec[expr::smessage]; + }); + + logging::core::get()->remove_all_sinks(); // drop the default trivial sink so lines are not doubled + logging::core::get()->add_sink(sink); +} + +// Slice-and-export a two-colour cube through every shipped printer (optionally scoped to one vendor via +// -v). Unlike the static reference/placeholder checks, this expands every custom *_gcode - including +// change_filament_gcode at the one filament change - against the printer's fully-resolved config, so +// undefined-placeholder / invalid-flow bugs surface here. Reports every offending printer and returns 1 +// if any failed, 0 otherwise. When outdir is non-empty, each printer's g-code is also written there as +// "__.gcode" for manual inspection. The sweep is SEQUENTIAL by necessity: +// Print::process() keeps process-global state, so slicing printers concurrently in one process races +// even with per-slice Model+Print. Load in validation mode so the vendors are read straight from the -p +// profiles dir (no data_dir/system tree) and -v scoping is honoured for free. +int slice_all_printers(const std::string &vendor, const std::string &outdir) +{ + install_slice_context_log_sink(); + + if (!outdir.empty()) { + boost::system::error_code ec; + fs::create_directories(outdir, ec); + if (ec) { + BOOST_LOG_TRIVIAL(error) << "Could not create output directory \"" << outdir << "\": " << ec.message(); + std::cout << "Validation failed" << std::endl; + return 1; + } + std::cout << "Saving sliced g-code to " << outdir << std::endl; + } + + PresetBundle bundle; + bundle.set_is_validation_mode(true); + bundle.set_vendor_to_validate(vendor); // empty == all vendors + AppConfig app_config; + app_config.set("preset_folder", "default"); + try { + bundle.load_presets(app_config, ForwardCompatibilitySubstitutionRule::Disable); + } catch (const std::exception &ex) { + BOOST_LOG_TRIVIAL(error) << ex.what(); + std::cout << "Validation failed" << std::endl; + return 1; + } + + // Enable every instantiable model/variant in AppConfig - system printers are hidden until enabled; + // without this select_preset_by_name silently falls back to the "Default Printer". + std::vector> printers; // (vendor name, preset name) + for (const Preset &p : bundle.printers.get_presets()) { + if (p.vendor == nullptr) continue; // skips the Default Printer + const std::string model = p.config.opt_string("printer_model"); + const std::string variant = p.config.opt_string("printer_variant"); + if (model.empty() || variant.empty()) continue; // skip non-instantiable base/common configs + app_config.set_variant(p.vendor->id, model, variant, true); + printers.push_back({p.vendor->name, p.name}); + } + bundle.load_installed_printers(app_config); + + if (printers.empty()) { + BOOST_LOG_TRIVIAL(error) << "No instantiable printer presets found" + << (vendor.empty() ? "" : " for vendor " + vendor); + std::cout << "Validation failed" << std::endl; + return 1; + } + std::cout << "Slicing " << printers.size() << " printer preset(s)" + << (vendor.empty() ? "" : " for vendor " + vendor) << "..." << std::endl; + + int failures = 0; + for (const auto &[vendor_name, printer] : printers) { + g_slice_context = vendor_name + " / " + printer; // tag every engine log line from this slice + const bool selected = bundle.printers.select_preset_by_name(printer, /*force=*/true); + if (!selected || bundle.printers.get_selected_preset_name() != printer) { + BOOST_LOG_TRIVIAL(error) << "Printer preset \"" << printer << "\" could not be selected"; + ++failures; + continue; + } + + select_printer_default_presets(bundle); // slice with the printer's shipped process/filament + bundle.update_multi_material_filament_presets(); // size filament_presets to nozzle count + bundle.update_compatible(PresetSelectCompatibleType::Always); + + // Never slice with a generic default preset - that would validate stand-in settings, not the + // real profile (a legit per-profile error). + if (bundle.prints.get_selected_preset().is_default || bundle.filaments.get_selected_preset().is_default) { + BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer << "\" fell back to a default preset (process=\"" + << bundle.prints.get_selected_preset_name() << "\", filament=\"" + << bundle.filaments.get_selected_preset_name() << "\")"; + ++failures; + continue; + } + + // Grow to a 2nd filament so the cube can change colour; never shrink a multi-nozzle printer + // below its nozzle count, or full_config()'s flush-volume matrix no longer matches validate(). + const size_t nozzles = bundle.printers.get_selected_preset().config.option("nozzle_diameter")->size(); + bundle.set_num_filaments((unsigned int) std::max(2, nozzles)); + + // Mirror the app's manual filament->nozzle assignment for a multi-nozzle BBL printer: put each + // filament on its own nozzle and pin the map (fmmManual) so full_config() collapses every filament to + // the variant of the nozzle it actually prints from, and the engine keeps that assignment instead of + // auto-remapping it during process(). Without this the synthetic 2nd filament keeps nozzle 1's variant + // while the auto map moves it to nozzle 2 - harmless, but on the one printer whose nozzles differ in + // type (Direct Drive + Bowden) the mismatched lookup spams [error] lines. Single-nozzle and non-BBL + // printers keep the default map (their toolchange rides the AMS/tool-changer path unchanged). + const bool pin_filament_map = bundle.is_bbl_vendor() && nozzles > 1; + if (pin_filament_map) { + auto &fmap = bundle.project_config.option("filament_map", true)->values; + for (size_t i = 0; i < fmap.size(); ++i) + fmap[i] = int(i % nozzles) + 1; + } + + DynamicPrintConfig cfg = bundle.full_config(); + cfg.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); // force a purge tower so the change is detectable + // The map above drives full_config()'s per-filament variant collapse; fmmManual on the sliced config + // stops process() from auto-remapping filaments back onto a different nozzle (which would re-introduce + // the variant mismatch this pinning avoids). + if (pin_filament_map) + cfg.set_key_value("filament_map_mode", new ConfigOptionEnum(fmmManual)); + + // full_config() grows filament_extruder_variant to one entry per filament, but because the synthetic + // 2nd filament is a duplicate of the first (set_num_filaments copies the same preset), it leaves + // filament_self_index at size 1. That makes update_values_to_printer_extruders_for_multiple_filaments + // fail to resolve the 2nd filament's variant - a benign fallback that spams [error] lines. A real + // 2-colour project ships filament_self_index = 1,2,...; mirror that so the sweep log stays clean. The + // slice output is unaffected: the duplicated filament's per-variant values are identical to the first. + if (auto *variants = cfg.option("filament_extruder_variant")) { + auto &self_index = cfg.option("filament_self_index", true)->values; + if (self_index.size() != variants->size()) { + self_index.resize(variants->size()); + for (size_t i = 0; i < self_index.size(); ++i) + self_index[i] = int(i) + 1; + } + } + + try { + const std::string out = slice_two_color_cube_and_export(cfg, bundle.is_bbl_vendor()); + if (!outdir.empty() && !out.empty()) { + const fs::path f = fs::path(outdir) / (sanitize_filename(vendor_name) + "__" + sanitize_filename(printer) + ".gcode"); + save_string_file(f, out); + } + if (out.empty() || out.find("G1") == std::string::npos) { + BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer << "\" produced no g-code"; + ++failures; + } else if (out.find("CP TOOLCHANGE START") == std::string::npos) { + // The filament change never rode the tower, so change_filament_gcode was not exercised. + BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer + << "\" sliced but the filament change never fired (no CP TOOLCHANGE START)"; + ++failures; + } + } catch (const std::exception &ex) { + BOOST_LOG_TRIVIAL(error) << "Printer \"" << printer << "\" failed to slice: " << ex.what(); + ++failures; + } + } + g_slice_context.clear(); + + if (failures > 0) { + std::cout << failures << " of " << printers.size() << " printer preset(s) failed to slice" << std::endl; + std::cout << "Validation failed" << std::endl; + return 1; + } + std::cout << "All " << printers.size() << " printer preset(s) sliced successfully" << std::endl; + std::cout << "Validation completed successfully" << std::endl; + return 0; +} + +} // namespace + int main(int argc, char* argv[]) { po::options_description desc("Orca Profile Validator\nUsage"); @@ -95,6 +379,8 @@ int main(int argc, char* argv[]) #endif ("vendor,v", po::value()->default_value(""), "Vendor name. Optional, all profiles present in the folder will be validated if not specified") ("generate_presets,g", po::value()->default_value(false), "Generate user presets for mock test") + ("slice,s", po::bool_switch()->default_value(false), "Slice a two-colour cube through every printer to expand all custom g-code (catches placeholder/flow errors that static checks miss). Off unless this flag is present.") + ("outdir,o", po::value()->default_value(""), "With -s, also save each printer's g-code to this folder (as __.gcode) for manual inspection. Optional.") ("check_filament_subtypes,f", po::bool_switch()->default_value(false), "Also flag printers with duplicate (ambiguous) filament subtypes. Off unless this flag is present.") ("log_level,l", po::value()->default_value(2), "Log level. Optional, default is 2 (warning). Higher values produce more detailed logs."); // clang-format on @@ -119,6 +405,8 @@ int main(int argc, char* argv[]) std::string vendor = vm["vendor"].as(); int log_level = vm["log_level"].as(); bool generate_user_preset = vm["generate_presets"].as(); + bool slice_mode = vm["slice"].as(); + std::string slice_outdir = vm["outdir"].as(); bool check_filament_subtypes = vm["check_filament_subtypes"].as(); // check if path is valid, and return error if not @@ -132,6 +420,12 @@ int main(int argc, char* argv[]) // std::cout<<"log_level: "</profiles, so point resources_dir() at that + // parent. Without this, resources_dir() is empty and slice mode's HRC lookup + // (info/nozzle_info.json) resolves to a non-existent relative path and falls back to a + // built-in table (logging a spurious parse error and dropping the E3D entry). + if (fs::exists(fs::path(path).parent_path() / "info")) + set_resources_dir(fs::path(path).parent_path().string()); auto user_dir = fs::path(Slic3r::data_dir()) / PRESET_USER_DIR; user_dir.make_preferred(); @@ -139,6 +433,12 @@ int main(int argc, char* argv[]) fs::create_directory(user_dir); set_logging_level(log_level); + + // Slice mode expands every printer's custom g-code by actually slicing (see slice_all_printers). + // A distinct opt-in mode so the default static checks stay fast for every profile PR. + if (slice_mode) + return slice_all_printers(vendor, slice_outdir); + auto preset_bundle = new PresetBundle(); // preset_bundle->setup_directories(); preset_bundle->set_is_validation_mode(true); diff --git a/src/libslic3r/AppConfig.cpp b/src/libslic3r/AppConfig.cpp index c81e6c391c..df5b3f5380 100644 --- a/src/libslic3r/AppConfig.cpp +++ b/src/libslic3r/AppConfig.cpp @@ -304,6 +304,10 @@ void AppConfig::set_defaults() if (get("show_3d_navigator").empty()) set_bool("show_3d_navigator", true); + // Show the one-time "Filament Track Switch is ready" tip until it has been seen once. + if (get("show_fila_switch_tips").empty()) + set_bool("show_fila_switch_tips", true); + if (get("show_plate_gridlines").empty()) set_bool("show_plate_gridlines", true); @@ -800,6 +804,10 @@ std::string AppConfig::load() preset_info.nozzle_volume_type = NozzleVolumeType(cali_it.value()["nozzle_volume_type"].get()); if (cali_it.value().contains("bed_type")) preset_info.bed_type = BedType(cali_it.value()["bed_type"].get()); + if (cali_it.value().contains("nozzle_pos_id")) + preset_info.nozzle_pos_id = cali_it.value()["nozzle_pos_id"].get(); + if (cali_it.value().contains("nozzle_sn")) + preset_info.nozzle_sn = cali_it.value()["nozzle_sn"].get(); cali_info.selected_presets.push_back(preset_info); } } @@ -957,6 +965,8 @@ void AppConfig::save() preset_json["extruder_id"] = filament_preset.extruder_id; preset_json["nozzle_volume_type"] = int(filament_preset.nozzle_volume_type); preset_json["bed_type"] = int(filament_preset.bed_type); + preset_json["nozzle_pos_id"] = filament_preset.nozzle_pos_id; + preset_json["nozzle_sn"] = filament_preset.nozzle_sn; preset_json["nozzle_diameter"] = filament_preset.nozzle_diameter; preset_json["filament_id"] = filament_preset.filament_id; preset_json["setting_id"] = filament_preset.setting_id; diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp index 2d2cf9896d..da5c7357c1 100644 --- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp +++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp @@ -1660,7 +1660,7 @@ void SkeletalTrapezoidation::propagateBeadingsDownward(edge_t* edge_to_peak, ptr } -SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius) const +SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius) { assert(ratio_left_to_whole >= 0.0 && ratio_left_to_whole <= 1.0); Beading ret = interpolate(left, ratio_left_to_whole, right); @@ -1684,6 +1684,12 @@ SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beadin { // We cant adjust to fit the next edge because there is no previous one?! return ret; } + // ret follows the thicker of left/right, which can hold fewer insets than left when bead + // count and thickness disagree; skip the adjustment rather than index ret past its end. + if (next_inset_idx >= coord_t(ret.toolpath_locations.size())) + { + return ret; + } assert(next_inset_idx < coord_t(left.toolpath_locations.size())); assert(left.toolpath_locations[next_inset_idx] <= switching_radius); assert(left.toolpath_locations[next_inset_idx + 1] >= switching_radius); @@ -1703,7 +1709,7 @@ SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beadin } -SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right) const +SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right) { assert(ratio_left_to_whole >= 0.0 && ratio_left_to_whole <= 1.0); float ratio_right_to_whole = 1.0 - ratio_left_to_whole; diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp index 70c2a7d9a3..d87cd74728 100644 --- a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp +++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp @@ -488,7 +488,7 @@ protected: * beads. * \return The beading at the interpolated location. */ - Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius) const; + static Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius); /*! * Subroutine of \ref interpolate(const Beading&, Ratio, const Beading&, coord_t) @@ -501,7 +501,7 @@ protected: * \param right One of the beadings to interpolate between. * \return The beading at the interpolated location. */ - Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right) const; + static Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right); /*! * Get the beading at a certain node of the skeletal graph, or create one if diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index fb4b251c99..c38685ae06 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -221,6 +221,7 @@ set(lisbslic3r_sources GCode/FanMover.hpp GCode/GCodeProcessor.cpp GCode/GCodeProcessor.hpp + GCode/ElegooGCodeProcessorHelper.cpp GCode.hpp GCode/PchipInterpolatorHelper.cpp GCode/PchipInterpolatorHelper.hpp @@ -472,6 +473,8 @@ set(lisbslic3r_sources FilamentGroup.cpp FilamentGroupUtils.hpp FilamentGroupUtils.cpp + MultiNozzleUtils.hpp + MultiNozzleUtils.cpp GCode/ToolOrderUtils.hpp GCode/ToolOrderUtils.cpp FlushVolPredictor.hpp diff --git a/src/libslic3r/Clipper2Utils.cpp b/src/libslic3r/Clipper2Utils.cpp index 12fd867500..d389d25209 100644 --- a/src/libslic3r/Clipper2Utils.cpp +++ b/src/libslic3r/Clipper2Utils.cpp @@ -188,6 +188,18 @@ ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta) return results; } +ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta, Clipper2Lib::JoinType joinType) +{ + Clipper2Lib::Paths64 subject = Slic3rExPolygons_to_Paths64(expolygons); + Clipper2Lib::ClipperOffset offsetter; + offsetter.AddPaths(subject, joinType, Clipper2Lib::EndType::Polygon); + Clipper2Lib::PolyPath64 polytree; + offsetter.Execute(delta, polytree); + ExPolygons results = PolyTreeToExPolygons(std::move(polytree)); + + return results; +} + ExPolygons offset2_ex_2(const ExPolygons& expolygons, double delta1, double delta2) { // 1st offset diff --git a/src/libslic3r/Clipper2Utils.hpp b/src/libslic3r/Clipper2Utils.hpp index 54b48d6bd7..2b4b0fb2ef 100644 --- a/src/libslic3r/Clipper2Utils.hpp +++ b/src/libslic3r/Clipper2Utils.hpp @@ -15,6 +15,7 @@ Slic3r::Polylines diff_pl_2(const Slic3r::Polylines& subject, const Slic3r::Pol ExPolygons union_ex_2(const Polygons &expolygons); ExPolygons union_ex_2(const ExPolygons &expolygons); ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta); +ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta, Clipper2Lib::JoinType joinType); ExPolygons offset2_ex_2(const ExPolygons &expolygons, double delta1, double delta2); } diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 31c73c4aa1..ea19eeb559 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -1,3 +1,7 @@ +#include +#include +#include + #include "ClipperUtils.hpp" #include "Geometry.hpp" #include "ShortestPath.hpp" @@ -930,6 +934,77 @@ Slic3r::Polylines intersection_pl(const Slic3r::Polylines &subject, const Slic3r Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip) { return _clipper_pl_closed(ClipperLib::ctIntersection, ClipperUtils::PolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip)); } +// Orca: Sort and orient open polyline fragments produced by clipping `source` with +// intersection_pl(), so that they run in the same order and direction as the source +// polyline. Clipping creates new endpoints at the clip boundary, but it keeps the +// interior source vertices intact, so a fragment's position on the source path is +// recovered exactly by looking its vertices up in the source. Fragments without any +// surviving source vertex lie on a single source segment, found by a nearest-segment +// search. +void restore_source_path_order(const Slic3r::Polyline &source, Slic3r::Polylines &fragments) +{ + const Points &src = source.points; + if (src.size() < 2 || fragments.empty()) + return; + + std::unordered_map source_index; + source_index.reserve(src.size()); + for (size_t i = 0; i < src.size(); ++ i) + source_index.emplace(src[i], i); + + // Sort key: index of the source vertex where the fragment starts, then the signed + // offset of the fragment's start from that vertex, to order multiple fragments cut + // from one long source segment. + std::vector> keys(fragments.size()); + for (size_t n = 0; n < fragments.size(); ++ n) { + Polyline &pl = fragments[n]; + const size_t npos = size_t(-1); + size_t front = npos; + size_t back = npos; + for (const Point &pt : pl.points) + if (auto it = source_index.find(pt); it != source_index.end()) { + front = it->second; + break; + } + for (auto i = pl.points.rbegin(); i != pl.points.rend(); ++ i) + if (auto it = source_index.find(*i); it != source_index.end()) { + back = it->second; + break; + } + Vec2crd source_dir; + if (front == npos) { + // All vertices were created by clipping, thus the whole fragment lies on a + // single source segment. Find that segment. + double best = std::numeric_limits::max(); + for (size_t i = 0; i + 1 < src.size(); ++ i) + if (double d = Line::distance_to_squared(pl.first_point(), src[i], src[i + 1]); d < best) { + best = d; + front = i; + } + back = front; + source_dir = src[front + 1] - src[front]; + } else + source_dir = src[std::min(back + 1, src.size() - 1)] - src[front > 0 ? front - 1 : 0]; + if (front > back) { + pl.reverse(); + std::swap(front, back); + } else if (front == back && + (pl.last_point() - pl.first_point()).cast().dot(source_dir.cast()) < 0.) + pl.reverse(); + const Vec2crd seg = src[std::min(front + 1, src.size() - 1)] - src[front]; + keys[n] = { front, (pl.first_point() - src[front]).cast().dot(seg.cast()) }; + } + + std::vector order(fragments.size()); + std::iota(order.begin(), order.end(), size_t(0)); + std::sort(order.begin(), order.end(), [&keys](size_t a, size_t b) { return keys[a] < keys[b]; }); + Polylines sorted; + sorted.reserve(fragments.size()); + for (size_t n : order) + sorted.emplace_back(std::move(fragments[n])); + fragments = std::move(sorted); +} + Lines _clipper_ln(ClipperLib::ClipType clipType, const Lines &subject, const Polygons &clip) { // convert Lines to Polylines diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index 9c2fa23926..5ed161c27a 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -528,6 +528,10 @@ Slic3r::Polylines intersection_pl(const Slic3r::Polygons &subject, const Slic3r Slic3r::Polylines3 intersection_pl(const Slic3r::Polylines3 &subject, const Slic3r::Polygon &clip); Slic3r::Polylines3 intersection_pl(const Slic3r::Polylines3 &subject, const Slic3r::ExPolygon &clip); +// Orca: Sort and orient open polyline fragments produced by clipping `source` with +// intersection_pl(), so that they run in the same order and direction as the source polyline. +void restore_source_path_order(const Slic3r::Polyline &source, Slic3r::Polylines &fragments); + inline Slic3r::Lines intersection_ln(const Slic3r::Lines &subject, const Slic3r::Polygons &clip) { return _clipper_ln(ClipperLib::ctIntersection, subject, clip); diff --git a/src/libslic3r/Config.hpp b/src/libslic3r/Config.hpp index 54a09ec96a..82f7dc4f69 100644 --- a/src/libslic3r/Config.hpp +++ b/src/libslic3r/Config.hpp @@ -363,6 +363,7 @@ public: virtual void set_with_restore(const ConfigOptionVectorBase* rhs, std::vector& restore_index, int stride) = 0; virtual void set_with_restore_2(const ConfigOptionVectorBase* rhs, std::vector& restore_index, int start, int len, bool skip_error = false) = 0; virtual void set_only_diff(const ConfigOptionVectorBase* rhs, std::vector& diff_index, int stride) = 0; + virtual void set_to_index(const ConfigOptionVectorBase* rhs, std::vector& dest_index, int stride) = 0; virtual void set_with_nil(const ConfigOptionVectorBase* rhs, const ConfigOptionVectorBase* inherits, int stride) = 0; // Resize the vector of values, copy the newly added values from opt_default if provided. virtual void resize(size_t n, const ConfigOption *opt_default = nullptr) = 0; @@ -586,6 +587,32 @@ public: throw ConfigurationError("ConfigOptionVector::set_only_diff(): Assigning an incompatible type"); } + //set a item related with extruder variants when apply static config with dynamic config + //rhs: item from dynamic config + //dest_index: which index in this vector need to be used + virtual void set_to_index(const ConfigOptionVectorBase* rhs, std::vector& dest_index, int stride) override + { + if (rhs->type() == this->type()) { + // Assign the first value of the rhs vector. + auto other = static_cast*>(rhs); + T v = other->values.front(); + this->values.resize(dest_index.size() * stride, v); + + for (size_t i = 0; i < dest_index.size(); i++) { + if (dest_index[i] < 0) + continue; + for (size_t j = 0; j < size_t(stride); j++) + { + const size_t src_idx = size_t(dest_index[i]) * size_t(stride) + j; + if (src_idx < other->values.size() && !other->is_nil(size_t(dest_index[i]) * size_t(stride))) + this->values[i * size_t(stride) + j] = other->values[src_idx]; + } + } + } + else + throw ConfigurationError("ConfigOptionVector::set_to_index(): Assigning an incompatible type"); + } + //set a item related with extruder variants when saving user config, set the non-diff value of some extruder to nill //this item has different value with inherit config //rhs: item from userconfig @@ -716,6 +743,7 @@ public: return false; } // Apply an override option, possibly a nullable one. + //default_index are 0 based bool apply_override(const ConfigOption *rhs, std::vector& default_index) override { if (this->nullable()) throw ConfigurationError("Cannot override a nullable ConfigOption."); @@ -751,8 +779,8 @@ public: this->values[i] = rhs_vec->values[i]; modified = true; } else { - if ((i < default_index.size()) && (default_index[i] - 1 < default_value.size())) - this->values[i] = default_value[default_index[i] - 1]; + if ((i < default_index.size()) && (default_index[i] < default_value.size())) + this->values[i] = default_value[default_index[i]]; else this->values[i] = default_value[0]; } diff --git a/src/libslic3r/Extruder.cpp b/src/libslic3r/Extruder.cpp index f6632c57ef..1e250b707e 100644 --- a/src/libslic3r/Extruder.cpp +++ b/src/libslic3r/Extruder.cpp @@ -13,11 +13,20 @@ Extruder::Extruder(unsigned int id, GCodeConfig *config, bool share_extruder) : { reset(); + m_config_index = int(m_id); // cache values that are going to be called often m_e_per_mm3 = this->filament_flow_ratio(); m_e_per_mm3 /= this->filament_crossection(); } +void Extruder::set_config_index(int idx) +{ + m_config_index = idx < 0 ? int(m_id) : idx; + // keep the cached flow term reading the same column as the getters + m_e_per_mm3 = this->filament_flow_ratio(); + m_e_per_mm3 /= this->filament_crossection(); +} + unsigned int Extruder::extruder_id() const { assert(m_config); @@ -162,28 +171,35 @@ double Extruder::filament_cost() const double Extruder::filament_flow_ratio() const { - return m_config->filament_flow_ratio.get_at(m_id); + return m_config->filament_flow_ratio.get_at(m_config_index); } // Return a "retract_before_wipe" percentage as a factor clamped to <0, 1> double Extruder::retract_before_wipe() const { - return std::min(1., std::max(0., m_config->retract_before_wipe.get_at(m_id) * 0.01)); + return std::clamp(m_config->retract_before_wipe.get_at(m_config_index) * 0.01, 0., 1.); +} + +// Orca: +// Return a "retract_after_wipe" percentage as a factor clamped to <0, 1> +double Extruder::retract_after_wipe() const +{ + return std::min(std::clamp(m_config->retract_after_wipe.get_at(m_config_index) * 0.01, 0., 1.), 1. - retract_before_wipe()); } double Extruder::retraction_length() const { - return m_config->retraction_length.get_at(m_id); + return m_config->retraction_length.get_at(m_config_index); } double Extruder::retract_lift() const { - return m_config->z_hop.get_at(m_id); + return m_config->z_hop.get_at(m_config_index); } int Extruder::retract_speed() const { - return int(floor(m_config->retraction_speed.get_at(m_id)+0.5)); + return int(floor(m_config->retraction_speed.get_at(m_config_index)+0.5)); } bool Extruder::use_firmware_retraction() const @@ -193,13 +209,13 @@ bool Extruder::use_firmware_retraction() const int Extruder::deretract_speed() const { - int speed = int(floor(m_config->deretraction_speed.get_at(m_id)+0.5)); + int speed = int(floor(m_config->deretraction_speed.get_at(m_config_index)+0.5)); return (speed > 0) ? speed : this->retract_speed(); } double Extruder::retract_restart_extra() const { - return m_config->retract_restart_extra.get_at(m_id); + return m_config->retract_restart_extra.get_at(m_config_index); } double Extruder::retract_length_toolchange() const @@ -214,6 +230,8 @@ double Extruder::retract_restart_extra_toolchange() const double Extruder::travel_slope() const { + // Orca: deliberately keyed by the physical extruder, not the filament column — this read + // predates the per-variant merge and switching it would change existing multi-extruder output. return m_config->travel_slope.get_at(extruder_id()) * PI / 180; } diff --git a/src/libslic3r/Extruder.hpp b/src/libslic3r/Extruder.hpp index 0d76ede8c9..aa023ea040 100644 --- a/src/libslic3r/Extruder.hpp +++ b/src/libslic3r/Extruder.hpp @@ -29,6 +29,13 @@ public: unsigned int id() const { return m_id; } + // Column of the per-variant filament/override arrays the getters read. Defaults to the + // filament id (one column per filament); the g-code generator refreshes it on layer changes + // and toolchanges when a per-layer nozzle grouping gives a filament several variant columns. + int config_index() const { return m_config_index; } + // idx < 0 resets to the filament id. Re-syncs the cached e_per_mm3 flow term. + void set_config_index(int idx); + unsigned int extruder_id() const; double extrude(double dE); double retract(double length, double restart_extra); @@ -51,6 +58,10 @@ public: double retracted() const { return m_retracted; } // Get extra retraction planned after double restart_extra() const { return m_restart_extra; } + // Share-aware retracted-length readers (for extruders shared between filaments), consumed by GCodeWriter::get_extruder_retracted_length. + bool is_share_extruder() const { return m_share_extruder; } + double get_single_retracted_length() const { return m_retracted; } + double get_share_retracted_length() const { return m_share_retracted[extruder_id()]; } // Setters for the PlaceholderParser. // Set current extruder position. Only applicable with absolute extruder addressing. void set_position(double e) { m_E = e; } @@ -63,6 +74,8 @@ public: double filament_cost() const; double filament_flow_ratio() const; double retract_before_wipe() const; + // Orca: + double retract_after_wipe() const; double retraction_length() const; double retract_lift() const; int retract_speed() const; @@ -82,6 +95,8 @@ private: GCodeConfig *m_config; // Print-wide global ID of this extruder. unsigned int m_id; + // Column into the per-variant filament/override arrays; equals m_id unless refreshed. + int m_config_index{0}; // Current state of the extruder axis, may be resetted if use_relative_e_distances. double m_E; // Current state of the extruder tachometer, used to output the extruded_volume() and used_filament() statistics. diff --git a/src/libslic3r/FilamentGroup.cpp b/src/libslic3r/FilamentGroup.cpp index 2a9b5b6037..97da94652c 100644 --- a/src/libslic3r/FilamentGroup.cpp +++ b/src/libslic3r/FilamentGroup.cpp @@ -5,10 +5,15 @@ #include #include #include +#include namespace Slic3r { using namespace FilamentGroupUtils; + static constexpr long long ENUM_THRESHOLD = 10000; + static constexpr long long ENUM_EARLY_EXIT = 10000000; + constexpr uint32_t GOLDEN_RATIO_32 = 0x9e3779b9; + // clear the array and heap,save the groups in heap to the array static void change_memoryed_heaps_to_arrays(MemoryedGroupHeap& heap,const int total_filament_num,const std::vector& used_filaments, std::vector>& arrs) { @@ -36,88 +41,349 @@ namespace Slic3r return filament_merge_map; } - - std::vector calc_filament_group_for_tpu(const std::set& tpu_filaments, const int filament_nums, const int master_extruder_id) + static uint64_t fnv_hash_nozzle(int volume_type, int is_right_extruder, int loaded_filament = -1) { - std::vector ret(filament_nums); - for (size_t fidx = 0; fidx < filament_nums; ++fidx) { - if (tpu_filaments.count(fidx)) - ret[fidx] = master_extruder_id; - else - ret[fidx] = 1 - master_extruder_id; + constexpr uint64_t FNV_OFFSET_BASIS = 14695981039346656037ULL; + constexpr uint64_t FNV_PRIME = 1099511628211ULL; + constexpr uint64_t SALT_A = 0xA5A5A5A5A5A5A5A5ULL; + constexpr uint64_t SALT_B = 0x5A5A5A5A5A5A5A5AULL; + constexpr uint64_t SALT_C = 0x3C3C3C3C3C3C3C3CULL; + + uint64_t h = FNV_OFFSET_BASIS; + h ^= static_cast(volume_type) + SALT_A; + h *= FNV_PRIME; + h ^= static_cast(is_right_extruder) + SALT_B; + h *= FNV_PRIME; + if (loaded_filament >= 0) { + h ^= static_cast(loaded_filament) + SALT_C; + h *= FNV_PRIME; } - return ret; + + return h; } - bool can_swap_groups(const int extruder_id_0, const std::set& group_0, const int extruder_id_1, const std::set& group_1, const FilamentGroupContext& ctx) + static double evaluate_score(const double flush, const double time, const bool with_time = false) { + if (!with_time) return flush; + + double approx_density = 1.26; // g/cm^3 + double approx_flush_speed = 180; // s/g + double correction_factor = 2; + double flush_score = flush * approx_density * approx_flush_speed * correction_factor / 1000; + return flush_score + time; + } + + static double calc_change_time_for_group( + const std::vector& filament_change_seq, + const std::vector& nozzle_change_seq, + const std::vector& logical_filaments, + const std::vector& nozzle_list, + const MultiNozzleUtils::FilamentChangeTimeParams& time_params, + const std::vector& ams_preload_enabled, + const std::vector& group_of_filament) { - std::vector>extruder_unprintables(2); - { - std::vector> unprintable_filaments = ctx.model_info.unprintable_filaments; - if (unprintable_filaments.size() > 1) - remove_intersection(unprintable_filaments[0], unprintable_filaments[1]); + auto r = MultiNozzleUtils::simulate_filament_change_time( + logical_filaments, nozzle_list, filament_change_seq, + nozzle_change_seq, group_of_filament, time_params, + ams_preload_enabled); + return r.actual_time; + } - std::map>unplaceable_limts; - for (auto& group_id : { extruder_id_0,extruder_id_1 }) - for (auto f : unprintable_filaments[group_id]) - unplaceable_limts[f].emplace_back(group_id); + static double full_evaluate( + const std::vector& used_filaments, + const std::vector& filament_nozzle_map, + const FilamentGroupContext& ctx, + std::optional&)>> get_custom_seq = std::nullopt, + int* out_flush = nullptr) + { + auto group_res = MultiNozzleUtils::LayeredNozzleGroupResult::create(filament_nozzle_map, ctx.nozzle_info.nozzle_list, used_filaments); + if (!group_res) { + if (out_flush) *out_flush = 0; + return 0.0; + } - for (auto& elem : unplaceable_limts) - sort_remove_duplicates(elem.second); - - for (auto& elem : unplaceable_limts) { - for (auto& eid : elem.second) { - if (eid == extruder_id_0) { - extruder_unprintables[0].insert(elem.first); - } - if (eid == extruder_id_1) { - extruder_unprintables[1].insert(elem.first); + MultiNozzleUtils::NozzleStatusRecorder initial_status; + for (auto& [nozzle_id, filament_id] : ctx.nozzle_info.nozzle_status) { + if (filament_id >= 0) { + int extruder_id = 0; + for (const auto& nozzle : ctx.nozzle_info.nozzle_list) { + if (nozzle.group_id == nozzle_id) { + extruder_id = nozzle.extruder_id; + break; } } + initial_status.set_nozzle_status(nozzle_id, filament_id, extruder_id); } } - // check printable limits - for (auto fid : group_0) { - if (extruder_unprintables[1].count(fid) > 0) - return false; + std::vector> filament_sequences; + int flush = reorder_filaments_for_multi_nozzle_extruder( + used_filaments, + *group_res, + ctx.model_info.layer_filaments, + ctx.model_info.flush_matrix, + get_custom_seq ? *get_custom_seq : std::function&)>{}, + &filament_sequences, + initial_status + ); + + if (out_flush) *out_flush = flush; + + double change_time = 0.0; + if (!filament_sequences.empty()) { + std::vector filament_change_seq; + std::vector nozzle_change_seq; + int prev_fil = -1, prev_nozzle = -1; + for (const auto& layer_seq : filament_sequences) { + for (unsigned int fil : layer_seq) { + auto nozzle_info = group_res->get_first_nozzle_for_filament(fil); + if (!nozzle_info) continue; + int nid = nozzle_info->group_id; + if ((int)fil == prev_fil && nid == prev_nozzle) continue; + filament_change_seq.push_back(static_cast(fil)); + nozzle_change_seq.push_back(nid); + prev_fil = (int)fil; + prev_nozzle = nid; + } + } + + std::vector logical_filaments(used_filaments.begin(), used_filaments.end()); + std::vector group_of_filament(used_filaments.size(), 0); + for (size_t fi = 0; fi < used_filaments.size(); ++fi) { + int nozzle_id = filament_nozzle_map[used_filaments[fi]]; + if (nozzle_id >= 0 && nozzle_id < (int)ctx.nozzle_info.nozzle_list.size()) + group_of_filament[fi] = ctx.nozzle_info.nozzle_list[nozzle_id].extruder_id; + } + change_time = calc_change_time_for_group( + filament_change_seq, + nozzle_change_seq, + logical_filaments, + ctx.nozzle_info.nozzle_list, + ctx.speed_info.change_time_params, + ctx.speed_info.ams_preload_enabled, + group_of_filament + ); } - for (auto fid : group_1) { - if (extruder_unprintables[0].count(fid) > 0) - return false; + double print_time = 0.0; + if (ctx.speed_info.group_with_time) { + TimeEvaluator time_evaluator(ctx.speed_info); + print_time = time_evaluator.get_estimated_time(filament_nozzle_map); } - // check extruder capacity ,if result before exchange meets the constraints and the result after exchange does not meet the constraints, return false - if (ctx.machine_info.max_group_size[extruder_id_0] >= group_0.size() && ctx.machine_info.max_group_size[extruder_id_1] >= group_1.size() && (ctx.machine_info.max_group_size[extruder_id_0] < group_1.size() || ctx.machine_info.max_group_size[extruder_id_1] < group_0.size())) - return false; - - return true; + return evaluate_score(flush, change_time + print_time, true); } - - // only support extruder nums with 2, try to swap the master extruder id with the other extruder id - std::vector optimize_group_for_master_extruder(const std::vector& used_filaments,const FilamentGroupContext& ctx, std::vector& filament_map) + static long long estimate_dedup_enum_count(int k, int n, const FilamentGroupContext& ctx) { - std::vector ret = filament_map; - std::unordered_map> groups; - for (size_t idx = 0; idx < used_filaments.size(); ++idx) { - int filament_id = used_filaments[idx]; - int group_id = ret[filament_id]; - groups[group_id].insert(filament_id); + if (n <= 0 || k <= 0) return 0; + + long long total = 1; + for (int i = 0; i < n; ++i) { + total *= k; + if (total > ENUM_EARLY_EXIT) return total; } - int none_master_extruder_id = 1 - ctx.machine_info.master_extruder_id; - assert(0 <= none_master_extruder_id && none_master_extruder_id <= 1); + if (k <= 1) return total; - if (can_swap_groups(none_master_extruder_id, groups[none_master_extruder_id], ctx.machine_info.master_extruder_id, groups[ctx.machine_info.master_extruder_id], ctx) - && groups[none_master_extruder_id].size()>groups[ctx.machine_info.master_extruder_id].size()) { - for (auto fid : groups[none_master_extruder_id]) - ret[fid] = ctx.machine_info.master_extruder_id; - for (auto fid : groups[ctx.machine_info.master_extruder_id]) - ret[fid] = none_master_extruder_id; + int dedup_factor = 1; + std::map nozzle_type_count; + for (const auto& nozzle : ctx.nozzle_info.nozzle_list) { + auto it = ctx.nozzle_info.nozzle_status.find(nozzle.group_id); + int loaded_filament = (it != ctx.nozzle_info.nozzle_status.end()) ? it->second : -1; + uint64_t hash = fnv_hash_nozzle(nozzle.volume_type, nozzle.group_id > 0, loaded_filament); + nozzle_type_count[hash]++; } - return ret; + + for (auto& [hash, count] : nozzle_type_count) { + int factorial = 1; + for (int i = 2; i <= count; ++i) factorial *= i; + dedup_factor *= factorial; + } + + return total / std::max(dedup_factor, 1); + } + + std::vector FilamentGroup::calc_group_by_enum( + int k, + const std::vector& used_filaments, + const std::unordered_map>& unplaceable_limits, + int* cost) + { + static constexpr int UNPLACEABLE_LIMIT_REWARD = 10000; + static constexpr int MAX_SIZE_LIMIT_REWARD = 5000; + static constexpr int SUPPORT_PREFER_REWARD = 100; + static constexpr int BEST_FIT_LIMIT_REWARD = 10; + + int n = (int)used_filaments.size(); + + std::vector> candidates(n); + for (int i = 0; i < n; i++) { + std::unordered_set group_set; + if (auto it = unplaceable_limits.find(i); it != unplaceable_limits.end()) { + for (int g = 0; g < k; g++) group_set.insert(g); + for (int g : it->second) group_set.erase(g); + } else { + for (int g = 0; g < k; g++) group_set.insert(g); + } + candidates[i].assign(group_set.begin(), group_set.end()); + } + + auto vector_equal = [](const std::vector& a, const std::vector& b) -> bool { + if (a.size() != b.size()) return false; + for (size_t i = 0; i < a.size(); i++) { + if (a[i] != b[i]) return false; + } + return true; + }; + auto vector_hash = [](const std::vector& v) -> size_t { + size_t h = 0; + for (auto val : v) { h ^= val + GOLDEN_RATIO_32 + (h << 6) + (h >> 2); } + return h; + }; + std::unordered_set, decltype(vector_hash), decltype(vector_equal)> group_set(0, vector_hash, vector_equal); + std::vector group_hashs; + + std::vector nozzles_hash(k); + for (const auto& nozzle : ctx.nozzle_info.nozzle_list) { + if (nozzle.group_id < k) { + auto it = ctx.nozzle_info.nozzle_status.find(nozzle.group_id); + int loaded_filament = (it != ctx.nozzle_info.nozzle_status.end()) ? it->second : -1; + nozzles_hash[nozzle.group_id] = fnv_hash_nozzle(nozzle.volume_type, nozzle.group_id > 0, loaded_filament); + } + } + + std::vector best_full_map(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); + double best_score = std::numeric_limits::max(); + int best_prefer_level = 0; + int best_flush = 0; + + const long long total = (long long)std::pow(k, n); + for (long long mask = 0; mask < total; mask++) { + long long num = mask; + std::unordered_map> nozzles_filaments; + std::vector groups_count(k, 0); + std::vector used_labels(n, 0); + + for (int i = 0; i < n; i++) { + int g_id = num % k; + num /= k; + used_labels[i] = g_id; + nozzles_filaments[g_id].emplace_back(i); + groups_count[g_id]++; + } + + // Hash dedup + group_hashs.clear(); + for (auto& nf : nozzles_filaments) { + uint64_t filament_mask = 0; + for (int filament : nf.second) filament_mask |= (1ULL << filament); + size_t gh = nozzles_hash[nf.first]; + gh ^= (std::hash{}(filament_mask) + GOLDEN_RATIO_32 + (gh << 6) + (gh >> 2)); + group_hashs.emplace_back(gh); + } + std::sort(group_hashs.begin(), group_hashs.end()); + if (group_set.find(group_hashs) != group_set.end()) continue; + group_set.insert(group_hashs); + + // Prefer level + int prefer_level = 0; + int placeable_count = 0; + for (int i = 0; i < n; i++) { + if (std::find(candidates[i].begin(), candidates[i].end(), used_labels[i]) != candidates[i].end()) + placeable_count++; + } + prefer_level += placeable_count * UNPLACEABLE_LIMIT_REWARD; + + bool size_ok = true; + for (int g = 0; g < k; g++) { + if (g < (int)ctx.machine_info.max_group_size.size() && groups_count[g] > ctx.machine_info.max_group_size[g]) + size_ok = false; + } + if (size_ok) + prefer_level += MAX_SIZE_LIMIT_REWARD; + + if (ctx.group_info.strategy == FGStrategy::BestFit) { + bool all_full = true; + for (int g = 0; g < k; g++) { + if (g < (int)ctx.machine_info.max_group_size.size() && groups_count[g] < ctx.machine_info.max_group_size[g]) + all_full = false; + } + if (all_full) + prefer_level += BEST_FIT_LIMIT_REWARD; + } + + for (int g = 0; g < k; g++) { + if (g < (int)ctx.machine_info.prefer_non_model_filament.size() && ctx.machine_info.prefer_non_model_filament[g]) { + for (int fidx : nozzles_filaments[g]) { + if (ctx.model_info.filament_info[used_filaments[fidx]].usage_type == SupportOnly) + prefer_level += SUPPORT_PREFER_REWARD; + } + } + } + + // Build full map and evaluate + std::vector full_map(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); + for (int i = 0; i < n; ++i) + full_map[used_filaments[i]] = used_labels[i]; + + int flush_vol = 0; + double score = full_evaluate(used_filaments, full_map, ctx, get_custom_seq, &flush_vol); + + int master_ex_id = ctx.machine_info.master_extruder_id; + if (master_ex_id < k && groups_count[master_ex_id] < (int)(used_filaments.size() + 1) / 2) + score += ABSOLUTE_FLUSH_GAP_TOLERANCE; + + if (prefer_level > best_prefer_level || (prefer_level == best_prefer_level && score < best_score)) { + best_score = score; + best_prefer_level = prefer_level; + best_full_map = full_map; + best_flush = flush_vol; + } + + MemoryedGroup mg(used_labels, score, prefer_level); + update_memoryed_groups(mg, ctx.group_info.max_gap_threshold, m_memoryed_heap); + } + + if (cost) *cost = best_flush; + return best_full_map; + } + + std::vector FilamentGroup::calc_group_by_kmedoids( + int k, + const std::vector& used_filaments, + const std::unordered_map>& unplaceable_limits, + int* cost) + { + auto distance_evaluator = std::make_shared(ctx.model_info.flush_matrix, used_filaments, ctx.model_info.layer_filaments); + KMediods PAM(k, (int)used_filaments.size(), distance_evaluator, ctx.machine_info.master_extruder_id); + PAM.set_unplacable_limits(unplaceable_limits); + PAM.set_memory_threshold(ctx.group_info.max_gap_threshold); + + std::vector, int>> cluster_size_limit; + for (auto& [extruder_id, nozzles] : ctx.nozzle_info.extruder_nozzle_list) { + std::pair, int> clusters; + clusters.first = std::set(nozzles.begin(), nozzles.end()); + clusters.second = ctx.machine_info.max_group_size.at(extruder_id); + cluster_size_limit.emplace_back(clusters); + } + PAM.set_cluster_group_size(cluster_size_limit); + + PAM.do_clustering(ctx, m_clustering_budget); + + m_memoryed_heap = PAM.get_memoryed_groups(); + + auto labels = PAM.get_cluster_labels(); + std::vector full_map(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); + for (int i = 0; i < (int)labels.size(); ++i) + full_map[used_filaments[i]] = labels[i]; + + if (cost) { + int flush_vol = 0; + full_evaluate(used_filaments, full_map, ctx, get_custom_seq, &flush_vol); + *cost = flush_vol; + } + + return full_map; } /** @@ -128,20 +394,26 @@ namespace Slic3r * considered valid. * * @param map_lists Group list with similar flush count + * @param nozzle_lists nozzle_id -> extruder_id * @param used_filaments Idx of used filaments * @param used_filament_info Information of filaments used * @param machine_filament_info Information of filaments loaded in printer * @param color_threshold Threshold for considering colors to be similar * @return The group that best fits the filament distribution in AMS */ - std::vector select_best_group_for_ams(const std::vector>& map_lists, + std::vector select_best_group_for_ams(const std::vector>& filament_to_nozzles, + const std::vector& nozzle_list, const std::vector& used_filaments, - const std::vector& used_filament_info, + const std::vector& used_filament_info, const std::vector>& machine_filament_info_, + const bool has_filament_switcher, const double color_threshold) { using namespace FlushPredict; + if (has_filament_switcher) + return filament_to_nozzles.size() ? filament_to_nozzles.front() : std::vector(); + const int fail_cost = 9999; // these code is to make we machine filament info size is 2 @@ -151,12 +423,13 @@ namespace Slic3r int best_cost = std::numeric_limits::max(); std::vectorbest_map; - for (auto& map : map_lists) { + for (auto &filament_to_nozzle : filament_to_nozzles) { std::vector> group_filaments(2); std::vector>group_colors(2); for (size_t i = 0; i < used_filaments.size(); ++i) { - int target_group = map[used_filaments[i]] == 0 ? 0 : 1; + auto &nozzle = nozzle_list[filament_to_nozzle[used_filaments[i]]]; + int target_group = nozzle.extruder_id == 0 ? 0 : 1; group_colors[target_group].emplace_back(used_filament_info[i].color); group_filaments[target_group].emplace_back(i); } @@ -211,7 +484,7 @@ namespace Slic3r if (best_map.empty() || group_cost < best_cost) { best_cost = group_cost; - best_map = map; + best_map = filament_to_nozzle; } } @@ -228,7 +501,7 @@ namespace Slic3r return; } double gap_rate = (double)std::abs(elem.cost - best.cost) / (double)best.cost; - if (gap_rate < gap_threshold) + if (gap_rate <= gap_threshold) heap.push(elem); }; @@ -271,11 +544,11 @@ namespace Slic3r for (const auto& f : lf) used_filaments_set.insert(f); std::vectorused_filaments(used_filaments_set.begin(), used_filaments_set.end()); - std::sort(used_filaments.begin(), used_filaments.end()); + sort_remove_duplicates(used_filaments); return used_filaments; } - FlushDistanceEvaluator::FlushDistanceEvaluator(const FlushMatrix& flush_matrix, const std::vector& used_filaments, const std::vector>& layer_filaments, double p) + FlushDistanceEvaluator::FlushDistanceEvaluator(const std::vector& flush_matrix, const std::vector& used_filaments, const std::vector>& layer_filaments, double p) { //calc pair counts std::vector>count_matrix(used_filaments.size(), std::vector(used_filaments.size())); @@ -296,200 +569,362 @@ namespace Slic3r } } - m_distance_matrix.resize(used_filaments.size(), std::vector(used_filaments.size())); + m_distance_matrix.resize(flush_matrix.size(), std::vector>(used_filaments.size(), std::vector(used_filaments.size()))); for (size_t i = 0; i < used_filaments.size(); ++i) { for (size_t j = 0; j < used_filaments.size(); ++j) { - if (i == j) - m_distance_matrix[i][j] = 0; - else { + for (size_t k = 0; k < flush_matrix.size(); k++) { + if (i == j) + m_distance_matrix[k][i][j] = 0; + else { //TODO: check m_flush_matrix - float max_val = std::max(flush_matrix[used_filaments[i]][used_filaments[j]], flush_matrix[used_filaments[j]][used_filaments[i]]); - float min_val = std::min(flush_matrix[used_filaments[i]][used_filaments[j]], flush_matrix[used_filaments[j]][used_filaments[i]]); - m_distance_matrix[i][j] = (max_val * p + min_val * (1 - p)) * count_matrix[i][j]; - } - } - } - } - - double FlushDistanceEvaluator::get_distance(int idx_a, int idx_b) const - { - assert(0 <= idx_a && idx_a < m_distance_matrix.size()); - assert(0 <= idx_b && idx_b < m_distance_matrix.size()); - - return m_distance_matrix[idx_a][idx_b]; - } - - std::vector KMediods2::cluster_small_data(const std::map& unplaceable_limits, const std::vector& group_size) - { - std::vectorlabels(m_elem_count, -1); - std::vectornew_group_size = group_size; - - for (auto& [elem, center] : unplaceable_limits) { - if (labels[elem] == -1) { - int gid = 1 - center; - labels[elem] = gid; - new_group_size[gid] -= 1; - } - } - - for (auto& label : labels) { - if (label == -1) { - int gid = -1; - for (size_t idx = 0; idx < new_group_size.size(); ++idx) { - if (new_group_size[idx] > 0) { - gid = idx; - break; + float max_val = std::max(flush_matrix[k][used_filaments[i]][used_filaments[j]], flush_matrix[k][used_filaments[j]][used_filaments[i]]); + float min_val = std::min(flush_matrix[k][used_filaments[i]][used_filaments[j]], flush_matrix[k][used_filaments[j]][used_filaments[i]]); + m_distance_matrix[k][i][j] = (max_val * p + min_val * (1 - p)) * (std::max(count_matrix[i][j], 1)); } } - if (gid != -1) { - label = gid; - new_group_size[gid] -= 1; - } - else { - label = m_default_group_id; - } } } - - return labels; } - std::vector KMediods2::assign_cluster_label(const std::vector& center, const std::map& unplaceable_limtis, const std::vector& group_size, const FGStrategy& strategy) + double FlushDistanceEvaluator::get_distance(int idx_a, int idx_b, int extruder_id) const { - struct Comp { - bool operator()(const std::pair& a, const std::pair& b) { - return a.second > b.second; - } - }; + assert(0 <= idx_a && idx_a < m_distance_matrix[extruder_id].size()); + assert(0 <= idx_b && idx_b < m_distance_matrix[extruder_id].size()); - std::vector>groups(2); - std::vectornew_max_group_size = group_size; - // store filament idx and distance gap between center 0 and center 1 - std::priority_queue, std::vector>, Comp>min_heap; - - for (int i = 0; i < m_elem_count; ++i) { - if (auto it = unplaceable_limtis.find(i); it != unplaceable_limtis.end()) { - int gid = it->second; - assert(gid == 0 || gid == 1); - groups[1 - gid].insert(i); // insert to group - new_max_group_size[1 - gid] = std::max(new_max_group_size[1 - gid] - 1, 0); // decrease group_size - continue; - } - int distance_to_0 = m_evaluator->get_distance(i, center[0]); - int distance_to_1 = m_evaluator->get_distance(i, center[1]); - min_heap.push({ i,distance_to_0 - distance_to_1 }); - } - - bool have_enough_size = (min_heap.size() <= (new_max_group_size[0] + new_max_group_size[1])); - - if (have_enough_size || strategy == FGStrategy::BestFit) { - while (!min_heap.empty()) { - auto top = min_heap.top(); - min_heap.pop(); - if (groups[0].size() < new_max_group_size[0] && (top.second <= 0 || groups[1].size() >= new_max_group_size[1])) - groups[0].insert(top.first); - else if (groups[1].size() < new_max_group_size[1] && (top.second > 0 || groups[0].size() >= new_max_group_size[0])) - groups[1].insert(top.first); - else { - if (top.second <= 0) - groups[0].insert(top.first); - else - groups[1].insert(top.first); - } - } - } - else { - while (!min_heap.empty()) { - auto top = min_heap.top(); - min_heap.pop(); - if (top.second <= 0) - groups[0].insert(top.first); - else - groups[1].insert(top.first); - } - } - - std::vectorlabels(m_elem_count); - for (auto& f : groups[0]) - labels[f] = 0; - for (auto& f : groups[1]) - labels[f] = 1; - - return labels; + return m_distance_matrix[extruder_id][idx_a][idx_b]; } - int KMediods2::calc_cost(const std::vector& labels, const std::vector& medoids) + double TimeEvaluator::get_estimated_time(const std::vector& filament_map) const { + double time = 0; + for(auto &elem : m_speed_info.filament_print_time){ + int filament_idx = elem.first; + auto extruder_time = elem.second; + int filament_extruder_id = filament_map[filament_idx]; + time += extruder_time[filament_extruder_id]; + } + return time; + } + + + + void KMediods::set_cluster_group_size(const std::vector, int>> &cluster_group_size) + { + m_cluster_group_size = cluster_group_size; + m_nozzle_to_extruder.resize(m_k, 0); + for (int i = 0; i < m_cluster_group_size.size(); i++) { + for (auto nozzle_id : m_cluster_group_size[i].first) m_nozzle_to_extruder[nozzle_id] = i; + } + } + + int KMediods::calc_cost(const std::vector& cluster_labels, const std::vector& cluster_centers,int cluster_id) + { + assert(m_evaluator); int total_cost = 0; - for (int i = 0; i < m_elem_count; ++i) - total_cost += m_evaluator->get_distance(i, medoids[labels[i]]); + + std::vector> nozzle_cost(m_k,{0,0.0}); + std::vector nozzle_filaments(m_k, 0); + for (int i = 0; i < m_elem_count; ++i) { + if (cluster_id != -1 && cluster_labels[i] != cluster_id) + continue; + if (cluster_centers[cluster_labels[i]] == -1) + continue; + + nozzle_filaments[cluster_labels[i]]++; + for (int j = i + 1; j < m_elem_count; ++j) { + int nozzle_i = cluster_labels[i]; + int nozzle_j = cluster_labels[j]; + if (nozzle_i == nozzle_j) { + nozzle_cost[nozzle_i].first++; + nozzle_cost[nozzle_j].second += m_evaluator->get_distance(i, j, m_nozzle_to_extruder[nozzle_i]); + } + } + } + for (size_t i = 0; i < nozzle_cost.size(); ++i) { + if (nozzle_filaments[i] > 0 && nozzle_cost[i].second > 0) + total_cost += nozzle_cost[i].second / nozzle_cost[i].first * (nozzle_filaments[i] - 1); + } + return total_cost; } - void KMediods2::do_clustering(const FGStrategy& g_strategy, int timeout_ms) + bool KMediods::have_enough_size(const std::vector& cluster_size, const std::vector, int>>& cluster_group_size,int elem_count) + { + bool have_enough_size = true; + std::optionalcluster_sum; + std::optionalcluster_group_sum; + + if (!cluster_size.empty()) + cluster_sum = std::accumulate(cluster_size.begin(), cluster_size.end(), 0); + if (!cluster_group_size.empty()) + cluster_group_sum = std::accumulate(cluster_group_size.begin(), cluster_group_size.end(), 0, [](int a, const std::pair, int>& p) {return a + p.second; }); + if (cluster_sum.has_value()) + have_enough_size &= (cluster_sum >= elem_count); + if (cluster_group_sum.has_value()) + have_enough_size &= (cluster_group_sum >= elem_count); + return have_enough_size; + } + + + // make sure each cluster has at least one element + std::vector KMediods::init_cluster_center(const std::unordered_map>& placeable_limits, const std::unordered_map>& unplaceable_limits,const std::vector& cluster_size,const std::vector,int>>& cluster_group_size, int seed) + { + // max flow network + std::vector l_nodes(m_elem_count); // represent the filament idx, to be shuffled + std::vector r_nodes(m_k); // represent the group idx + std::iota(l_nodes.begin(), l_nodes.end(), 0); + std::iota(r_nodes.begin(), r_nodes.end(), 0); + + std::unordered_map> shuffled_placeable_limits; + std::unordered_map> shuffled_unplaceable_limits; + // shuffle the filaments and transfer placeable,unplaceable limits + { + std::mt19937 rng(seed); + std::shuffle(l_nodes.begin(), l_nodes.end(), rng); + + std::unordered_mapidx_transfer; + for (size_t idx = 0; idx < l_nodes.size(); ++idx){ + int new_idx = std::find(l_nodes.begin(),l_nodes.end(), idx) - l_nodes.begin(); + idx_transfer[idx] = new_idx; + } + for (auto& elem : placeable_limits) + shuffled_placeable_limits[idx_transfer[elem.first]] = elem.second; + for (auto& elem : unplaceable_limits) + shuffled_unplaceable_limits[idx_transfer[elem.first]] = elem.second; + } + + + MaxFlowSolver M(l_nodes, r_nodes, shuffled_placeable_limits, shuffled_unplaceable_limits); + auto ret = M.solve(); + + // A remaining -1 means some filaments cannot be placed under the limit. We ignore the -1 here since we + // are deciding the cluster center; the -1 can be handled in later steps. + std::vector cluster_center(m_k, -1); + for (size_t idx = 0; idx < ret.size(); ++idx) { + if (ret[idx] != -1) { + cluster_center[ret[idx]] = l_nodes[idx]; + } + } + + return cluster_center; + } + + std::vector KMediods::assign_cluster_label(const std::vector& center, const std::unordered_map>& placeable_limits, const std::unordered_map>& unplaceable_limits, const std::vector& cluster_size, const std::vector, int>>& cluster_group_size) + { + std::vector labels(m_elem_count, -1); + std::vector l_nodes(m_elem_count); + std::vector r_nodes(m_k); + std::iota(l_nodes.begin(), l_nodes.end(), 0); + std::iota(r_nodes.begin(), r_nodes.end(), 0); + + std::vector> distance_matrix(m_elem_count, std::vector(m_k)); + for (int i = 0; i < m_elem_count; ++i) { + for (int j = 0; j < m_k; ++j) { + if (center[j] == -1) + distance_matrix[i][j] = static_cast(MaxFlowGraph::MCMF_MAX_EDGE_COST); + else + distance_matrix[i][j] = m_evaluator->get_distance(i, center[j], m_nozzle_to_extruder[j]); + } + } + + // only consider the size limit if the group can contain all of the filaments + std::vector r_nodes_capacity = {}; + std::vector, int>> r_nodes_group_capacity = {}; + if (have_enough_size(cluster_size, cluster_group_size, m_elem_count)) { + r_nodes_capacity = cluster_size; + r_nodes_group_capacity = cluster_group_size; + } + else { + // TODO: throw exception here? + // adjust group size to elem count if the group cannot contain all of the filaments + r_nodes_capacity = std::vector(m_k, m_elem_count); + } + std::vector l_nodes_capacity(l_nodes.size(),1); + //for (size_t idx = 0; idx < center.size(); ++idx) + // if (center[idx] != -1) + // l_nodes_capacity[center[idx]] = 0; + + + // Each group can receive up to m_elem_count materials at most, so the flow from r_nodes to sink is adjusted to m_elem_count. + MinFlushFlowSolver M(distance_matrix, l_nodes, r_nodes, placeable_limits, unplaceable_limits, l_nodes_capacity, r_nodes_capacity, r_nodes_group_capacity); + auto ret = M.solve(); + + for (size_t idx = 0; idx < ret.size(); ++idx) { + if (ret[idx] != MaxFlowGraph::INVALID_ID) { + labels[l_nodes[idx]] = r_nodes[ret[idx]]; + } + } + + for (size_t idx = 0; idx < center.size(); ++idx) + if (center[idx] != -1) + assert(labels[center[idx]] == idx); + + //for (size_t idx = 0; idx < center.size(); ++idx) { + // if (center[idx] != -1) { + // labels[center[idx]] = idx; + // } + //} + + // If there are materials that have not been grouped in the last step, assign them to a valid group. + for (size_t idx = 0; idx < labels.size(); ++idx) { + if (labels[idx] == -1) { + int fallback = m_default_group_id; + auto it = unplaceable_limits.find(static_cast(idx)); + if (it != unplaceable_limits.end()) { + for (int nid = 0; nid < m_k; ++nid) { + if (std::find(it->second.begin(), it->second.end(), nid) == it->second.end()) { + fallback = nid; + break; + } + } + } + labels[idx] = fallback; + } + } + + return labels; + } + + /* + 1.Select initial medoids randomly + 2.Iterate while the cost decreases: + 2.1 In each cluster, make the point that minimizes the sum of distances within the cluster the medoid + 2.2 Reassign each point to the cluster defined by the closest medoid determined in the previous step + */ + void KMediods::do_clustering(const FilamentGroupContext& context, const ClusteringBudget& budget) { FlushTimeMachine T; T.time_machine_start(); - if (m_elem_count < m_k) { - m_cluster_labels = cluster_small_data(m_unplaceable_limits, m_max_cluster_size); - { - std::vectorcluster_center(m_k, -1); - for (size_t idx = 0; idx < m_cluster_labels.size(); ++idx) { - if (cluster_center[m_cluster_labels[idx]] == -1) - cluster_center[m_cluster_labels[idx]] = idx; - } - MemoryedGroup g(m_cluster_labels, calc_cost(m_cluster_labels, cluster_center), 1); - update_memoryed_groups(g, memory_threshold, memoryed_groups); - } - return; - } + const std::vector used_filaments = collect_sorted_used_filaments(context.model_info.layer_filaments); - std::vectorbest_labels; - int best_cost = std::numeric_limits::max(); + auto build_full_map = [&](const std::vector& labels) -> std::vector { + std::vector full_map(context.group_info.total_filament_num, m_default_group_id); + for (int i = 0; i < (int)labels.size(); ++i) + full_map[used_filaments[i]] = labels[i]; + return full_map; + }; - for (int center_0 = 0; center_0 < m_elem_count; ++center_0) { - if (auto iter = m_unplaceable_limits.find(center_0); iter != m_unplaceable_limits.end() && iter->second == 0) - continue; - for (int center_1 = 0; center_1 < m_elem_count; ++center_1) { - if (center_0 == center_1) - continue; - if (auto iter = m_unplaceable_limits.find(center_1); iter != m_unplaceable_limits.end() && iter->second == 1) - continue; + auto evaluate_labels = [&](const std::vector& labels) -> double { + auto full_map = build_full_map(labels); + return full_evaluate(used_filaments, full_map, context); + }; - std::vectornew_centers = { center_0,center_1 }; - std::vectornew_labels = assign_cluster_label(new_centers, m_unplaceable_limits, m_max_cluster_size, g_strategy); + std::vector best_cluster_centers = std::vector(m_k, 0); + std::vector best_cluster_labels = std::vector(m_elem_count, m_default_group_id); + double best_cluster_cost = std::numeric_limits::max(); + int retry_count = 0; - int new_cost = calc_cost(new_labels, new_centers); - if (new_cost < best_cost) { - best_cost = new_cost; - best_labels = new_labels; + // Run at least one restart; otherwise every filament would stay in the default group. + const int retry = std::max(1, budget.max_restarts); + auto within_budget = [&]() { return budget.timeout_ms <= 0 || T.time_machine_end() < budget.timeout_ms; }; + + while (retry_count < retry && within_budget()) { + std::vector curr_cluster_centers = init_cluster_center(m_placeable_limits, m_unplaceable_limits, m_max_cluster_size, m_cluster_group_size, retry_count); + std::vector curr_cluster_labels = assign_cluster_label(curr_cluster_centers, m_placeable_limits, m_unplaceable_limits, m_max_cluster_size, m_cluster_group_size); + double curr_cluster_cost = evaluate_labels(curr_cluster_labels); + + MemoryedGroup g(curr_cluster_labels, curr_cluster_cost, 1); + update_memoryed_groups(g, memory_threshold, memoryed_groups); + + bool mediods_changed = true; + while (mediods_changed && within_budget()) { + mediods_changed = false; + double best_swap_cost = curr_cluster_cost; + int best_swap_cluster = -1; + int best_swap_elem = -1; + + for (size_t cluster_id = 0; cluster_id < m_k; ++cluster_id) { + if (curr_cluster_centers[cluster_id] == -1) continue; + for (int elem = 0; elem < m_elem_count; ++elem) { + if (std::find(curr_cluster_centers.begin(), curr_cluster_centers.end(), elem) != curr_cluster_centers.end() || + std::find(m_unplaceable_limits[cluster_id].begin(), m_unplaceable_limits[cluster_id].end(), elem) != m_unplaceable_limits[cluster_id].end()) + continue; + std::vector tmp_centers = curr_cluster_centers; + tmp_centers[cluster_id] = elem; + std::vector tmp_labels = assign_cluster_label(tmp_centers, m_placeable_limits, m_unplaceable_limits, m_max_cluster_size, m_cluster_group_size); + double tmp_cost = evaluate_labels(tmp_labels); + + if (tmp_cost < best_swap_cost) { + best_swap_cost = tmp_cost; + best_swap_cluster = cluster_id; + best_swap_elem = elem; + mediods_changed = true; + } + } } - { - MemoryedGroup g(new_labels,new_cost,1); + if (mediods_changed) { + curr_cluster_centers[best_swap_cluster] = best_swap_elem; + curr_cluster_labels = assign_cluster_label(curr_cluster_centers, m_placeable_limits, m_unplaceable_limits, m_max_cluster_size, m_cluster_group_size); + curr_cluster_cost = evaluate_labels(curr_cluster_labels); + + MemoryedGroup g(curr_cluster_labels, curr_cluster_cost, 1); update_memoryed_groups(g, memory_threshold, memoryed_groups); } - - if (T.time_machine_end() > timeout_ms) - break; } - if (T.time_machine_end() > timeout_ms) - break; + + if (curr_cluster_cost < best_cluster_cost) { + best_cluster_centers = curr_cluster_centers; + best_cluster_cost = curr_cluster_cost; + best_cluster_labels = curr_cluster_labels; + } + retry_count += 1; } - this->m_cluster_labels = best_labels; + m_cluster_labels = best_cluster_labels; } std::vector FilamentGroup::calc_min_flush_group(int* cost) { auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); - int used_filament_num = used_filaments.size(); + int n = (int)used_filaments.size(); + int k = (int)ctx.nozzle_info.nozzle_list.size(); - if (used_filament_num < 10) - return calc_min_flush_group_by_enum(used_filaments, cost); + std::unordered_map> unplaceable_limits; + extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unplaceable_limits); + unplaceable_limits = rebuild_nozzle_unprintables(used_filaments, unplaceable_limits, ctx.group_info.filament_volume_map); + + m_memoryed_heap = MemoryedGroupHeap(); + std::vector result; + + long long estimated = estimate_dedup_enum_count(k, n, ctx); + if (estimated < ENUM_THRESHOLD) + result = calc_group_by_enum(k, used_filaments, unplaceable_limits, cost); else - return calc_min_flush_group_by_pam2(used_filaments, cost, 500); + result = calc_group_by_kmedoids(k, used_filaments, unplaceable_limits, cost); + + change_memoryed_heaps_to_arrays(m_memoryed_heap, ctx.group_info.total_filament_num, used_filaments, m_memoryed_groups); + + return result; + } + + std::map FilamentGroup::rebuild_unprintables(const std::vector& used_filaments, const std::map& extruder_unprintables) + { + std::map ret; + for (int f_idx = 0; f_idx < used_filaments.size(); f_idx++) { + int unprintable_ext = -1; + if (extruder_unprintables.find(f_idx) != extruder_unprintables.end()) { + unprintable_ext = extruder_unprintables.at(f_idx); + } + + bool multi_unprintable = false; + auto unprintable_volumes = ctx.model_info.unprintable_volumes[used_filaments[f_idx]]; + for (int nozzle_idx = 0; nozzle_idx != ctx.nozzle_info.nozzle_list.size(); nozzle_idx++) { + auto nozzle_info = ctx.nozzle_info.nozzle_list[nozzle_idx]; + + if (unprintable_volumes.count(nozzle_info.volume_type)) { + if (unprintable_ext == -1) + unprintable_ext = nozzle_info.extruder_id; + else if (unprintable_ext != nozzle_info.extruder_id) + multi_unprintable = true; + } + } + + if (!multi_unprintable && unprintable_ext != -1) ret[f_idx] = unprintable_ext; + + } + return ret; } std::unordered_map> FilamentGroup::try_merge_filaments() @@ -577,6 +1012,11 @@ namespace Slic3r std::vector FilamentGroup::calc_filament_group(int* cost) { + /*auto extruder_variant_list = ctx.nozzle_info.extruder_nozzle_list; + for (auto nozzle : ctx.nozzle_info.nozzle_list) + if (nozzle.volume_type == NozzleVolumeType::nvtTPUHighFlow) + return calc_filament_group_for_tpu(cost);*/ + try { if (FGMode::MatchMode == ctx.group_info.mode) return calc_filament_group_for_match(cost); @@ -584,18 +1024,16 @@ namespace Slic3r catch (const FilamentGroupException& e) { } - auto merged_map = try_merge_filaments(); - rebuild_context(merged_map); - auto filamnet_map = calc_filament_group_for_flush(cost); - return seperate_merged_filaments(filamnet_map, merged_map); + return calc_filament_group_for_flush(cost); } std::vector FilamentGroup::calc_filament_group_for_match(int* cost) { using namespace FlushPredict; + constexpr int SupportPreferScore = 3; auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); - std::vector used_filament_list; + std::vector used_filament_list; for (auto f : used_filaments) used_filament_list.emplace_back(ctx.model_info.filament_info[f]); @@ -613,6 +1051,7 @@ namespace Slic3r std::map unprintable_limit_indices; // key stores filament idx in used_filament, value stores unprintable extruder extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unprintable_limit_indices); + unprintable_limit_indices = rebuild_unprintables(used_filaments, unprintable_limit_indices); std::vector> color_dist_matrix(used_filament_list.size(), std::vector(machine_filament_list.size())); for (size_t i = 0; i < used_filament_list.size(); ++i) { @@ -652,19 +1091,17 @@ namespace Slic3r return unlink_limits; }; - auto optimize_map_to_machine_filament = [&](const std::vector& map_to_machine_filament, const std::vector& l_nodes, const std::vector& r_nodes, std::vector& filament_map, bool consider_capacity) { + auto optimize_map_to_machine_filament = [&](const std::vector& map_to_machine_filament, const std::vector& l_nodes, const std::vector& r_nodes, std::vector& filament_map) { std::vector ungrouped_filaments; std::vector filaments_to_optimize; auto map_filament_to_machine_filament = [&](int filament_idx, int machine_filament_idx) { auto& machine_filament = machine_filament_list[machine_filament_idx]; - machine_filament_capacity[machine_filament_idx] = std::max(0, machine_filament_capacity[machine_filament_idx] - 1); // decrease machine filament capacity filament_map[used_filaments[filament_idx]] = machine_filament.extruder_id; // set extruder id to filament map extruder_filament_count[machine_filament.extruder_id] += 1; // increase filament count in extruder }; auto unmap_filament_to_machine_filament = [&](int filament_idx, int machine_filament_idx) { auto& machine_filament = machine_filament_list[machine_filament_idx]; - machine_filament_capacity[machine_filament_idx] += 1; // increase machine filament capacity extruder_filament_count[machine_filament.extruder_id] -= 1; // increase filament count in extruder }; @@ -684,25 +1121,63 @@ namespace Slic3r // try to optimize the result for (auto idx : filaments_to_optimize) { int filament_idx = l_nodes[idx]; + bool is_support_filament = used_filament_list[filament_idx].usage_type == FilamentUsageType::SupportOnly; int old_machine_filament_idx = r_nodes[map_to_machine_filament[idx]]; auto& old_machine_filament = machine_filament_list[old_machine_filament_idx]; - int curr_gap = std::abs(extruder_filament_count[0] - extruder_filament_count[1]); unmap_filament_to_machine_filament(filament_idx, old_machine_filament_idx); auto optional_filaments = machine_filament_set[old_machine_filament]; - auto iter = optional_filaments.begin(); - for (; iter != optional_filaments.end(); ++iter) { - int new_extruder_id = machine_filament_list[*iter].extruder_id; - int new_gap = std::abs(extruder_filament_count[new_extruder_id] + 1 - extruder_filament_count[1 - new_extruder_id]); - if (new_gap < curr_gap && (!consider_capacity || machine_filament_capacity[*iter] > 0)) { - map_filament_to_machine_filament(filament_idx, *iter); - break; + + // Phase 1: collect all candidates and compute their preference scores + std::vector> valid_candidates; // available machine-filament idx and its score + for (auto machine_filament : optional_filaments) { + int new_extruder_id = machine_filament_list[machine_filament].extruder_id; + + // preference score for this assignment + int preference_score = 0; + bool new_extruder_prefer_support = ctx.machine_info.prefer_non_model_filament[new_extruder_id]; + + // reward a support filament assigned to a support-preferring nozzle + if (is_support_filament && new_extruder_prefer_support) { + preference_score += SupportPreferScore; + } + + valid_candidates.emplace_back(machine_filament, preference_score); + } + // Phase 2: determine the best preference score + int best_preference_score = 0; + for (const auto& candidate : valid_candidates) { + if (candidate.second >= best_preference_score) { + best_preference_score = candidate.second; } } - if (iter == optional_filaments.end()) + // Phase 3: among candidates with the best preference score, pick the most load-balanced one + int best_candidate = -1; + int best_gap = std::numeric_limits::max(); + + for (const auto& candidate : valid_candidates) { + // only consider candidates with the best preference score + int machine_filament = candidate.first; + int score = candidate.second; + if (score == best_preference_score) { + int new_extruder_id = machine_filament_list[machine_filament].extruder_id; + int new_gap = std::abs(extruder_filament_count[new_extruder_id] + 1 - extruder_filament_count[1 - new_extruder_id]); + + // among equal-preference candidates, pick the one giving the most balanced load + if (new_gap < best_gap) { + best_gap = new_gap; + best_candidate = machine_filament; + } + } + } + // apply the best choice + if (best_candidate != -1) { + map_filament_to_machine_filament(filament_idx, best_candidate); + } else { map_filament_to_machine_filament(filament_idx, old_machine_filament_idx); + } } return ungrouped_filaments; }; @@ -718,7 +1193,7 @@ namespace Slic3r { MatchModeGroupSolver s(color_dist_matrix, l_nodes, r_nodes, machine_filament_capacity, unlink_limits_full); - ungrouped_filaments = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes,group,false); + ungrouped_filaments = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes,group); if (ungrouped_filaments.empty()) return group; } @@ -731,7 +1206,7 @@ namespace Slic3r }); MatchModeGroupSolver s(color_dist_matrix, l_nodes, r_nodes, machine_filament_capacity, unlink_limits); - ungrouped_filaments = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes, group,false); + ungrouped_filaments = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes, group); if (ungrouped_filaments.empty()) return group; } @@ -740,7 +1215,7 @@ namespace Slic3r { l_nodes = ungrouped_filaments; MatchModeGroupSolver s(color_dist_matrix, l_nodes, r_nodes, machine_filament_capacity, {}); - auto ret = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes, group,false); + auto ret = optimize_map_to_machine_filament(s.solve(), l_nodes, r_nodes, group); for (size_t idx = 0; idx < ret.size(); ++idx) { if (ret[idx] == MaxFlowGraph::INVALID_ID) assert(false); @@ -760,140 +1235,253 @@ namespace Slic3r std::vector> memoryed_maps = this->m_memoryed_groups; memoryed_maps.insert(memoryed_maps.begin(), ret); - std::vector optimized_ret = optimize_group_for_master_extruder(used_filaments, ctx, ret); - if (optimized_ret != ret) - memoryed_maps.insert(memoryed_maps.begin(), optimized_ret); - std::vector used_filament_info; for (auto f : used_filaments) { used_filament_info.emplace_back(ctx.model_info.filament_info[f]); } - ret = select_best_group_for_ams(memoryed_maps, used_filaments, used_filament_info, ctx.machine_info.machine_filament_info); + ret = select_best_group_for_ams(memoryed_maps, ctx.nozzle_info.nozzle_list, used_filaments, used_filament_info, ctx.machine_info.machine_filament_info, ctx.group_info.has_filament_switcher); return ret; } + std::vector FilamentGroup::calc_filament_group_for_tpu(int *cost) { + + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + std::vector used_filament_list; + for (auto f : used_filaments) + used_filament_list.emplace_back(ctx.model_info.filament_info[f]); + + std::vector> print_time_matrix(used_filaments.size(), std::vector(ctx.nozzle_info.extruder_nozzle_list.size())); + for (int i = 0; i < used_filaments.size(); ++i){ + for (int j = 0; j < ctx.nozzle_info.extruder_nozzle_list.size(); ++j){ + print_time_matrix[i][j] = ctx.speed_info.filament_print_time[used_filaments[i]][j]; + if (ctx.nozzle_info.nozzle_list[j].volume_type == nvtTPUHighFlow) // when both TPU High Flow and other nozzle types exist, prefer assigning filament to the TPU High Flow nozzle + print_time_matrix[i][j] *= 0.9; + } + } + + std::vector l_nodes(used_filaments.size()); + std::iota(l_nodes.begin(), l_nodes.end(), 0); + std::vector r_nodes(ctx.nozzle_info.extruder_nozzle_list.size()); + std::iota(r_nodes.begin(), r_nodes.end(), 0); + std::vector machine_filament_capacity({int(used_filaments.size()), int(used_filaments.size())}); + + std::map unprintable_limit_indices; // key stores filament idx in used_filament, value stores unprintable extruder + extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unprintable_limit_indices); + unprintable_limit_indices = rebuild_unprintables(used_filaments, unprintable_limit_indices); + + std::unordered_map> unlink_limits(used_filaments.size()); + for (int i = 0; i < used_filaments.size(); i++) { + auto iter = unprintable_limit_indices.find(i); + if (iter == unprintable_limit_indices.end() || iter->second < 0 || iter->second >= 2) continue; + unlink_limits[i].emplace_back(iter->second); + } + + MatchModeGroupSolver s(print_time_matrix, l_nodes, r_nodes, machine_filament_capacity, unlink_limits); + auto ret = s.solve(); + for (size_t idx = 0; idx < ret.size(); ++idx) { + if (ret[idx] == MaxFlowGraph::INVALID_ID) { + assert(false); + ret[idx] = 1; + } + } + std::vector group(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); + for (int i = 0; i < ret.size(); ++i) group[used_filaments[i]] = ret[i]; + return group; + } // sorted used_filaments - std::vector FilamentGroup::calc_min_flush_group_by_enum(const std::vector& used_filaments, int* cost) + + std::unordered_map> FilamentGroup::rebuild_nozzle_unprintables(const std::vector& used_filaments, const std::unordered_map>& extruder_unprintables, const std::vector& filament_volume_map) { - static constexpr int UNPLACEABLE_LIMIT_REWARD = 100; // reward value if the group result follows the unprintable limit - static constexpr int MAX_SIZE_LIMIT_REWARD = 10; // reward value if the group result follows the max size per extruder - static constexpr int BEST_FIT_LIMIT_REWARD = 1; // reward value if the group result try to fill the max size per extruder + std::unordered_map> nozzle_unprintables; - MemoryedGroupHeap memoryed_groups; + for(size_t fidx = 0 ;fidx unexpected_extruders; + if(extruder_unprintables.find(fidx) != extruder_unprintables.end()){ + unexpected_extruders = extruder_unprintables.at(fidx); + } - auto bit_count_one = [](uint64_t n) - { - int count = 0; - while (n != 0) - { - n &= n - 1; - count++; + auto unprintable_volumes = ctx.model_info.unprintable_volumes[used_filaments[fidx]]; + + std::vector unprintable_nozzles; + for(size_t nozzle_idx =0 ;nozzle_idx < ctx.nozzle_info.nozzle_list.size(); ++nozzle_idx){ + auto nozzle_info = ctx.nozzle_info.nozzle_list[nozzle_idx]; + + if(std::find(unexpected_extruders.begin(), unexpected_extruders.end(), nozzle_info.extruder_id)!= unexpected_extruders.end() || (expected_volume!=nvtHybrid && expected_volume != nozzle_info.volume_type) || + (unprintable_volumes.count(nozzle_info.volume_type) != 0)) + unprintable_nozzles.push_back(nozzle_idx); + } + if(unprintable_nozzles.empty()) + continue; + + sort_remove_duplicates(unprintable_nozzles); + nozzle_unprintables[fidx] = unprintable_nozzles; + } + + return nozzle_unprintables; + } + + + std::vector calc_filament_group_for_match_multi_nozzle(const FilamentGroupContext& ctx) + { + FilamentGroup fg1(ctx); + auto filament_extruder_map = fg1.calc_filament_group_for_match(); + + FilamentGroupContext new_ctx = ctx; + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + for(size_t idx = 0; idx < used_filaments.size(); ++idx) + new_ctx.model_info.unprintable_filaments[1 - filament_extruder_map[used_filaments[idx]]].insert(used_filaments[idx]); + new_ctx.machine_info.max_group_size.assign(new_ctx.machine_info.max_group_size.size(), std::numeric_limits::max()); + FilamentGroup fg(new_ctx); + return fg.calc_filament_group_for_flush(); + } + + std::vector plan_filament_nozzle_mapping_and_order(const FilamentGroupContext &ctx) + { + std::vector res; + + // right nodes: nozzles + std::vector r_nodes(ctx.nozzle_info.nozzle_list.size(), -1); + auto initial_nozzle = ctx.nozzle_info.nozzle_status; + for (int r_id = 0; r_id < r_nodes.size(); r_id++) { if (initial_nozzle.count(r_id)) r_nodes[r_id] = initial_nozzle[r_id]; } + + std::vector r_nodes_group(ctx.nozzle_info.nozzle_list.size(), -1); + for (auto &nozzle_info : ctx.nozzle_info.nozzle_list) { r_nodes_group[nozzle_info.group_id] = nozzle_info.extruder_id; } + + int layer_nums = ctx.model_info.layer_filaments.size(); + auto &flush_matrix = ctx.model_info.flush_matrix; + + int prev_layer_last_nozzle_id = -1; + bool used_prev_layer_last_nozzle = false; + + // per-layer filament->nozzle matching + std::vector layer_fil_nozzle_match(ctx.model_info.filament_info.size(), 0); + for (int i = 0; i < layer_nums; i++) { + // left nodes: filaments, deduplicated + const auto &layer_filaments = ctx.model_info.layer_filaments[i]; + std::vector l_nodes(layer_filaments.begin(), layer_filaments.end()); + std::sort(l_nodes.begin(), l_nodes.end()); + l_nodes.erase(std::unique(l_nodes.begin(), l_nodes.end()), l_nodes.end()); + + if (l_nodes.empty()) { + res.emplace_back(FilamentPlanRes{{}, {}}); + continue; + } + + // per-layer queue of filaments used within each nozzle + std::vector> nozzle_fil_deq(r_nodes.size()); + + // build a reverse map from nozzle-loaded filament to nozzle index to speed lookups from O(n) to O(1) + std::unordered_map filament_to_nozzle; + filament_to_nozzle.reserve(r_nodes.size()); + for (size_t noz_id = 0; noz_id < r_nodes.size(); ++noz_id) { + if (r_nodes[noz_id] >= 0) { filament_to_nozzle[r_nodes[noz_id]] = noz_id; } + } + + const int epochs = std::ceil(double(l_nodes.size()) / r_nodes.size()); + for (int j = 0; j < epochs; j++) { + // 1. filter out filaments already matching the state loaded in a nozzle + std::vector remaining_l_nodes; + std::vector remaining_r_nodes; + std::vector remaining_r_nodes_to_origin; + std::vector used_r_nodes(r_nodes.size(), false); + + remaining_l_nodes.reserve(l_nodes.size()); + remaining_r_nodes.reserve(r_nodes.size()); + remaining_r_nodes_to_origin.reserve(r_nodes.size()); + + for (int f_id : l_nodes) { + auto it = filament_to_nozzle.find(f_id); + if (it != filament_to_nozzle.end()) { + size_t noz_id = it->second; + layer_fil_nozzle_match[f_id] = noz_id; + nozzle_fil_deq[noz_id].push_back(f_id); + used_prev_layer_last_nozzle = (noz_id == prev_layer_last_nozzle_id); + used_r_nodes[noz_id] = true; + } else { + remaining_l_nodes.emplace_back(f_id); + } } - return count; - }; + l_nodes = std::move(remaining_l_nodes); - std::mapunplaceable_limit_indices; - extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unplaceable_limit_indices); + for (int r_id = 0; r_id < r_nodes.size(); r_id++) { + if (!used_r_nodes[r_id]) { + remaining_r_nodes.emplace_back(r_nodes[r_id]); + remaining_r_nodes_to_origin.emplace_back(r_id); + } + } - int used_filament_num = used_filaments.size(); - uint64_t max_group_num = (static_cast(1) << used_filament_num); - - int best_cost = std::numeric_limits::max(); - std::vectorbest_label; - int best_prefer_level = 0; - - for (uint64_t i = 0; i < max_group_num; ++i) { - std::vector>groups(2); - for (int j = 0; j < used_filament_num; ++j) { - if (i & (static_cast(1) << j)) - groups[1].insert(j); - else - groups[0].insert(j); + // 2. run min-cost flow on the remaining nodes + GroupMinCostFlowSolver s(flush_matrix, l_nodes, remaining_r_nodes, r_nodes_group); + auto match = s.solve(); + int write = 0; + for (int l_id = 0; l_id < l_nodes.size(); l_id++) { + if (match[l_id] >= 0 && match[l_id] < remaining_r_nodes.size()) { + int noz_id = remaining_r_nodes_to_origin[match[l_id]]; + int filament_id = l_nodes[l_id]; + layer_fil_nozzle_match[filament_id] = noz_id; + r_nodes[noz_id] = filament_id; + nozzle_fil_deq[noz_id].push_back(filament_id); + // update the reverse map + filament_to_nozzle[filament_id] = noz_id; + } else { + l_nodes[write++] = l_nodes[l_id]; + } + } + l_nodes.resize(write); } - int prefer_level = 0; - - if (check_printable(groups, unplaceable_limit_indices)) - prefer_level += UNPLACEABLE_LIMIT_REWARD; - if (groups[0].size() <= ctx.machine_info.max_group_size[0] && groups[1].size() <= ctx.machine_info.max_group_size[1]) - prefer_level += MAX_SIZE_LIMIT_REWARD; - if (FGStrategy::BestFit == ctx.group_info.strategy && groups[0].size() >= ctx.machine_info.max_group_size[0] && groups[1].size() >= ctx.machine_info.max_group_size[1]) - prefer_level += BEST_FIT_LIMIT_REWARD; - - std::vectorfilament_maps(used_filament_num); - for (int i = 0; i < used_filament_num; ++i) { - if (groups[0].find(i) != groups[0].end()) - filament_maps[i] = 0; - if (groups[1].find(i) != groups[1].end()) - filament_maps[i] = 1; + // order the filaments within the layer + int start_extruder = 0; + int start_nozzle = 0; + if (used_prev_layer_last_nozzle) { + start_extruder = ctx.nozzle_info.nozzle_list[prev_layer_last_nozzle_id].extruder_id; + start_nozzle = prev_layer_last_nozzle_id; } - int total_cost = reorder_filaments_for_minimum_flush_volume( - used_filaments, - filament_maps, - ctx.model_info.layer_filaments, - ctx.model_info.flush_matrix, - get_custom_seq, - nullptr - ); - - if (prefer_level > best_prefer_level || (prefer_level == best_prefer_level && total_cost < best_cost)) { - best_prefer_level = prefer_level; - best_cost = total_cost; - best_label = filament_maps; + std::deque used_nozzle_deq; + for (int m = 0; m < ctx.nozzle_info.extruder_nozzle_list.size(); m++) { + int cur_extruder = (m + start_extruder) % ctx.nozzle_info.extruder_nozzle_list.size(); + for (auto noz_id : ctx.nozzle_info.extruder_nozzle_list.at(cur_extruder)) { + if (nozzle_fil_deq[noz_id].empty()) continue; + if (noz_id == start_nozzle) + used_nozzle_deq.push_front(noz_id); + else + used_nozzle_deq.push_back(noz_id); + } } - { - MemoryedGroup mg(filament_maps, total_cost, prefer_level); - update_memoryed_groups(mg, ctx.group_info.max_gap_threshold, memoryed_groups); + std::vector layer_fil_order; + for (auto noz_id : used_nozzle_deq) { + auto deq = nozzle_fil_deq[noz_id]; + layer_fil_order.reserve(layer_fil_order.size() + deq.size()); + layer_fil_order.insert(layer_fil_order.end(), deq.begin(), deq.end()); + + prev_layer_last_nozzle_id = noz_id; } + + FilamentPlanRes layer_pan{layer_fil_order, layer_fil_nozzle_match}; + res.emplace_back(layer_pan); } - if (cost) - *cost = best_cost; - - std::vector filament_labels(ctx.group_info.total_filament_num, 0); - for (size_t i = 0; i < best_label.size(); ++i) - filament_labels[used_filaments[i]] = best_label[i]; - - - change_memoryed_heaps_to_arrays(memoryed_groups, ctx.group_info.total_filament_num, used_filaments, m_memoryed_groups); - - return filament_labels; + return res; } - // sorted used_filaments - std::vector FilamentGroup::calc_min_flush_group_by_pam2(const std::vector& used_filaments, int* cost, int timeout_ms) + std::vector calc_filament_group_for_manual_multi_nozzle(const std::vector& filament_map_manual, const FilamentGroupContext& ctx) { - std::vectorfilament_labels_ret(ctx.group_info.total_filament_num, ctx.machine_info.master_extruder_id); + FilamentGroupContext new_ctx = ctx; + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + for(size_t idx = 0; idx < used_filaments.size(); ++idx) + new_ctx.model_info.unprintable_filaments[1 - filament_map_manual[used_filaments[idx]]].insert(used_filaments[idx]); - std::mapunplaceable_limits; - extract_unprintable_limit_indices(ctx.model_info.unprintable_filaments, used_filaments, unplaceable_limits); - - auto distance_evaluator = std::make_shared(ctx.model_info.flush_matrix[0], used_filaments, ctx.model_info.layer_filaments); - KMediods2 PAM((int)used_filaments.size(), distance_evaluator, ctx.machine_info.master_extruder_id); - PAM.set_max_cluster_size(ctx.machine_info.max_group_size); - PAM.set_unplaceable_limits(unplaceable_limits); - PAM.set_memory_threshold(ctx.group_info.max_gap_threshold); - PAM.do_clustering(ctx.group_info.strategy, timeout_ms); - - std::vectorfilament_labels = PAM.get_cluster_labels(); - - { - auto memoryed_groups = PAM.get_memoryed_groups(); - change_memoryed_heaps_to_arrays(memoryed_groups, ctx.group_info.total_filament_num, used_filaments, m_memoryed_groups); - } - - if (cost) - *cost = reorder_filaments_for_minimum_flush_volume(used_filaments, filament_labels, ctx.model_info.layer_filaments, ctx.model_info.flush_matrix, std::nullopt, nullptr); - - for (int i = 0; i < filament_labels.size(); ++i) - filament_labels_ret[used_filaments[i]] = filament_labels[i]; - return filament_labels_ret; + new_ctx.machine_info.max_group_size.assign(new_ctx.machine_info.max_group_size.size(), std::numeric_limits::max()); + FilamentGroup fg(new_ctx); + return fg.calc_filament_group_for_flush(); } + } diff --git a/src/libslic3r/FilamentGroup.hpp b/src/libslic3r/FilamentGroup.hpp index ce1aedfbb4..9172685bee 100644 --- a/src/libslic3r/FilamentGroup.hpp +++ b/src/libslic3r/FilamentGroup.hpp @@ -13,7 +13,8 @@ const static int DEFAULT_CLUSTER_SIZE = 16; -const static int ABSOLUTE_FLUSH_GAP_TOLERANCE = 5; +const static int ABSOLUTE_FLUSH_GAP_TOLERANCE = 10; + namespace Slic3r { @@ -52,12 +53,12 @@ namespace Slic3r struct MemoryedGroup { MemoryedGroup() = default; - MemoryedGroup(const std::vector& group_, const int cost_, const int prefer_level_) :group(group_), cost(cost_), prefer_level(prefer_level_) {} + MemoryedGroup(const std::vector& group_, const double cost_, const int prefer_level_) :group(group_), cost(cost_), prefer_level(prefer_level_) {} bool operator>(const MemoryedGroup& other) const { return prefer_level < other.prefer_level || (prefer_level == other.prefer_level && cost > other.cost); } - int cost{ 0 }; + double cost{ 0 }; int prefer_level{ 0 }; std::vectorgroup; }; @@ -75,6 +76,7 @@ namespace Slic3r std::vector filament_info; std::vector filament_ids; std::vector> unprintable_filaments; + std::map> unprintable_volumes; } model_info; struct GroupInfo { @@ -82,40 +84,74 @@ namespace Slic3r double max_gap_threshold; FGMode mode; FGStrategy strategy; - bool ignore_ext_filament; //wai gua filament + bool ignore_ext_filament; + bool has_filament_switcher = false; + std::vector filament_volume_map; } group_info; struct MachineInfo { std::vector max_group_size; std::vector> machine_filament_info; - std::vector, int>> extruder_group_size; + std::vector prefer_non_model_filament; int master_extruder_id; } machine_info; + + struct SpeedInfo{ + std::unordered_map> filament_print_time; + double extruder_change_time; + double filament_change_time; + bool group_with_time; + MultiNozzleUtils::FilamentChangeTimeParams change_time_params; + std::vector ams_preload_enabled; + } speed_info; + + struct NozzleInfo { + std::map> extruder_nozzle_list; + std::vector nozzle_list; + std::unordered_map nozzle_status; + } nozzle_info; }; - std::vector select_best_group_for_ams(const std::vector>& map_lists, + std::vector select_best_group_for_ams(const std::vector> &filament_to_nozzles, + const std::vector& nozzle_list, const std::vector& used_filaments, const std::vector& used_filament_info, const std::vector>& machine_filament_info, + const bool has_filament_switcher = false, const double color_delta_threshold = 20); - std::vector optimize_group_for_master_extruder(const std::vector& used_filaments, const FilamentGroupContext& ctx, const std::vector& filament_map); - - bool can_swap_groups(const int extruder_id_0, const std::set& group_0, const int extruder_id_1, const std::set& group_1, const FilamentGroupContext& ctx); - - std::vector calc_filament_group_for_tpu(const std::set& tpu_filaments, const int filament_nums, const int master_extruder_id); class FlushDistanceEvaluator { public: - FlushDistanceEvaluator(const FlushMatrix& flush_matrix,const std::vector&used_filaments,const std::vector>& layer_filaments, double p = 0.65); + FlushDistanceEvaluator(const std::vector& flush_matrix,const std::vector&used_filaments,const std::vector>& layer_filaments, double p = 0.65); ~FlushDistanceEvaluator() = default; - double get_distance(int idx_a, int idx_b) const; + double get_distance(int idx_a, int idx_b, int extruder_id) const; private: - std::vector>m_distance_matrix; + std::vector>>m_distance_matrix; }; + + class TimeEvaluator + { + public: + TimeEvaluator(const FilamentGroupContext::SpeedInfo& speed_info) : m_speed_info(speed_info) {} + double get_estimated_time(const std::vector& filament_map) const; + private: + FilamentGroupContext::SpeedInfo m_speed_info; + }; + + // Search budget for the k-medoids clustering, an anytime search. Each restart is seeded from its + // own index, so what it returns depends on how many restarts complete before the clock expires, + // and therefore on the speed of the machine. A timeout_ms <= 0 removes the clock and bounds the + // search by max_restarts alone. + struct ClusteringBudget + { + int timeout_ms = 3000; + int max_restarts = 30; + }; + class FilamentGroup { using MemoryedGroup = FilamentGroupUtils::MemoryedGroup; @@ -123,17 +159,25 @@ namespace Slic3r public: explicit FilamentGroup(const FilamentGroupContext& ctx_) :ctx(ctx_) {} public: + void set_clustering_budget(const ClusteringBudget& budget) { m_clustering_budget = budget; } + std::vector calc_filament_group(int * cost = nullptr); std::vector> get_memoryed_groups()const { return m_memoryed_groups; } public: std::vector calc_filament_group_for_match(int* cost = nullptr); std::vector calc_filament_group_for_flush(int* cost = nullptr); - + std::vector calc_filament_group_for_tpu(int* cost = nullptr); private: std::vector calc_min_flush_group(int* cost = nullptr); - std::vector calc_min_flush_group_by_enum(const std::vector& used_filaments, int* cost = nullptr); - std::vector calc_min_flush_group_by_pam2(const std::vector& used_filaments, int* cost = nullptr, int timeout_ms = 300); + + std::vector calc_group_by_enum(int k, const std::vector& used_filaments, + const std::unordered_map>& unplaceable_limits, int* cost = nullptr); + std::vector calc_group_by_kmedoids(int k, const std::vector& used_filaments, + const std::unordered_map>& unplaceable_limits, int* cost = nullptr); + + std::map rebuild_unprintables(const std::vector& used_filaments, const std::map& extruder_unprintables); + std::unordered_map> rebuild_nozzle_unprintables(const std::vector& used_filaments, const std::unordered_map>& extruder_unprintables, const std::vector& filament_volume_map); std::unordered_map> try_merge_filaments(); void rebuild_context(const std::unordered_map>& merged_filaments); @@ -141,57 +185,79 @@ namespace Slic3r private: FilamentGroupContext ctx; + MemoryedGroupHeap m_memoryed_heap; std::vector> m_memoryed_groups; - + ClusteringBudget m_clustering_budget; public: std::optional&)>> get_custom_seq; }; - class KMediods2 + std::vector calc_filament_group_for_manual_multi_nozzle(const std::vector& filament_map_manual,const FilamentGroupContext& ctx); + + std::vector calc_filament_group_for_match_multi_nozzle(const FilamentGroupContext& ctx); + + struct FilamentPlanRes { + std::vector fil_order; + std::vector fil_nozzle_match; + }; + + std::vector plan_filament_nozzle_mapping_and_order(const FilamentGroupContext& ctx); + + + class KMediods + { + protected: using MemoryedGroupHeap = FilamentGroupUtils::MemoryedGroupHeap; using MemoryedGroup = FilamentGroupUtils::MemoryedGroup; - - enum INIT_TYPE - { - Random = 0, - Farthest - }; public: - KMediods2(const int elem_count, const std::shared_ptr& evaluator, int default_group_id = 0) : - m_evaluator{ evaluator }, - m_elem_count{ elem_count }, - m_default_group_id{ default_group_id } - { - m_max_cluster_size = std::vector(m_k, DEFAULT_CLUSTER_SIZE); + KMediods(const int k, const int elem_count, const std::shared_ptr& evaluator, int default_group_id = 0) { + m_k = k; + m_evaluator = evaluator; + m_max_cluster_size = std::vector(k, DEFAULT_CLUSTER_SIZE); + m_elem_count = elem_count; + m_default_group_id = default_group_id; } - // set max group size void set_max_cluster_size(const std::vector& group_size) { m_max_cluster_size = group_size; } - // key stores elem idx, value stores the cluster id that elem cnanot be placed - void set_unplaceable_limits(const std::map& placeable_limits) { m_unplaceable_limits = placeable_limits; } + void set_cluster_group_size(const std::vector,int>>& cluster_group_size); - void do_clustering(const FGStrategy& g_strategy,int timeout_ms = 100); + // key stores elem, value stores the cluster id that the elem must be placed + void set_placable_limits(const std::unordered_map>& placable_limits) { m_placeable_limits = placable_limits; } + + // key stores elem, value stores the cluster id that the elem cannot be placed + void set_unplacable_limits(const std::unordered_map>& unplacable_limits) { m_unplaceable_limits = unplacable_limits; } void set_memory_threshold(double threshold) { memory_threshold = threshold; } MemoryedGroupHeap get_memoryed_groups()const { return memoryed_groups; } - std::vectorget_cluster_labels()const { return m_cluster_labels; } + void do_clustering(const FilamentGroupContext& context, const ClusteringBudget& budget); + std::vector get_cluster_labels()const { return m_cluster_labels; } - private: - std::vectorcluster_small_data(const std::map& unplaceable_limits, const std::vector& group_size); - std::vectorassign_cluster_label(const std::vector& center, const std::map& unplaceable_limits, const std::vector& group_size, const FGStrategy& strategy); - int calc_cost(const std::vector& labels, const std::vector& medoids); protected: - FilamentGroupUtils::MemoryedGroupHeap memoryed_groups; - std::shared_ptr m_evaluator; - std::mapm_unplaceable_limits; - std::vectorm_cluster_labels; - std::vectorm_max_cluster_size; + bool have_enough_size(const std::vector& cluster_size, const std::vector, int>>& cluster_group_size,int elem_count); + // calculate cluster distance + int calc_cost(const std::vector& clusters, const std::vector& cluster_centers, int cluster_id = -1); - const int m_k = 2; + // get initial cluster center + std::vectorinit_cluster_center(const std::unordered_map>& placeable_limits, const std::unordered_map>& unplaceable_limits, const std::vector& cluster_size, const std::vector, int>>& cluster_group_size, int seed); + // assign each elem to the cluster + std::vector assign_cluster_label(const std::vector& center, const std::unordered_map>& placeable_limits, const std::unordered_map>& unplaceable_limits, const std::vector& group_size, const std::vector, int>>& cluster_group_size); + + protected: + MemoryedGroupHeap memoryed_groups; + std::shared_ptrm_evaluator; + std::unordered_map> m_unplaceable_limits; // key: filament, value: nozzle ids it cannot be assigned to + std::unordered_map> m_placeable_limits; // key: filament, value: nozzle ids it must be assigned to + std::vectorm_max_cluster_size; // max number of filaments each nozzle can hold + std::vectorm_cluster_labels; // assignment result, resolved down to nozzle id + std::vector,int>> m_cluster_group_size; + std::vector m_nozzle_to_extruder; + + + int m_k; int m_elem_count; int m_default_group_id{ 0 }; double memory_threshold{ 0 }; diff --git a/src/libslic3r/FilamentGroupUtils.cpp b/src/libslic3r/FilamentGroupUtils.cpp index 1b16a1337f..c0cd747025 100644 --- a/src/libslic3r/FilamentGroupUtils.cpp +++ b/src/libslic3r/FilamentGroupUtils.cpp @@ -274,5 +274,70 @@ namespace FilamentGroupUtils } return true; } + + int get_estimate_extruder_change_count(const std::vector> &layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info) + { + int ret = 0; + for (size_t layer_id = 0; layer_id < layer_filaments.size(); ++layer_id) { + int extruder_count = extruder_nozzle_info.get_used_extruders(layer_id).size(); + ret += (extruder_count - 1); + } + return ret; + } + + int get_estimate_nozzle_change_count(const std::vector> &layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info) + { + int ret = 0; + for (size_t layer_id = 0; layer_id < layer_filaments.size(); ++layer_id) { + auto extruder_list = extruder_nozzle_info.get_used_extruders(layer_id); + for (auto extruder_id : extruder_list) { + int nozzle_count = extruder_nozzle_info.get_used_nozzles_in_extruder(extruder_id, layer_id).size(); + if (nozzle_count > 1) ret += (nozzle_count - 1); + } + } + return ret; + } + + std::pair get_estimate_extruder_filament_change_count(const MultiNozzleUtils::LayeredNozzleGroupResult &extruder_nozzle_info) + { + std::pair ret{0,0}; + int layer_nums = extruder_nozzle_info.get_layer_filament_sequences().size(); + for (int layer_id = 0; layer_id < layer_nums; layer_id++) { + std::vector extruders = extruder_nozzle_info.get_used_extruders(layer_id); + ret.first = extruders.size() - 1; + + for (auto ext_id : extruders) { + int nozzles = extruder_nozzle_info.get_used_nozzles_in_extruder(ext_id, layer_id).size(); + ret.second += nozzles; + } + ret.second = std::max(0, ret.second - ret.first); + } + return ret; + } + + std::map> build_extruder_nozzle_list(const std::vector& nozzle_list) + { + std::map> ret; + for (auto& nozzle : nozzle_list) { + ret[nozzle.extruder_id].emplace_back(nozzle.group_id); + } + + for (auto& elem : ret) + std::sort(elem.second.begin(), elem.second.end()); + return ret; + } + + std::vector update_used_filament_values(const std::vector& old_values, const std::vector& new_values, const std::vector& used_filaments) + { + std::vector res = old_values; + for (size_t i = 0; i < used_filaments.size(); ++i) { + // Orca: guard against filament ids beyond the map sizes (possible with + // mis-normalized per-filament arrays from CLI inputs); skip instead of UB. + if (used_filaments[i] >= res.size() || used_filaments[i] >= new_values.size()) + continue; + res[used_filaments[i]] = new_values[used_filaments[i]]; + } + return res; + } } } \ No newline at end of file diff --git a/src/libslic3r/FilamentGroupUtils.hpp b/src/libslic3r/FilamentGroupUtils.hpp index 71839c2be6..f0865a93c6 100644 --- a/src/libslic3r/FilamentGroupUtils.hpp +++ b/src/libslic3r/FilamentGroupUtils.hpp @@ -7,6 +7,7 @@ #include #include "PrintConfig.hpp" +#include "MultiNozzleUtils.hpp" namespace Slic3r { @@ -31,6 +32,10 @@ namespace Slic3r Color color; std::string type; bool is_support; + // How this filament is used across the model. Orca's shipping grouping + // algorithm does not read it yet; defaulted so a default-built FilamentInfo + // is deterministic. The nozzle-centric engine consumes it later. + FilamentUsageType usage_type = FilamentUsageType::ModelOnly; }; struct MachineFilamentInfo: public FilamentInfo { @@ -80,6 +85,20 @@ namespace Slic3r void extract_unprintable_limit_indices(const std::vector>& unprintable_elems, const std::vector& used_filaments, std::unordered_map>& unplaceable_limits); bool check_printable(const std::vector>& groups, const std::map& unprintable); + + // Nozzle-centric grouping helpers. The estimate helpers read a LayeredNozzleGroupResult's + // per-layer extruder/nozzle usage; the two builders support building the grouping context + // (extruder->nozzle inventory) and writing back a resolved map onto only the used-filament + // slots. + int get_estimate_extruder_change_count(const std::vector>& layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult& extruder_nozzle_info); + + int get_estimate_nozzle_change_count(const std::vector>& layer_filaments, const MultiNozzleUtils::LayeredNozzleGroupResult& extruder_nozzle_info); + + std::pair get_estimate_extruder_filament_change_count(const MultiNozzleUtils::LayeredNozzleGroupResult& extruder_nozzle_info); + + std::map> build_extruder_nozzle_list(const std::vector& nozzle_list); + + std::vector update_used_filament_values(const std::vector& old_values, const std::vector& new_values, const std::vector& used_filaments); } diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index bdb21124d4..063481876f 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -272,6 +272,12 @@ struct SurfaceFillParams // For Gyroid: when true, use the parameterized "optimized" wave. bool gyroid_optimized = false; + CenterOfSurfacePattern center_of_surface_pattern{CenterOfSurfacePattern::Each_Surface}; + bool separated_infills{false}; + + // Orca: forced print order of surface fill loops/fragments for center-based patterns. + SurfaceFillOrder fill_order = SurfaceFillOrder::Default; + bool operator<(const SurfaceFillParams &rhs) const { #define RETURN_COMPARE_NON_EQUAL(KEY) if (this->KEY < rhs.KEY) return true; if (this->KEY > rhs.KEY) return false; #define RETURN_COMPARE_NON_EQUAL_TYPED(TYPE, KEY) if (TYPE(this->KEY) < TYPE(rhs.KEY)) return true; if (TYPE(this->KEY) > TYPE(rhs.KEY)) return false; @@ -301,8 +307,12 @@ struct SurfaceFillParams RETURN_COMPARE_NON_EQUAL(lateral_lattice_angle_2); RETURN_COMPARE_NON_EQUAL(symmetric_infill_y_axis); RETURN_COMPARE_NON_EQUAL(infill_lock_depth); - RETURN_COMPARE_NON_EQUAL(skin_infill_depth); RETURN_COMPARE_NON_EQUAL(infill_overhang_angle); + RETURN_COMPARE_NON_EQUAL(skin_infill_depth); + RETURN_COMPARE_NON_EQUAL(infill_overhang_angle); RETURN_COMPARE_NON_EQUAL(gyroid_optimized); + RETURN_COMPARE_NON_EQUAL(center_of_surface_pattern); + RETURN_COMPARE_NON_EQUAL(separated_infills); + RETURN_COMPARE_NON_EQUAL_TYPED(unsigned, fill_order); return false; } @@ -329,7 +339,10 @@ struct SurfaceFillParams this->infill_lock_depth == rhs.infill_lock_depth && this->skin_infill_depth == rhs.skin_infill_depth && this->infill_overhang_angle == rhs.infill_overhang_angle && - this->gyroid_optimized == rhs.gyroid_optimized; + this->center_of_surface_pattern == rhs.center_of_surface_pattern && + this->separated_infills == rhs.separated_infills && + this->gyroid_optimized == rhs.gyroid_optimized && + this->fill_order == rhs.fill_order; } }; @@ -868,6 +881,8 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.lateral_lattice_angle_1 = region_config.lateral_lattice_angle_1; params.lateral_lattice_angle_2 = region_config.lateral_lattice_angle_2; params.infill_overhang_angle = region_config.infill_overhang_angle; + params.center_of_surface_pattern = region_config.center_of_surface_pattern; + params.separated_infills = region_config.separated_infills; if (params.pattern == ipLockedZag) { params.infill_lock_depth = scale_(region_config.infill_lock_depth); params.skin_infill_depth = scale_(region_config.skin_infill_depth); @@ -922,6 +937,14 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.extruder = region_config.bottom_surface_filament_id; else if (params.extrusion_role == erSolidInfill) params.extruder = region_config.internal_solid_filament_id; + // Orca: forced fill order applies only to top/bottom surfaces filled with a + // center-based pattern; everything else stays at Default to keep batching together. + if (params.pattern == ipConcentric || params.pattern == ipArchimedeanChords || params.pattern == ipOctagramSpiral) { + if (params.extrusion_role == erTopSolidInfill) + params.fill_order = region_config.top_surface_fill_order.value; + else if (params.extrusion_role == erBottomSurface) + params.fill_order = region_config.bottom_surface_fill_order.value; + } // Orca: apply fill multiline only for sparse infill params.multiline = params.extrusion_role == erInternalInfill ? int(region_config.fill_multiline) : 1; @@ -1308,6 +1331,22 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: auto ®ion_config = layerm->region().config(); params.config = ®ion_config; params.pattern = surface_fill.params.pattern; + params.fill_order = surface_fill.params.fill_order; + + // Orca: Checking the filling of a centered surface by drawing for each model parts + bool is_top_or_bottom = params.extrusion_role == erTopSolidInfill || params.extrusion_role == erBottomSurface; + bool is_centered_infill = surface_fill.params.pattern == ipArchimedeanChords || surface_fill.params.pattern == ipOctagramSpiral; + if (is_top_or_bottom) { + params.center_of_surface_pattern = surface_fill.params.center_of_surface_pattern; // Orca: center of surface pattern + } + // Orca: Each_Model centers the pattern on each model part's bbox; Each_Surface / Each_Assembly + // fall through to the default (whole-object) bounding box below. + bool is_per_model_center = is_top_or_bottom && params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Model && is_centered_infill; + bool is_separate_infill = !is_top_or_bottom && surface_fill.params.separated_infills && + ( + is_separable_infill_pattern(surface_fill.params.pattern) || + params.config->solid_infill_rotate_template != "" || + params.config->sparse_infill_rotate_template != "" ); if( surface_fill.params.pattern == ipLockedZag ) { params.locked_zag = true; @@ -1332,7 +1371,36 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive: params.can_reverse = false; for (ExPolygon& expoly : surface_fill.expolygons) { - f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); + // Orca: separate infill / per-model pattern centering. + // + // Center the pattern on each connected body of the object independently, so every piece + // is filled exactly as if it were sliced on its own: touching/overlapping parts merge + // into one body sharing a center, while separate parts and disconnected islands (even + // interleaved-but-not-touching ones, e.g. chain links) each get their own. The body each + // island belongs to, and its full bounding box, were resolved in 3D by PrintObject:: + // infill() (lslices_separated_component_bboxes, aligned with this layer's lslices). We + // match this fill region to the island it overlaps most, then re-use the whole-object + // bounding box (origin-centered — identical extent to the default, so coverage and cost + // are unchanged) re-centered on that body. + if (is_per_model_center || is_separate_infill) { + double best_overlap = 0.; + BoundingBox best_component; + for (size_t r = 0; r < this->lslices.size() && r < this->lslices_separated_component_bboxes.size(); ++ r) { + const double overlap = area(intersection_ex(this->lslices[r], expoly)); + if (overlap > best_overlap) { + best_overlap = overlap; + best_component = this->lslices_separated_component_bboxes[r]; + } + } + if (best_component.defined) { + const Point c = best_component.center(); + BoundingBox part_bbox = bbox; // origin-centered, whole-object extent (from above) + part_bbox.translate(c.x(), c.y()); // re-center on this body + f->set_bounding_box(part_bbox); + } + } // - End: separate infill / per-model pattern centering + + f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes); if (params.symmetric_infill_y_axis) { params.symmetric_y_axis = f->extended_object_bounding_box().center().x(); expoly.symmetric_y(params.symmetric_y_axis); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 1d15614ccb..2606529099 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -165,7 +165,11 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para // ORCA: special flag for flow rate calibration auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_flowrate_topinfill_special_order") && this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool(); - if (is_flow_calib) { + // Orca: a forced surface fill order must survive the G-code path planner, which would + // otherwise re-chain and possibly reverse the paths. The same applies to the flow rate + // calibration's special toolpath order. + const bool keep_fill_order = params.fill_order != SurfaceFillOrder::Default; + if (is_flow_calib || keep_fill_order) { eec->no_sort = true; } size_t idx = eec->entities.size(); @@ -180,7 +184,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para params.extrusion_role, flow_mm3_per_mm, float(flow_width), params.flow.height()); } - if (!params.can_reverse || is_flow_calib) { + if (!params.can_reverse || is_flow_calib || keep_fill_order) { for (size_t i = idx; i < eec->entities.size(); i++) eec->entities[i]->set_reverse(); } diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp index ef6a6bc804..8128b9c9d1 100644 --- a/src/libslic3r/Fill/FillBase.hpp +++ b/src/libslic3r/Fill/FillBase.hpp @@ -100,12 +100,17 @@ struct FillParams bool dont_sort{ false }; // do not sort the lines, just simply connect them bool can_reverse{true}; + // Orca: forced print order of surface fill loops/fragments for center-based patterns + // (Concentric, Archimedean Chords, Octagram Spiral). Default keeps shortest-path ordering. + SurfaceFillOrder fill_order { SurfaceFillOrder::Default }; + float horiz_move{0.0}; //move infill to get cross zag pattern bool symmetric_infill_y_axis{false}; coord_t symmetric_y_axis{0}; bool locked_zag{false}; float infill_lock_depth{0.0}; float skin_infill_depth{0.0}; + CenterOfSurfacePattern center_of_surface_pattern{CenterOfSurfacePattern::Each_Surface}; }; static_assert(IsTriviallyCopyable::value, "FillParams class is not POD (and it should be - see constructor)."); diff --git a/src/libslic3r/Fill/FillConcentric.cpp b/src/libslic3r/Fill/FillConcentric.cpp index 4f2a0b8970..a75d2ed7d3 100644 --- a/src/libslic3r/Fill/FillConcentric.cpp +++ b/src/libslic3r/Fill/FillConcentric.cpp @@ -41,6 +41,10 @@ void FillConcentric::_fill_surface_single( // generate paths from the outermost to the innermost, to avoid // adhesion problems of the first central tiny loops loops = union_pt_chained_outside_in(loops); + + // Orca: an outward fill order prints the innermost loops first instead. + if (params.fill_order == SurfaceFillOrder::Outward) + std::reverse(loops.begin(), loops.end()); // split paths using a nearest neighbor search size_t iPathFirst = polylines_out.size(); @@ -108,6 +112,17 @@ void FillConcentric::_fill_surface_single(const FillParams& params, all_extrusions.emplace_back(&wall); } + // Orca: a forced fill order prints the loops in strictly monotonic depth order so + // that surfaces broken up by holes or slots cannot hop outward and back inward. + const bool forced_fill_order = params.fill_order != SurfaceFillOrder::Default; + if (forced_fill_order) { + const bool outward = params.fill_order == SurfaceFillOrder::Outward; + std::stable_sort(all_extrusions.begin(), all_extrusions.end(), + [outward](const Arachne::ExtrusionLine *a, const Arachne::ExtrusionLine *b) { + return outward ? a->inset_idx > b->inset_idx : a->inset_idx < b->inset_idx; + }); + } + // Split paths using a nearest neighbor search. size_t firts_poly_idx = thick_polylines_out.size(); Point last_pos(0, 0); @@ -136,7 +151,8 @@ void FillConcentric::_fill_surface_single(const FillParams& params, if (j < thick_polylines_out.size()) thick_polylines_out.erase(thick_polylines_out.begin() + int(j), thick_polylines_out.end()); - reorder_by_shortest_traverse(thick_polylines_out); + if (!forced_fill_order) + reorder_by_shortest_traverse(thick_polylines_out); } else { Polylines polylines; diff --git a/src/libslic3r/Fill/FillPlanePath.cpp b/src/libslic3r/Fill/FillPlanePath.cpp index b4681d05f9..7ce8e4abb3 100644 --- a/src/libslic3r/Fill/FillPlanePath.cpp +++ b/src/libslic3r/Fill/FillPlanePath.cpp @@ -77,20 +77,24 @@ void FillPlanePath::_fill_surface_single( //FIXME Vojtech: We are not sure whether the user expects the fill patterns on visible surfaces to be aligned across all the islands of a single layer. // One may align for this->centered() to align the patterns for Archimedean Chords and Octagram Spiral patterns. - const bool align = params.density < 0.995; - + // Orca: the old implementation became obsolete when it became possible to change the density of the top and bottom surfaces + bool align = params.extrusion_role == ExtrusionRole::erInternalInfill; + BoundingBox bounding_box; BoundingBox snug_bounding_box = get_extents(expolygon).inflated(SCALED_EPSILON); // Expand the bounding box to avoid artifacts at the edges - snug_bounding_box.offset(scale_(this->spacing)*params.multiline); + snug_bounding_box.offset(scale_(this->spacing)*params.multiline); - // Rotated bounding box of the area to fill in with the pattern. - BoundingBox bounding_box = align ? - // Sparse infill needs to be aligned across layers. Align infill across layers using the object's bounding box. - this->bounding_box.rotated(-direction.first) : - // Solid infill does not need to be aligned across layers, generate the infill pattern - // around the clipping expolygon only. - snug_bounding_box; + // Sparse infill (or Internal where align == true) needs to be aligned across layers. Align infill across layers using the object's bounding box. + // Solid infill does not need to be aligned across layers, generate the infill pattern around the clipping expolygon only. + if (align) + bounding_box = this->bounding_box.rotated(-direction.first); + else if (params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Surface) + bounding_box = snug_bounding_box; + else if (params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Model) + bounding_box = this->bounding_box.rotated(-direction.first); + else + bounding_box = extended_object_bounding_box(); Point shift = this->centered() ? bounding_box.center() : @@ -130,8 +134,12 @@ void FillPlanePath::_fill_surface_single( if (!polylines.empty()) { Polylines chained; if (params.dont_connect() || params.density > 0.5) { - // ORCA: special flag for flow rate calibration - auto is_flow_calib = params.extrusion_role == erTopSolidInfill && + // ORCA: special flag for flow rate calibration. The chords chained ahead of the + // inside-out center spiral collide with it in opposing directions, raising a + // tactile lip that the calibration reads. Only applies while the fill order is + // Default, so it can be overridden from the calibration objects. + auto is_flow_calib = params.fill_order == SurfaceFillOrder::Default && + params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_flowrate_topinfill_special_order") && this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() && dynamic_cast(this); @@ -149,12 +157,26 @@ void FillPlanePath::_fill_surface_single( // Chain the other polylines polylines.erase(it); - chained = chain_polylines(std::move(polylines)); + chained = chain_polylines(std::move(polylines), nullptr); // Then add the center spiral back chained.push_back(std::move(center_spiral)); + } else if (params.fill_order != SurfaceFillOrder::Default) { + // Orca: print the fragments in the order they appear along the generated + // path, which runs from the center outwards. The Euclidean distance from + // the center cannot be used for this: along the Octagram Spiral the radius + // oscillates by far more than the ring spacing, so fragments of different + // rings would interleave. + restore_source_path_order(polyline, polylines); + chained = std::move(polylines); + if (params.fill_order == SurfaceFillOrder::Inward) { + // The source path runs from the center outwards; flip everything for inward. + std::reverse(chained.begin(), chained.end()); + for (Polyline &pl : chained) + pl.reverse(); + } } else { - chained = chain_polylines(std::move(polylines)); + chained = chain_polylines(std::move(polylines), nullptr); } } else connect_infill(std::move(polylines), expolygon, chained, this->spacing, params); diff --git a/src/libslic3r/Fill/FillRectilinear.cpp b/src/libslic3r/Fill/FillRectilinear.cpp index 5638dea869..138b50bc88 100644 --- a/src/libslic3r/Fill/FillRectilinear.cpp +++ b/src/libslic3r/Fill/FillRectilinear.cpp @@ -2739,13 +2739,19 @@ static void polylines_from_paths(const std::vector &path, c // The extended bounding box of the whole object that covers any rotation of every layer. BoundingBox FillRectilinear::extended_object_bounding_box() const { + // Build the extension around the box center. The transpose merge and the sqrt(2.) scaling + // (which covers any possible rotation) are both defined about the origin, so a box that is not + // origin-centered — e.g. a separated-infill box re-centered on a single assembly part — would be + // distorted. Shift to the origin first and back afterwards; for the default origin-centered box + // the two translations cancel and this is identical to the original behavior. + const Point c = this->bounding_box.center(); BoundingBox out = this->bounding_box; + out.translate(-c.x(), -c.y()); out.merge(Point(out.min.y(), out.min.x())); out.merge(Point(out.max.y(), out.max.x())); - - // The bounding box is scaled by sqrt(2.) to ensure that the bounding box - // covers any possible rotations. - return out.scaled(sqrt(2.)); + out = out.scaled(sqrt(2.)); + out.translate(c.x(), c.y()); + return out; } bool FillRectilinear::fill_surface_by_lines(const Surface *surface, const FillParams ¶ms, float angleBase, float pattern_shift, Polylines &polylines_out) @@ -3098,8 +3104,11 @@ bool FillRectilinear::fill_surface_trapezoidal( const coord_t d2 = coord_t(0.5 * period - d1); - // Align bounding box to the grid - bb.merge(align_to_grid(bb.min, Point(period, period))); + // Align bounding box to the grid, phased through the box center so separated infills align + // each part on itself (grid_center is the origin for a standalone object / feature off). + // Captured before the merge, which grows bb and would otherwise shift its center. + const Point grid_center = bb.center(); + bb.merge(align_to_grid(bb.min, Point(period, period), grid_center)); const coord_t xmin = bb.min.x(); const coord_t xmax = bb.max.x(); const coord_t ymin = bb.min.y(); @@ -3146,11 +3155,17 @@ bool FillRectilinear::fill_surface_trapezoidal( flip_vertical = !flip_vertical; } - // transpose points for odd infill layers (taking infill combination into account) + // transpose points for odd infill layers (taking infill combination into account). + // Orca: mirror across the diagonal through grid_center (not the origin), so the swapped + // layers stay aligned with the center-phased grid. For a standalone object / feature off, + // grid_center is the origin and this is a plain x/y swap. if (infill_layer_id % 2 == 1) { for (Polyline& pl : polylines) { for (Point& p : pl.points) { - std::swap(p.x(), p.y()); + const coord_t dx = p.x() - grid_center.x(); + const coord_t dy = p.y() - grid_center.y(); + p.x() = grid_center.x() + dy; + p.y() = grid_center.y() + dx; } } } @@ -3341,6 +3356,14 @@ bool FillRectilinear::fill_surface_trapezoidal( break; } + // Orca: cases 1 & 2 build the pattern symmetrically around the origin, so on their own they + // phase to the global origin and every part shares one grid. Shift the pattern onto the box + // center this->bounding_box carries, so separated infills align each part on itself. The center + // is the origin for a standalone object (or when the feature is off), making this a no-op there. + if (Pattern_type != 0) + for (Polyline &pl : polylines) + pl.translate(rotate_vector.second); + // Apply multiline fill multiline_fill(polylines, params, spacing); diff --git a/src/libslic3r/Format/bbs_3mf.cpp b/src/libslic3r/Format/bbs_3mf.cpp index 31519e4fbe..3000adb441 100644 --- a/src/libslic3r/Format/bbs_3mf.cpp +++ b/src/libslic3r/Format/bbs_3mf.cpp @@ -347,6 +347,7 @@ static constexpr const char* OTHER_LAYERS_PRINT_SEQUENCE_NUMS_ATTR = "other_laye static constexpr const char* SPIRAL_VASE_MODE = "spiral_mode"; static constexpr const char* FILAMENT_MAP_MODE_ATTR = "filament_map_mode"; static constexpr const char* FILAMENT_MAP_ATTR = "filament_maps"; +static constexpr const char* FILAMENT_VOL_MAP_ATTR = "filament_volume_maps"; static constexpr const char* LIMIT_FILAMENT_MAP_ATTR = "limit_filament_maps"; static constexpr const char* GCODE_FILE_ATTR = "gcode_file"; static constexpr const char* THUMBNAIL_FILE_ATTR = "thumbnail_file"; @@ -699,6 +700,35 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) info.id = it->first; info.used_g = used_filament_g; info.used_m = used_filament_m; + + // Stamp each filament's logical-nozzle assignment onto the saved 3mf so the device/monitor can + // reconstruct it. This block runs for every print: reorder_extruders_for_minimum_flush_volume + // runs unconditionally and stores a (non-null) 1-nozzle result even for a single-extruder print, + // so result->nozzle_group_result is non-null here for single-nozzle printers too. The stamped + // nozzle_diameter is the grouping result's rounded matching-key value; the 3mf writer decides the + // final saved diameter (see has_multi_nozzle_extruder). group_id and volume_type are unaffected. + if (result && result->nozzle_group_result) { + auto nozzles_for_filament = result->nozzle_group_result->get_nozzles_for_filament(it->first); + if (!nozzles_for_filament.empty()) { + info.group_id.reserve(nozzles_for_filament.size()); + std::set diameters; + std::set volume_types; + for (const auto& nozzle : nozzles_for_filament) { + info.group_id.emplace_back(nozzle.group_id); + diameters.insert(string_to_double_decimal_point(nozzle.diameter)); + volume_types.insert(nozzle.volume_type); + } + std::sort(info.group_id.begin(), info.group_id.end()); + info.group_id.erase(std::unique(info.group_id.begin(), info.group_id.end()), info.group_id.end()); + if (!diameters.empty()) + info.nozzle_diameter = *diameters.begin(); + if (volume_types.size() > 1) + info.nozzle_volume_type = get_nozzle_volume_type_string(nvtHybrid); + else if (!volume_types.empty()) + info.nozzle_volume_type = get_nozzle_volume_type_string(*volume_types.begin()); + } + } + auto model_volume_it = ps.model_volumes_per_extruder.find(it->first); auto support_volume_it = ps.support_volumes_per_extruder.find(it->first); info.used_for_object = model_volume_it != ps.model_volumes_per_extruder.end() && model_volume_it->second > EPSILON; @@ -706,6 +736,13 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) slice_filaments_info.push_back(info); } + // Carry the layer-aware grouping result into the plate so the 3mf writer can emit the tags + // and the enable_filament_dynamic_map flag. Only a LayeredNozzleGroupResult (the slicer output) is + // stored; a device-side StaticNozzleGroupResult loaded from a 3mf is not re-serialized here. + auto layered_group_result = std::dynamic_pointer_cast(result->nozzle_group_result); + if (layered_group_result) + nozzle_group_result = *layered_group_result; + /* only for test GCodeProcessorResult::SliceWarning sw; sw.msg = BED_TEMP_TOO_HIGH_THAN_FILAMENT; @@ -1283,6 +1320,9 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) bool _handle_start_config_warning(const char** attributes, unsigned int num_attributes); bool _handle_end_config_warning(); + bool _handle_start_config_nozzle(const char** attributes, unsigned int num_attributes); + bool _handle_end_config_nozzle(); + //BBS: add plater config parse functions bool _handle_start_config_plater(const char** attributes, unsigned int num_attributes); bool _handle_end_config_plater(); @@ -1618,8 +1658,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) plate->is_label_object_enabled = it->second->is_label_object_enabled; plate->skipped_objects = it->second->skipped_objects; plate->slice_filaments_info = it->second->slice_filaments_info; + plate->nozzles_info = it->second->nozzles_info; plate->printer_model_id = it->second->printer_model_id; plate->nozzle_diameters = it->second->nozzle_diameters; + plate->nozzle_volume_types = it->second->nozzle_volume_types; plate->filament_maps = it->second->filament_maps; plate->filament_change_sequence = it->second->filament_change_sequence; plate->nozzle_change_sequence = it->second->nozzle_change_sequence; @@ -2289,9 +2331,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) plate_data_list[it->first-1]->is_support_used = it->second->is_support_used; plate_data_list[it->first-1]->is_label_object_enabled = it->second->is_label_object_enabled; plate_data_list[it->first-1]->slice_filaments_info = it->second->slice_filaments_info; + plate_data_list[it->first-1]->nozzles_info = it->second->nozzles_info; plate_data_list[it->first-1]->skipped_objects = it->second->skipped_objects; plate_data_list[it->first-1]->printer_model_id = it->second->printer_model_id; plate_data_list[it->first-1]->nozzle_diameters = it->second->nozzle_diameters; + plate_data_list[it->first-1]->nozzle_volume_types = it->second->nozzle_volume_types; plate_data_list[it->first-1]->filament_maps = it->second->filament_maps; plate_data_list[it->first-1]->filament_change_sequence = it->second->filament_change_sequence; plate_data_list[it->first-1]->nozzle_change_sequence = it->second->nozzle_change_sequence; @@ -3469,6 +3513,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) res = _handle_start_config_filament(attributes, num_attributes); else if (::strcmp(SLICE_WARNING_TAG, name) == 0) res = _handle_start_config_warning(attributes, num_attributes); + else if (::strcmp(NOZZLE_TAG, name) == 0) + res = _handle_start_config_nozzle(attributes, num_attributes); else if (::strcmp(ASSEMBLE_TAG, name) == 0) res = _handle_start_assemble(attributes, num_attributes); else if (::strcmp(ASSEMBLE_ITEM_TAG, name) == 0) @@ -3503,6 +3549,8 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) res = _handle_end_config_plater(); else if (::strcmp(FILAMENT_TAG, name) == 0) res = _handle_end_config_filament(); + else if (::strcmp(NOZZLE_TAG, name) == 0) + res = _handle_end_config_nozzle(); else if (::strcmp(INSTANCE_TAG, name) == 0) res = _handle_end_config_plater_instance(); else if (::strcmp(ASSEMBLE_TAG, name) == 0) @@ -4460,6 +4508,21 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) m_curr_plater->config.set_key_value("filament_map", new ConfigOptionInts(filament_map)); } } + else if (key == FILAMENT_VOL_MAP_ATTR) { + if (m_curr_plater){ + auto filament_volume_map = get_vector_from_string(value); + for (size_t idx = 0; idx < filament_volume_map.size(); ++idx) { + // The map feeds per-filament slot resolution and grouping. Clamp any + // higher volume-type back to Standard(0) on load: Hybrid(2) is only an + // in-memory grouping seed that is never persisted, and TPU High Flow(3) + // is clamped with the same information loss on every load. + if (filament_volume_map[idx] > 1) { + filament_volume_map[idx] = 0; + } + } + m_curr_plater->config.set_key_value("filament_volume_map", new ConfigOptionInts(filament_volume_map)); + } + } else if (key == GCODE_FILE_ATTR) { m_curr_plater->gcode_file = value; @@ -4569,6 +4632,11 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (m_curr_plater) m_curr_plater->printer_model_id = value; } + else if (key == NOZZLE_VOLUME_TYPE_ATTR) + { + if (m_curr_plater) + m_curr_plater->nozzle_volume_types = value; + } else if (key == NOZZLE_DIAMETERS_ATTR) { if (m_curr_plater) @@ -4622,6 +4690,41 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) return true; } + bool _BBS_3MF_Importer::_handle_start_config_nozzle(const char** attributes, unsigned int num_attributes) + { + // Read the per-plate tags. Older 3mf without tags leave nozzles_info + // empty; load_nozzle_infos_with_compatibility then rebuilds the list from the per-filament + // group_id / filament_map on the device side. + if (m_curr_plater) { + // id="0" extruder_id="1" nozzle_diameter="0.4" volume_type="Standard" + std::string id = bbs_get_attribute_value_string(attributes, num_attributes, "id"); + std::string extruder_id = bbs_get_attribute_value_string(attributes, num_attributes, "extruder_id"); + std::string nozzle_diameter= bbs_get_attribute_value_string(attributes, num_attributes, "nozzle_diameter"); + std::string volume_type = bbs_get_attribute_value_string(attributes, num_attributes, "volume_type"); + + auto volume_type_str_to_enum = ConfigOptionEnum::get_enum_values(); + + MultiNozzleUtils::NozzleInfo nozzle_info; + nozzle_info.group_id = atoi(id.c_str()); + nozzle_info.extruder_id = atoi(extruder_id.c_str()) - 1; + nozzle_info.diameter = nozzle_diameter; + + if (volume_type_str_to_enum.count(volume_type)) + nozzle_info.volume_type = NozzleVolumeType(volume_type_str_to_enum.at(volume_type)); + else + nozzle_info.volume_type = NozzleVolumeType::nvtStandard; + + m_curr_plater->nozzles_info.push_back(nozzle_info); + } + return true; + } + + bool _BBS_3MF_Importer::_handle_end_config_nozzle() + { + // do nothing + return true; + } + bool _BBS_3MF_Importer::_handle_start_config_warning(const char** attributes, unsigned int num_attributes) { if (m_curr_plater) { @@ -5949,7 +6052,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) m_thumbnail_middle = iter->second; } boost::system::error_code ec; - std::string filename = std::string(store_params.path); + std::string filename = store_params.path; boost::filesystem::remove(filename + ".tmp", ec); bool result = _save_model_to_file(filename + ".tmp", *store_params.model, store_params.plate_data_list, store_params.project_presets, store_params.config, @@ -7980,6 +8083,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << "\"/>\n"; } + ConfigOptionInts* filament_volume_maps_opt = plate_data->config.option("filament_volume_map"); + if (filament_map_mode_opt != nullptr && filament_volume_maps_opt != nullptr) { + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << FILAMENT_VOL_MAP_ATTR << "\" " << VALUE_ATTR << "=\""; + const std::vector& volume_values = filament_volume_maps_opt->values; + for (int i = 0; i < volume_values.size(); ++i) { + stream << volume_values[i]; + if (i != (volume_values.size() - 1)) + stream << " "; + } + stream << "\"/>\n"; + } + if (save_gcode) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << GCODE_FILE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << xml_escape(plate_data->gcode_file) << "\"/>\n"; if (!plate_data->gcode_file.empty()) { @@ -8119,7 +8234,12 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) [](unsigned int filament_id) { return filament_id + 1; }); const std::string plate_key = "plate_" + std::to_string(idx + 1); - sequence_json[plate_key]["sequence"] = filament_sequence; + // Dynamic-map plates write the sequence under "filament_sequence"; every other plate (the + // whole shipping fleet + H2C static mode) keeps the "sequence" key, so the saved 3mf is + // byte-identical to the older format. The reader accepts both. + const bool enable_dynamic_map = plate_data->nozzle_group_result && plate_data->nozzle_group_result->is_support_dynamic_nozzle_map(); + const std::string seq_key = enable_dynamic_map ? "filament_sequence" : "sequence"; + sequence_json[plate_key][seq_key] = filament_sequence; sequence_json[plate_key]["nozzle_sequence"] = plate_data->nozzle_change_sequence; sequence_json[plate_key]["optimal_assignment"] = plate_data->optimal_assignment; } @@ -8205,6 +8325,18 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (nozzle_diameter_option) nozzle_diameters_str = nozzle_diameter_option->serialize(); + // True when any extruder carries a cluster of interchangeable nozzles (max nozzle count + // > 1). Such an extruder's per-nozzle diameters are not expressible in the per-extruder + // nozzle_diameter config, so the saved / diameters must come from the + // grouping result. For a single-nozzle-per-extruder printer the true diameter is the raw + // config value; the grouping result rounds it to the nearest of {0.2,0.4,0.6,0.8} for its + // internal matching key, so reading that back would rewrite a non-standard nozzle + // (e.g. 0.5 -> 0.4). Use this flag to keep the exact config value in that case. + auto* extruder_max_nozzle_count_option = dynamic_cast(config.option("extruder_max_nozzle_count")); + const bool has_multi_nozzle_extruder = extruder_max_nozzle_count_option && + std::any_of(extruder_max_nozzle_count_option->values.begin(), extruder_max_nozzle_count_option->values.end(), + [](int v) { return v > 1; }); + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << PRINTER_MODEL_ID_ATTR << "\" " << VALUE_ATTR << "=\"" << plate_data->printer_model_id << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << NOZZLE_DIAMETERS_ATTR << "\" " << VALUE_ATTR << "=\"" << nozzle_diameters_str << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << TIMELAPSE_TYPE_ATTR << "\" " << VALUE_ATTR << "=\"" << timelapse_type << "\"/>\n"; @@ -8214,7 +8346,15 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << OUTSIDE_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->toolpath_outside << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << SUPPORT_USED_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->is_support_used << "\"/>\n"; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << LABEL_OBJECT_ENABLED_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha<< plate_data->is_label_object_enabled << "\"/>\n"; - stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << ENABLE_FILAMENT_DYNAMIC_MAP_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << false << "\"/>\n"; + // Report the plate's dynamic-map state from the grouping result. The result is present + // for the whole fleet (a static single-nozzle result too), so this if-branch is normally + // taken; is_support_dynamic_nozzle_map() is false for any non-dynamic (static / + // single-extruder) result ⇒ byte-identical to the previously hard-coded value. The else + // is a defensive fallback for a missing result. + if (plate_data && plate_data->nozzle_group_result) + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << ENABLE_FILAMENT_DYNAMIC_MAP_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << plate_data->nozzle_group_result->is_support_dynamic_nozzle_map() << "\"/>\n"; + else + stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << ENABLE_FILAMENT_DYNAMIC_MAP_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << false << "\"/>\n"; { bool has_filament_switcher = config.has("has_filament_switcher") ? config.opt_bool("has_filament_switcher") : false; stream << " <" << METADATA_TAG << " " << KEY_ATTR << "=\"" << HAS_FILAMENT_SWITCHER_ATTR << "\" " << VALUE_ATTR << "=\"" << std::boolalpha << has_filament_switcher << "\"/>\n"; @@ -8329,7 +8469,10 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) if (std::find(used_nozzle_groups.begin(), used_nozzle_groups.end(), nozzle_group_id) == used_nozzle_groups.end()) used_nozzle_groups.push_back(nozzle_group_id); const std::string filament_nozzle_group_id = it->group_id.empty() ? std::to_string(nozzle_group_id) : join_int_list_comma(it->group_id); - const double filament_nozzle_diameter = it->nozzle_diameter > 0.0 ? it->nozzle_diameter : get_nozzle_diameter(nozzle_group_id); + // Single-nozzle extruders: exact config diameter; clusters keep the result's rounded + // value (see has_multi_nozzle_extruder). + const double filament_nozzle_diameter = (has_multi_nozzle_extruder && it->nozzle_diameter > 0.0) + ? it->nozzle_diameter : get_nozzle_diameter(nozzle_group_id); const std::string filament_nozzle_volume_type = it->nozzle_volume_type.empty() ? get_nozzle_volume_type(nozzle_group_id) : it->nozzle_volume_type; stream << " <" << FILAMENT_TAG << " " << FILAMENT_ID_TAG << "=\"" << std::to_string(it->id + 1) << "\" " @@ -8349,12 +8492,26 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result) stream << " <" << SLICE_WARNING_TAG << " msg=\"" << it->msg << "\" level=\"" << std::to_string(it->level) << "\" error_code =\"" << it->error_code << "\" />\n"; } - for (int nozzle_group_id : used_nozzle_groups) { - stream << " <" << NOZZLE_TAG << " " - << "id=\"" << nozzle_group_id << "\" " - << "extruder_id=\"" << nozzle_group_id + 1 << "\" " - << "nozzle_diameter=\"" << get_nozzle_diameter_str(nozzle_group_id) << "\" " - << "volume_type=\"" << get_nozzle_volume_type(nozzle_group_id) << "\"/>\n"; + // Emit the tags from the grouping result. Single-nozzle-per-extruder printers + // override the diameter with the exact config value (see has_multi_nozzle_extruder); the + // else is a defensive fallback for a missing result. + if (plate_data->nozzle_group_result) { + auto used_nozzle_list = plate_data->nozzle_group_result->get_used_nozzles_in_extruder(); + for (auto& used_nozzle : used_nozzle_list) { + if (!has_multi_nozzle_extruder && nozzle_diameter_option && + used_nozzle.extruder_id >= 0 && used_nozzle.extruder_id < (int) nozzle_diameter_option->values.size()) { + used_nozzle.diameter = get_nozzle_diameter_str(used_nozzle.extruder_id); + } + stream << " <" << NOZZLE_TAG << " " << used_nozzle.serialize() << "/>\n"; + } + } else { + for (int nozzle_group_id : used_nozzle_groups) { + stream << " <" << NOZZLE_TAG << " " + << "id=\"" << nozzle_group_id << "\" " + << "extruder_id=\"" << nozzle_group_id + 1 << "\" " + << "nozzle_diameter=\"" << get_nozzle_diameter_str(nozzle_group_id) << "\" " + << "volume_type=\"" << get_nozzle_volume_type(nozzle_group_id) << "\"/>\n"; + } } if (!plate_data->layer_filaments.empty()) { @@ -8988,7 +9145,7 @@ bool store_bbs_3mf(StoreParams& store_params) // All export should use "C" locales for number formatting. CNumericLocalesSetter locales_setter; - if (store_params.path == nullptr || store_params.model == nullptr) + if (store_params.path.empty() || store_params.model == nullptr) return false; _BBS_3MF_Exporter exporter; diff --git a/src/libslic3r/Format/bbs_3mf.hpp b/src/libslic3r/Format/bbs_3mf.hpp index df4f91f6e9..9c697a14fc 100644 --- a/src/libslic3r/Format/bbs_3mf.hpp +++ b/src/libslic3r/Format/bbs_3mf.hpp @@ -73,6 +73,7 @@ struct PlateData std::map> obj_inst_map; std::string printer_model_id; std::string nozzle_diameters; + std::string nozzle_volume_types; std::string gcode_file; std::string gcode_file_md5; std::string thumbnail_file; @@ -102,6 +103,13 @@ struct PlateData std::vector nozzle_change_sequence; std::vector optimal_assignment; + // Multi-nozzle grouping surface. nozzles_info accumulates the tags read from a + // gcode.3mf; nozzle_group_result is the slicer's per-filament→nozzle assignment carried into the + // saved 3mf metadata (write) and reconstructed on load. Both are empty/nullopt for single-nozzle + // prints, so the saved-3mf output for single-nozzle printers is byte-identical. + std::vector nozzles_info; + std::optional nozzle_group_result; + // Hexadecimal number, // the 0th digit corresponds to extruder 1 // the 1th digit corresponds to extruder 2 @@ -226,7 +234,7 @@ typedef std::map PlateDataMaps; struct StoreParams { - const char* path; + std::string path; Model* model = nullptr; PlateDataPtrs plate_data_list; int export_plate_idx = -1; diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 0b62fd0d6f..24cbec3567 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -99,11 +99,131 @@ static bool is_bambu_x2d_printer(const FullPrintConfig &config) return config.printer_model.value == "Bambu Lab X2D"; } +// Multi-nozzle printer predicate: an extruder carries a nozzle cluster (extruder_max_nozzle_count +// entry > 1). Today only H2C profiles trip it, so every existing single- and dual-extruder printer +// is excluded and keeps its historic placeholder values. +static bool is_multi_nozzle_printer(const FullPrintConfig &config) +{ + return std::any_of(config.extruder_max_nozzle_count.values.begin(), + config.extruder_max_nozzle_count.values.end(), + [](int v) { return v > 1; }); +} + static int hotend_id_for_gcode_placeholder(const FullPrintConfig &config, int hotend_id) { return is_bambu_x2d_printer(config) ? -1 : hotend_id; } +// current_hotend / next_hotend value. For multi-nozzle printers a dynamic nozzle map yields the real +// nozzle id, a static map yields -1: +// - multi-nozzle (H2C): dynamic nozzle map -> real nozzle id; static -> -1. +// The dynamic branch is dormant today: the selector create() overload that sets the flag has no +// callers yet (deferred with the nozzle-assignment pipeline), so H2C currently resolves to -1. +// - X2D: keeps its historic -1 (single-nozzle -> falls through to the fallback helper). +// - every other (existing single-nozzle) printer: keeps its historic extruder-id value, so +// existing g-code stays byte-identical. +// group_result may be null on slicing paths that don't populate it -> the dynamic branch is simply +// skipped, so we never dereference null. +static int hotend_id_for_gcode_placeholder(const FullPrintConfig &config, + const std::shared_ptr &group_result, + int filament_id, + int extruder_id, + int layer_id = -1) +{ + if (is_multi_nozzle_printer(config)) { + if (group_result && group_result->is_support_dynamic_nozzle_map() && filament_id >= 0) + return group_result->get_nozzle_id(filament_id, layer_id); + return -1; + } + return hotend_id_for_gcode_placeholder(config, extruder_id); +} + +// Logical nozzle id for the *_nozzle_id placeholders. Null-safe: falls back to the +// extruder id (single-nozzle equivalent) so existing printers are unaffected and we never crash. +static int nozzle_id_for_gcode_placeholder(const std::shared_ptr &group_result, + int filament_id, int extruder_id, int layer_id = -1) +{ + if (group_result && filament_id >= 0) + return group_result->get_nozzle_id(filament_id, layer_id); + return extruder_id; +} + +// Init variants: the start-gcode init sites (first_non_support_hotend / initial_no_support_hotend / +// current_hotend / initial_nozzle_id / filament_start current_nozzle_id) use get_first_nozzle_for_filament +// (the nozzle a filament FIRST uses) rather than the layer-based get_nozzle_id. Same hotend-value semantics +// as hotend_id_for_gcode_placeholder above (multi-nozzle static -> -1; dynamic branch dormant; +// existing printers -> extruder id; X2D -> -1); they differ from the layer-based helper only on the dormant +// dynamic path for a filament first used after layer 0. +static int first_hotend_id_for_gcode_placeholder(const FullPrintConfig &config, + const std::shared_ptr &group_result, + int filament_id, + int extruder_id) +{ + if (is_multi_nozzle_printer(config)) { + if (group_result && group_result->is_support_dynamic_nozzle_map() && filament_id >= 0) { + auto nozzle = group_result->get_first_nozzle_for_filament(filament_id); + if (nozzle) + return nozzle->group_id; + } + return -1; + } + return hotend_id_for_gcode_placeholder(config, extruder_id); +} + +static int first_nozzle_id_for_gcode_placeholder(const std::shared_ptr &group_result, + int filament_id, int extruder_id) +{ + if (group_result && filament_id >= 0) { + auto nozzle = group_result->get_first_nozzle_for_filament(filament_id); + if (nozzle) + return nozzle->group_id; + } + return extruder_id; +} + +// Nozzle diameters indexed by logical nozzle id, for the nozzle_diameter_at_nozzle_id[] +// placeholder. Empty when there is no group result. +static std::vector get_nozzle_diameters_by_nozzle_id(const MultiNozzleUtils::NozzleGroupResultBase *group_result) +{ + std::vector diameters; + if (!group_result) + return diameters; + for (int id = 0;; ++id) { + auto nozzle = group_result->get_nozzle_from_id(id); + if (!nozzle) + break; + diameters.push_back(std::stod(nozzle->diameter)); + } + return diameters; +} + +// Nozzle volume-type strings indexed by logical nozzle id, for the nozzle_volume_types[] +// placeholder. Empty when there is no group result. +static std::vector get_nozzle_volume_types_by_nozzle_id(const MultiNozzleUtils::NozzleGroupResultBase *group_result) +{ + std::vector volume_types; + if (!group_result) + return volume_types; + + int max_nozzle_id = -1; + for (unsigned int filament_id : group_result->get_used_filaments()) { + for (const auto &nozzle : group_result->get_nozzles_for_filament(filament_id)) { + if (nozzle.group_id > max_nozzle_id) + max_nozzle_id = nozzle.group_id; + } + } + if (max_nozzle_id < 0) + max_nozzle_id = 0; + + volume_types.resize(max_nozzle_id + 1, get_nozzle_volume_type_string(NozzleVolumeType::nvtStandard)); + for (int id = 0; id <= max_nozzle_id; ++id) { + auto nozzle = group_result->get_nozzle_from_id(id); + if (nozzle) + volume_types[id] = get_nozzle_volume_type_string(nozzle->volume_type); + } + return volume_types; +} + Vec2d travel_point_1; Vec2d travel_point_2; Vec2d travel_point_3; @@ -299,12 +419,14 @@ static std::vector get_path_of_change_filament(const Print& print) int OozePrevention::_get_temp(const GCode &gcodegen) const { + // Resolve the filament's per-variant config column (equals its id on static prints). + size_t fi = gcodegen.get_filament_config_index((int)gcodegen.writer().filament()->id()); // First layer temperature should be used when on the first layer (obviously) and when // "other layers" is set to zero (which means it should not be used). return (gcodegen.layer() == nullptr || gcodegen.layer()->id() == 0 - || gcodegen.config().nozzle_temperature.get_at(gcodegen.writer().filament()->id()) == 0) - ? gcodegen.config().nozzle_temperature_initial_layer.get_at(gcodegen.writer().filament()->id()) - : gcodegen.config().nozzle_temperature.get_at(gcodegen.writer().filament()->id()); + || gcodegen.config().nozzle_temperature.get_at(fi) == 0) + ? gcodegen.config().nozzle_temperature_initial_layer.get_at(fi) + : gcodegen.config().nozzle_temperature.get_at(fi); } // Orca: @@ -319,25 +441,35 @@ static std::vector get_path_of_change_filament(const Print& print) // Declare & initialize retraction lengths double retraction_length_remaining = 0, - retractionBeforeWipe = 0, - retractionDuringWipe = 0; + retraction_length_before_wipe = 0, + retraction_length_during_wipe = 0, + retraction_length_after_wipe = 0; - // initialise the remaining retraction amount with the full retraction amount. - retraction_length_remaining = toolchange ? extruder->retract_length_toolchange() : extruder->retraction_length(); + // Initialise the remaining retraction amount with the full retraction amount. + retraction_length_remaining = toolchange ? + extruder->retract_length_toolchange() : extruder->retraction_length(); - // nothing to retract - return early - if(retraction_length_remaining <=EPSILON) return {0.f,0.f}; + // Nothing to retract - return early + if (retraction_length_remaining <= EPSILON) + return { 0.f, 0.f, 0.f }; - // calculate retraction before wipe distance from the user setting. Keep adding to this variable any excess retraction needed - // to be performed before the wipe. - retractionBeforeWipe = retraction_length_remaining * extruder->retract_before_wipe(); - retraction_length_remaining -= retractionBeforeWipe; // subtract it from the remaining retraction length - - // all of the retraction is to be done before the wipe - if(retraction_length_remaining <=EPSILON) return {retractionBeforeWipe,0.f}; + // Calculate retraction before and after wipe distances from the user setting. + // Keep adding to the for retraction before wipe variable any excess retraction + // needed to be performed before the wipe. + retraction_length_before_wipe = retraction_length_remaining * extruder->retract_before_wipe(); + retraction_length_after_wipe = retraction_length_remaining * extruder->retract_after_wipe(); + + // Subtract it from the remaining retraction length + retraction_length_remaining -= retraction_length_before_wipe + retraction_length_after_wipe; + + // All of the retraction is to be done before the wipe + if (retraction_length_remaining <= EPSILON) + return { retraction_length_before_wipe, 0., retraction_length_after_wipe }; // Calculate wipe speed - double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index())); + // Orca: resolve the travel_speed slot via the Print-side per-layer resolver; the writer's + // per-layer synced config would yield the same index. + double wipe_speed = config.role_based_wipe_speed ? writer.get_current_speed() / 60.0 : config.get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.get_nozzle_config_index(gcodegen.writer().filament()->id()))); wipe_speed = std::max(wipe_speed, 10.0); // Process wipe path & calculate wipe path length @@ -347,18 +479,25 @@ static std::vector get_path_of_change_filament(const Print& print) double wipe_path_length = std::min(wipe_path.length(), wipe_dist); // Calculate the maximum retraction amount during wipe - retractionDuringWipe = config.retraction_speed.get_at(extruder_id) * unscale_(wipe_path_length) / wipe_speed; - // If the maximum retraction amount during wipe is too small, return 0 and retract everything prior to the wipe. - if(retractionDuringWipe <= EPSILON) return {retractionBeforeWipe,0.f}; + retraction_length_during_wipe = config.retraction_speed.get_at(extruder_id) * + unscale_(wipe_path_length) / wipe_speed; + + // If the maximum retraction amount during wipe is too small, + // disable wipe-time retraction and leave any remaining retract amount + // to the subsequent standard retract flow. + if (retraction_length_during_wipe <= EPSILON) + return { retraction_length_before_wipe, 0., retraction_length_after_wipe }; // If the maximum retraction amount during wipe is greater than any remaining retraction length // return the remaining retraction length to be retracted during the wipe - if (retractionDuringWipe - retraction_length_remaining > EPSILON) return {retractionBeforeWipe,retraction_length_remaining}; + if (retraction_length_during_wipe - retraction_length_remaining > EPSILON) + return { retraction_length_before_wipe, retraction_length_remaining, retraction_length_after_wipe }; // We will always proceed with incrementing the retraction amount before wiping with the difference // and return the maximum allowed wipe amount to be retracted during the wipe move - retractionBeforeWipe += retraction_length_remaining - retractionDuringWipe; - return {retractionBeforeWipe, retractionDuringWipe}; + retraction_length_before_wipe += retraction_length_remaining - retraction_length_during_wipe; + + return { retraction_length_before_wipe, retraction_length_during_wipe, retraction_length_after_wipe }; } std::string transform_gcode(const std::string &gcode, Vec2f pos, const Vec2f &translation, float angle) @@ -429,7 +568,9 @@ static std::vector get_path_of_change_filament(const Print& print) /* Reduce feedrate a bit; travel speed is often too high to move on existing material. Too fast = ripping of existing material; too slow = short wipe path, thus more blob. */ - double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.cur_extruder_index()));// gcodegen.writer().config.travel_speed.value * 0.8; + // Orca: resolve the travel_speed slot via the Print-side per-layer resolver; the writer's + // per-layer synced config would yield the same index. + double _wipe_speed = gcodegen.config().get_abs_value("wipe_speed", gcodegen.config().travel_speed.get_at(gcodegen.get_nozzle_config_index(gcodegen.writer().filament()->id())));// gcodegen.writer().config.travel_speed.value * 0.8; if(gcodegen.config().role_based_wipe_speed) _wipe_speed = gcodegen.writer().get_current_speed() / 60.0; if(_wipe_speed < 10) @@ -443,7 +584,7 @@ static std::vector get_path_of_change_filament(const Print& print) amount of retraction. In other words, how far do we move in XY at wipe_speed for the time needed to consume retraction_length at retraction_speed? */ // BBS - double wipe_dist = scale_(gcodegen.config().wipe_distance.get_at(gcodegen.writer().filament()->id())); + double wipe_dist = scale_(gcodegen.config().wipe_distance.get_at(gcodegen.get_filament_config_index((int)gcodegen.writer().filament()->id()))); /* Take the stored wipe path and replace first point with the current actual position (they might be different, for example, in case of loop clipping). */ @@ -505,9 +646,11 @@ static std::vector get_path_of_change_filament(const Print& print) } // set volumetric speed of outer wall ,ignore per obejct & region ,just use default setting - static float get_outer_wall_volumetric_speed(const FullPrintConfig& config, const Print& print, int filament_id, int extruder_id) { + // filament_variant_idx selects the per-variant column of filament_max_volumetric_speed + // (equals filament_id unless a per-layer nozzle grouping expanded the filament arrays). + static float get_outer_wall_volumetric_speed(const FullPrintConfig& config, const Print& print, int filament_id, int filament_variant_idx, int extruder_id) { float outer_wall_volumetric_speed = 0; - float filament_max_volumetric_speed = config.filament_max_volumetric_speed.get_at(filament_id); + float filament_max_volumetric_speed = config.filament_max_volumetric_speed.get_at(filament_variant_idx); const double filament_diameter = config.filament_diameter.get_at(filament_id); float outer_wall_line_width = print.default_region_config().get_abs_value("outer_wall_line_width", filament_diameter); if (outer_wall_line_width == 0.0) { @@ -716,6 +859,9 @@ static std::vector get_path_of_change_filament(const Print& print) int new_extruder_id = get_extruder_index(*m_print_config, new_filament_id); + // Logical nozzle grouping for this print (null on paths that don't populate it). + auto group_result = gcodegen.m_print->get_layered_nozzle_group_result(); + bool is_nozzle_change = !tcr.nozzle_change_result.gcode.empty() && (gcodegen.config().nozzle_diameter.size() > 1); std::string gcode; @@ -780,6 +926,10 @@ static std::vector get_path_of_change_filament(const Print& print) const std::string& filament_end_gcode = gcodegen.config().filament_end_gcode.get_at(old_filament_id); if (gcodegen.writer().filament() != nullptr && !filament_end_gcode.empty()) { DynamicConfig config; + config.set_key_value("current_filament_id", new ConfigOptionInt((int) old_filament_id)); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, (int) old_filament_id, (int) gcodegen.writer().filament()->extruder_id(), m_layer_idx))); + config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index)); config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z)); if (!gcodegen.m_filament_instances_code.empty()) { @@ -792,12 +942,9 @@ static std::vector get_path_of_change_filament(const Print& print) } } - //BBS: increase toolchange count - gcodegen.m_toolchange_count++; - std::string toolchange_gcode_str; - ZHopType z_hope_type = ZHopType(gcodegen.config().z_hop_types.get_at(gcodegen.writer().filament()->id())); + ZHopType z_hope_type = ZHopType(gcodegen.config().z_hop_types.get_at(gcodegen.get_filament_config_index((int)gcodegen.writer().filament()->id()))); LiftType auto_lift_type = LiftType::NormalLift; if (z_hope_type == ZHopType::zhtAuto || z_hope_type == ZHopType::zhtSpiral || z_hope_type == ZHopType::zhtSlope) auto_lift_type = LiftType::SpiralLift; @@ -843,13 +990,33 @@ static std::vector get_path_of_change_filament(const Print& print) DynamicConfig config; int old_filament_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->id() : -1; int old_extruder_id = gcodegen.writer().filament() ? (int)gcodegen.writer().filament()->extruder_id() : -1; + // Logical nozzle ids for old/new filament (null-safe -> extruder id). + int old_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, old_filament_id, old_extruder_id, m_layer_idx); + int next_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, m_layer_idx); config.set_key_value("previous_extruder", new ConfigOptionInt(old_filament_id)); config.set_key_value("next_extruder", new ConfigOptionInt(new_filament_id)); - config.set_key_value("current_hotend", new ConfigOptionInt(old_extruder_id >= 0 ? - hotend_id_for_gcode_placeholder(gcodegen.m_config, old_extruder_id) : -1)); - config.set_key_value("next_hotend", - new ConfigOptionInt(hotend_id_for_gcode_placeholder(gcodegen.m_config, (int) gcodegen.get_extruder_id(new_filament_id)))); + // current_hotend/next_hotend (see hotend_id_for_gcode_placeholder): multi-nozzle H2C -> -1 + // (static; dynamic branch dormant), X2D -> -1, existing printers -> extruder id. + config.set_key_value("current_hotend", new ConfigOptionInt( + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, old_filament_id, old_extruder_id, m_layer_idx))); + config.set_key_value("next_hotend", new ConfigOptionInt( + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, new_filament_id, (int) gcodegen.get_extruder_id(new_filament_id), m_layer_idx))); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(old_nozzle_id)); + config.set_key_value("next_nozzle_id", new ConfigOptionInt(next_nozzle_id)); + config.set_key_value("current_filament_id", new ConfigOptionInt(old_filament_id)); + config.set_key_value("next_filament_id", new ConfigOptionInt(new_filament_id)); + // Orca: nozzle-volume variant of the old/new extruder (e.g. "Direct Drive TPU High Flow"), + // consumed by H2D's variant-aware change_filament_gcode. Null-safe: old_extruder_id may be -1. + { + const auto &extruder_variants = m_print_config->printer_extruder_variant.values; + config.set_key_value("old_extruder_variant", new ConfigOptionString( + (old_extruder_id >= 0 && old_extruder_id < (int) extruder_variants.size()) ? extruder_variants[old_extruder_id] : std::string())); + config.set_key_value("new_extruder_variant", new ConfigOptionString( + (new_extruder_id >= 0 && new_extruder_id < (int) extruder_variants.size()) ? extruder_variants[new_extruder_id] : std::string())); + } + config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); config.set_key_value("layer_num", new ConfigOptionInt(gcodegen.m_layer_index)); config.set_key_value("layer_z", new ConfigOptionFloat(tcr.print_z)); config.set_key_value("toolchange_z", new ConfigOptionFloat(z)); @@ -859,25 +1026,32 @@ static std::vector get_path_of_change_filament(const Print& print) GCodeWriter& gcode_writer = gcodegen.m_writer; FullPrintConfig& full_config = gcodegen.m_config; + // Per-variant filament arrays can hold one column per variant a filament uses + // under a per-layer nozzle grouping; resolve the column instead of the raw id. + // The old filament resolves at the current layer, which is safe because the + // per-layer maps are gap-filled carry-forward. + size_t old_fi = (old_filament_id != -1) ? gcodegen.get_filament_config_index(old_filament_id) : 0; + size_t new_fi = gcodegen.get_filament_config_index(new_filament_id); + // set volumetric speed of outer wall ,ignore per obejct,just use default setting - float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(full_config, *gcodegen.m_print, new_filament_id, gcodegen.get_extruder_id(new_filament_id)); + float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(full_config, *gcodegen.m_print, new_filament_id, (int)new_fi, gcodegen.get_extruder_id(new_filament_id)); config.set_key_value("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed)); - float old_retract_length = (old_filament_id != -1) ? full_config.retraction_length.get_at(old_filament_id) : 0; - float new_retract_length = full_config.retraction_length.get_at(new_filament_id); + float old_retract_length = (old_filament_id != -1) ? full_config.retraction_length.get_at(old_fi) : 0; + float new_retract_length = full_config.retraction_length.get_at(new_fi); float old_retract_length_toolchange = (old_filament_id != -1) ? full_config.retract_length_toolchange.get_at(old_filament_id) : 0; float new_retract_length_toolchange = full_config.retract_length_toolchange.get_at(new_filament_id); - int old_filament_temp = (old_filament_id != -1) ? (gcodegen.on_first_layer()? full_config.nozzle_temperature_initial_layer.get_at(old_filament_id) : full_config.nozzle_temperature.get_at(old_filament_id)) : 210; - int new_filament_temp = gcodegen.on_first_layer() ? full_config.nozzle_temperature_initial_layer.get_at(new_filament_id) : full_config.nozzle_temperature.get_at(new_filament_id); + int old_filament_temp = (old_filament_id != -1) ? (gcodegen.on_first_layer()? full_config.nozzle_temperature_initial_layer.get_at(old_fi) : full_config.nozzle_temperature.get_at(old_fi)) : 210; + int new_filament_temp = gcodegen.on_first_layer() ? full_config.nozzle_temperature_initial_layer.get_at(new_fi) : full_config.nozzle_temperature.get_at(new_fi); Vec3d nozzle_pos = gcode_writer.get_position(); float purge_volume = tcr.purge_volume < EPSILON ? 0 : std::max(tcr.purge_volume, g_min_purge_volume); float filament_area = float((M_PI / 4.f) * pow(full_config.filament_diameter.get_at(new_filament_id), 2)); float purge_length = purge_volume / filament_area; - int old_filament_e_feedrate = (old_filament_id != -1) ? (int)(60.0 * full_config.filament_max_volumetric_speed.get_at(old_filament_id) / filament_area) : 200; + int old_filament_e_feedrate = (old_filament_id != -1) ? (int)(60.0 * full_config.filament_max_volumetric_speed.get_at(old_fi) / filament_area) : 200; old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate; - int new_filament_e_feedrate = (int)(60.0 * full_config.filament_max_volumetric_speed.get_at(new_filament_id) / filament_area); + int new_filament_e_feedrate = (int)(60.0 * full_config.filament_max_volumetric_speed.get_at(new_fi) / filament_area); new_filament_e_feedrate = new_filament_e_feedrate == 0 ? 100 : new_filament_e_feedrate; float wipe_avoid_pos_x = 0.f; { @@ -887,16 +1061,38 @@ static std::vector get_path_of_change_filament(const Print& print) wipe_avoid_pos_x = get_wipe_avoid_pos_x(box_min, box_max, 3.f); } + // Nozzle-heating center just outside the wipe tower. Clamp X to the + // region every extruder can reach (shared printable polygon), which equals the full + // printable_area for all current single/dual printers, so existing output is unchanged. + Vec2f stop_pos = tool_change_start_pos; + { + BoundingBoxf bbx = m_wipe_tower_bbx; + bbx.translate((m_wipe_tower_pos + m_rib_offset).cast()); + stop_pos.x() += (stop_pos.x() < bbx.center().x()) ? -2.f : 2.f; + auto printer_bbx = unscaled(get_extents(gcodegen.m_print->get_extruder_shared_printable_polygon())); + if (stop_pos.x() < printer_bbx.min[0]) stop_pos.x() = float(printer_bbx.min[0]); + if (stop_pos.x() > printer_bbx.max[0]) stop_pos.x() = float(printer_bbx.max[0]); + } + config.set_key_value("wipe_tower_center_pos_x", new ConfigOptionFloat(stop_pos.x())); + config.set_key_value("wipe_tower_center_pos_y", new ConfigOptionFloat(stop_pos.y())); + config.set_key_value("wipe_tower_center_pos_valid", new ConfigOptionBool(true)); + config.set_key_value("max_layer_z", new ConfigOptionFloat(gcodegen.m_max_layer_z)); config.set_key_value("relative_e_axis", new ConfigOptionBool(full_config.use_relative_e_distances)); - config.set_key_value("toolchange_count", new ConfigOptionInt((int) gcodegen.m_toolchange_count)); + config.set_key_value("toolchange_count", new ConfigOptionInt((int) gcodegen.m_toolchange_count + 1)); // BBS: fan speed is useless placeholer now, but we don't remove it to avoid // slicing error in old change_filament_gcode in old 3MF config.set_key_value("fan_speed", new ConfigOptionInt((int) 0)); config.set_key_value("old_retract_length", new ConfigOptionFloat(old_retract_length)); config.set_key_value("new_retract_length", new ConfigOptionFloat(new_retract_length)); + // Expose the old filament's nozzle-change retract length (filament_retract_length_nc; nil/-1 -> 0). + config.set_key_value("filament_retract_length_nc", new ConfigOptionFloat( + (old_filament_id != -1) ? (float) full_config.filament_retract_length_nc.get_at(old_fi) : 0.f)); config.set_key_value("old_retract_length_toolchange", new ConfigOptionFloat(old_retract_length_toolchange)); config.set_key_value("new_retract_length_toolchange", new ConfigOptionFloat(new_retract_length_toolchange)); + // Current parked-retract length of the incoming filament's extruder. + config.set_key_value("new_extruder_retracted_length", + new ConfigOptionFloat(gcode_writer.get_extruder_retracted_length((int) new_filament_id))); config.set_key_value("old_filament_temp", new ConfigOptionInt(old_filament_temp)); int interface_temp = full_config.filament_tower_interface_print_temp.get_at(new_filament_id); if (interface_temp == -1) @@ -905,12 +1101,19 @@ static std::vector get_path_of_change_filament(const Print& print) new_filament_temp = interface_temp; config.set_key_value("new_filament_temp", new ConfigOptionInt(new_filament_temp)); if (full_config.enable_tower_interface_features && tcr.is_contact) { - auto temps = full_config.nozzle_temperature.values; + // Rebuild in filament order: the config arrays may carry per-variant columns, + // while these placeholder vectors are consumed indexed by filament id. + size_t num_filaments = full_config.filament_type.values.size(); + std::vector temps(num_filaments); + std::vector first_layer_temps(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) { + size_t fi_i = gcodegen.get_filament_config_index((int)i); + temps[i] = full_config.nozzle_temperature.get_at(fi_i); + first_layer_temps[i] = full_config.nozzle_temperature_initial_layer.get_at(fi_i); + } if (new_filament_id >= 0 && new_filament_id < (int)temps.size()) temps[new_filament_id] = interface_temp; config.set_key_value("temperature", new ConfigOptionInts(temps)); - - auto first_layer_temps = full_config.nozzle_temperature_initial_layer.values; if (new_filament_id >= 0 && new_filament_id < (int)first_layer_temps.size()) first_layer_temps[new_filament_id] = interface_temp; config.set_key_value("first_layer_temperature", new ConfigOptionInts(first_layer_temps)); @@ -929,24 +1132,30 @@ static std::vector get_path_of_change_filament(const Print& print) config.set_key_value("travel_point_3_x", new ConfigOptionFloat(float(travel_point_3.x()))); config.set_key_value("travel_point_3_y", new ConfigOptionFloat(float(travel_point_3.y()))); - auto flush_v_speed = m_print_config->filament_flush_volumetric_speed.values; - auto flush_temps = m_print_config->filament_flush_temp.values; - auto filament_cooling_before_tower = m_print_config->filament_cooling_before_tower.values; - for (size_t idx = 0; idx < flush_v_speed.size(); ++idx) { - if (flush_v_speed[idx] == 0) - flush_v_speed[idx] = m_print_config->filament_max_volumetric_speed.get_at(idx); + { + size_t num_filaments = m_print_config->filament_type.values.size(); + // Fast purge mode uses filament_flush_temp_fast; Default is inert. + bool use_fast_flush = m_print_config->prime_volume_mode == PrimeVolumeMode::pvmFast; + std::vector flush_v_speed(num_filaments); + std::vector flush_temps(num_filaments); + std::vector filament_cooling_before_tower(num_filaments); + for (size_t idx = 0; idx < num_filaments; ++idx) { + size_t fi = gcodegen.get_filament_config_index(idx); + flush_v_speed[idx] = m_print_config->filament_flush_volumetric_speed.get_at(fi); + if (flush_v_speed[idx] == 0) + flush_v_speed[idx] = m_print_config->filament_max_volumetric_speed.get_at(fi); + flush_temps[idx] = use_fast_flush ? m_print_config->filament_flush_temp_fast.get_at(fi) + : m_print_config->filament_flush_temp.get_at(fi); + if (flush_temps[idx] == 0) + flush_temps[idx] = m_print_config->nozzle_temperature_range_high.get_at(idx); + filament_cooling_before_tower[idx] = m_print_config->filament_cooling_before_tower.get_at(fi); + } + if (tcr.is_contact || gcodegen.m_layer_index == 0) + std::fill(filament_cooling_before_tower.begin(), filament_cooling_before_tower.end(), 0); + config.set_key_value("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); + config.set_key_value("flush_temperatures", new ConfigOptionInts(flush_temps)); + config.set_key_value("filament_cooling_before_tower", new ConfigOptionFloats(filament_cooling_before_tower)); } - for (size_t idx = 0; idx < flush_temps.size(); ++idx) { - if (flush_temps[idx] == 0) - flush_temps[idx] = m_print_config->nozzle_temperature_range_high.get_at(idx); - } - if (filament_cooling_before_tower.size() < m_print_config->filament_type.values.size()) - filament_cooling_before_tower.resize(m_print_config->filament_type.values.size(), m_print_config->filament_cooling_before_tower.get_at(0)); - if (tcr.is_contact || gcodegen.m_layer_index == 0) - std::fill(filament_cooling_before_tower.begin(), filament_cooling_before_tower.end(), 0); - config.set_key_value("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); - config.set_key_value("flush_temperatures", new ConfigOptionInts(flush_temps)); - config.set_key_value("filament_cooling_before_tower", new ConfigOptionFloats(filament_cooling_before_tower)); config.set_key_value("flush_length", new ConfigOptionFloat(purge_length)); config.set_key_value("wipe_avoid_perimeter", new ConfigOptionBool(is_used_travel_avoid_perimeter)); config.set_key_value("wipe_avoid_pos_x", new ConfigOptionFloat(wipe_avoid_pos_x)); @@ -992,7 +1201,10 @@ static std::vector get_path_of_change_filament(const Print& print) std::string toolchange_command; if (tcr.priming || (new_filament_id >= 0 && gcodegen.writer().need_toolchange(new_filament_id))) - toolchange_command = gcodegen.writer().toolchange(new_filament_id); + // Orca: null-safe, layer-aware nozzle lookup — group_result may be null on + // non-multi-nozzle paths (the helper falls back to the extruder id). + toolchange_command = gcodegen.writer().toolchange(new_filament_id, + nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, m_layer_idx)); if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_filament_id)) toolchange_gcode_str += toolchange_command; else { @@ -1015,10 +1227,20 @@ static std::vector get_path_of_change_filament(const Print& print) BoundingBox avoid_bbx, printer_bbx; { // set printer_bbx - Pointfs bed_pointsf = gcodegen.m_config.printable_area.values; - Points bed_points; - for (auto p : bed_pointsf) { bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast() + plate_origin_2d)); } - printer_bbx = BoundingBox(bed_points); + // Multi-nozzle: clamp the avoid-perimeter travel bounds to the region every + // extruder can reach (get_extruder_shared_printable_polygon) instead of the full + // bed. Gated on the multi-nozzle predicate so H2D and every existing single/dual + // printer keep the historic full-printable_area routing byte-identical. + if (is_multi_nozzle_printer(gcodegen.m_config)) { + printer_bbx = get_extents(gcodegen.m_print->get_extruder_shared_printable_polygon()); + printer_bbx.min = wipe_tower_point_to_object_point(gcodegen, unscaled(printer_bbx.min) + plate_origin_2d); + printer_bbx.max = wipe_tower_point_to_object_point(gcodegen, unscaled(printer_bbx.max) + plate_origin_2d); + } else { + Pointfs bed_pointsf = gcodegen.m_config.printable_area.values; + Points bed_points; + for (auto p : bed_pointsf) { bed_points.push_back(wipe_tower_point_to_object_point(gcodegen, p.cast() + plate_origin_2d)); } + printer_bbx = BoundingBox(bed_points); + } } { // set avoid_bbx @@ -1049,14 +1271,37 @@ static std::vector get_path_of_change_filament(const Print& print) } // do unretract after setting current extruder_id - std::string toolchange_unretract_str = gcodegen.unretract(); + // PETG filaments on a device with a filament switcher get a small (2 mm) pre-extrusion + // before the tool change. has_filament_switcher is a develop-only key read defensively from the + // full config (Orca does not carry it as a static PrintConfig member — same convention as + // enable_filament_dynamic_map); no shipping profile sets it (grep resources/profiles = 0), so + // is_petg_pre_extrusion is always false -> extra_unretract stays 0 -> byte-identical to the plain + // unretract() fleet-wide. The tower-interface contact pre-extrusion length (the + // is_contact_pre_extrusion branch) is NOT applied here; it is only computed as the guard used to + // give the contact path priority over PETG. + const ConfigOptionBool* has_filament_switcher_opt = gcodegen.m_print->full_print_config().option("has_filament_switcher"); + bool is_contact_pre_extrusion = tcr.is_contact && gcodegen.m_config.enable_tower_interface_features; + bool is_petg_pre_extrusion = !is_contact_pre_extrusion + && gcodegen.config().filament_type.get_at(tcr.new_tool) == "PETG" + && has_filament_switcher_opt && has_filament_switcher_opt->value; + float extra_unretract = is_petg_pre_extrusion ? 2.f : 0.f; + std::string toolchange_unretract_str = (extra_unretract > 0.f) ? gcodegen.unretract(extra_unretract) : gcodegen.unretract(); check_add_eol(toolchange_unretract_str); gcodegen.placeholder_parser().set("current_extruder", new_filament_id); - gcodegen.placeholder_parser().set("retraction_distance_when_cut", gcodegen.m_config.retraction_distances_when_cut.get_at(new_filament_id)); - gcodegen.placeholder_parser().set("long_retraction_when_cut", gcodegen.m_config.long_retractions_when_cut.get_at(new_filament_id)); - gcodegen.placeholder_parser().set("retraction_distance_when_ec", gcodegen.m_config.retraction_distances_when_ec.get_at(new_filament_id)); - gcodegen.placeholder_parser().set("long_retraction_when_ec", gcodegen.m_config.long_retractions_when_ec.get_at(new_filament_id)); + gcodegen.placeholder_parser().set("current_filament_id", new_filament_id); + gcodegen.placeholder_parser().set("current_extruder_id", new_extruder_id); + gcodegen.placeholder_parser().set("current_nozzle_id", + nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, m_layer_idx)); + gcodegen.placeholder_parser().set("current_hotend", + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, new_filament_id, new_extruder_id, m_layer_idx)); + { + size_t fi = gcodegen.get_filament_config_index(new_filament_id); + gcodegen.placeholder_parser().set("retraction_distance_when_cut", gcodegen.m_config.retraction_distances_when_cut.get_at(fi)); + gcodegen.placeholder_parser().set("long_retraction_when_cut", gcodegen.m_config.long_retractions_when_cut.get_at(fi)); + gcodegen.placeholder_parser().set("retraction_distance_when_ec", gcodegen.m_config.retraction_distances_when_ec.get_at(fi)); + gcodegen.placeholder_parser().set("long_retraction_when_ec", gcodegen.m_config.long_retractions_when_ec.get_at(fi)); + } // Process the start filament gcode. std::string start_filament_gcode_str; @@ -1065,6 +1310,10 @@ static std::vector get_path_of_change_filament(const Print& print) // Process the filament_start_gcode for the active filament only. DynamicConfig config; config.set_key_value("filament_extruder_id", new ConfigOptionInt(new_filament_id)); + config.set_key_value("current_filament_id", new ConfigOptionInt(new_filament_id)); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, m_layer_idx))); + config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); start_filament_gcode_str = gcodegen.placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config); if (add_change_filament_624) { start_filament_gcode_str += "M625\n"; @@ -1083,6 +1332,10 @@ static std::vector get_path_of_change_filament(const Print& print) std::string tcr_gcode, tcr_escaped_gcode = gcodegen.placeholder_parser_process("tcr_rotated_gcode", tcr_rotated_gcode, new_filament_id, &config); unescape_string_cstyle(tcr_escaped_gcode, tcr_gcode); gcode += tcr_gcode; + // Count the toolchange only when the emitted block really changed the tool — + // tower visits without a filament change must not advance the ordinal. + if (custom_gcode_changes_tool(tcr_gcode, gcodegen.writer().toolchange_prefix(), new_filament_id)) + gcodegen.m_toolchange_count++; check_add_eol(toolchange_gcode_str); // SoftFever: set new PA for new filament @@ -1214,10 +1467,12 @@ static std::vector get_path_of_change_filament(const Print& print) } if (toolchange_temp_override > 0) { - int base_temp = gcodegen.on_first_layer() ? gcodegen.config().nozzle_temperature_initial_layer.get_at(new_extruder_id) - : gcodegen.config().nozzle_temperature.get_at(new_extruder_id); + // new_extruder_id is the incoming filament id; resolve its per-variant config column. + size_t new_fi = gcodegen.get_filament_config_index(new_extruder_id); + int base_temp = gcodegen.on_first_layer() ? gcodegen.config().nozzle_temperature_initial_layer.get_at(new_fi) + : gcodegen.config().nozzle_temperature.get_at(new_fi); if (std::abs(tcr.print_z) < EPSILON) - base_temp = gcodegen.config().nozzle_temperature_initial_layer.get_at(new_extruder_id); + base_temp = gcodegen.config().nozzle_temperature_initial_layer.get_at(new_fi); const std::string t_token = " T" + std::to_string(new_extruder_id); std::string out; out.reserve(toolchange_gcode_str.size()); @@ -1602,8 +1857,8 @@ static std::vector get_path_of_change_filament(const Print& print) const std::vector ColorPrintColors::Colors = { "#C0392B", "#E67E22", "#F1C40F", "#27AE60", "#1ABC9C", "#2980B9", "#9B59B6" }; #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->extruder_id()) -#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(m_writer.filament()->id()) -#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(cur_extruder_index()) +#define FILAMENT_CONFIG(OPT) m_config.OPT.get_at(get_filament_config_index(m_writer.filament()->id())) +#define NOZZLE_CONFIG(OPT) m_config.OPT.get_at(get_nozzle_config_index(m_writer.filament()->id())) void GCode::PlaceholderParserIntegration::reset() { @@ -2143,11 +2398,13 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu m_processor.result().support_traditional_timelapse = m_support_traditional_timelapse; bool activate_long_retraction_when_cut = false; - for (const auto& filament : m_writer.extruders()) + for (const auto& filament : m_writer.extruders()) { + size_t fi = get_filament_config_index((int)filament.id()); activate_long_retraction_when_cut |= ( - m_config.long_retractions_when_cut.get_at(filament.id()) - && m_config.retraction_distances_when_cut.get_at(filament.id()) > 0 + m_config.long_retractions_when_cut.get_at(fi) + && m_config.retraction_distances_when_cut.get_at(fi) > 0 ); + } m_processor.result().long_retraction_when_cut = activate_long_retraction_when_cut; @@ -2172,9 +2429,31 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu extruder_unprintable_polys, m_print->get_extruder_printable_height(), m_print->get_filament_maps(), m_print->get_physical_unprintable_filaments(m_print->get_slice_used_filaments(false))); + // Hand the per-filament nozzle grouping to the processor BEFORE finalize, so the + // pre-heat injector's second pass can resolve filament->nozzle->extruder (get_nozzle_from_id / + // is_support_dynamic_nozzle_map). Print::_do_export re-assigns it onto the extracted result afterwards + // (Print.cpp) for the device GUI, but that is too late for the in-finalize injector. Null for + // single-nozzle prints, where the injector is gated off anyway (enable_pre_heating false). + m_processor.result().nozzle_group_result = m_print->get_layered_nozzle_group_result(); + m_processor.finalize(true); // DoExport::update_print_estimated_times_stats(m_processor, print->m_print_statistics); DoExport::update_print_estimated_stats(m_processor, m_writer.extruders(), print->m_print_statistics, print->config()); + // Printed-mass safety check. Flushed filament leaves the bed, so subtract it + // from the total to get the mass actually resting on the plate. Gated on machine_max_printed_mass + // (>0 only for A2L machines), so no existing printer's gcode_check_result changes. + if (m_print->config().machine_max_printed_mass.value > EPSILON) { + double mass_on_bed_total = print->m_print_statistics.total_weight; + for (auto volume : m_processor.get_result().print_statistics.flush_per_filament) { + size_t extruder_id = volume.first; + auto extruder = std::find_if(m_writer.extruders().begin(), m_writer.extruders().end(), [extruder_id](const Extruder &extr) { return extr.id() == extruder_id; }); + if (extruder == m_writer.extruders().end()) continue; + mass_on_bed_total -= (volume.second * extruder->filament_density() * 0.001); + } // flushed weight will not be keeped on the hot bed, exclude it + if (mass_on_bed_total > m_print->config().machine_max_printed_mass.value) { + m_processor.result().gcode_check_result.error_code |= (1 << 11); // printed weight over limit + } + } if (result != nullptr) { *result = std::move(m_processor.extract_result()); // set the filename to the correct value @@ -2208,11 +2487,16 @@ void GCode::do_export(Print* print, const char* path, GCodeProcessorResult* resu // free functions called by GCode::_do_export() namespace DoExport { - static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled) + static void init_gcode_processor(const PrintConfig& config, GCodeProcessor& processor, bool& silent_time_estimator_enabled, + const std::shared_ptr& nozzle_group_result = nullptr) { silent_time_estimator_enabled = (config.gcode_flavor == gcfMarlinLegacy || config.gcode_flavor == gcfMarlinFirmware) && config.silent_mode; processor.reset(); + // Slot-resolution context for the streaming replay (reset() just cleared it). This is NOT + // the post-stream result-field handover at the end of do_export, which gates the richer + // change-time model and must stay after the stream. + processor.initialize_from_context(nozzle_group_result); processor.initialize_result_moves(); processor.apply_config(config); processor.enable_stealth_time_estimator(silent_time_estimator_enabled); @@ -2465,9 +2749,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_print = &print; m_timelapse_pos_picker.init(&print,m_writer.get_xy_offset().cast()); + // init as filament map + update_layer_related_config(0); // modifies m_silent_time_estimator_enabled - DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled); + DoExport::init_gcode_processor(print.config(), m_processor, m_silent_time_estimator_enabled, + print.get_layered_nozzle_group_result()); const bool is_bbl_printers = print.is_BBL_printer(); const WipeTowerType wipe_tower_type = print.wipe_tower_type(); m_calib_config.clear(); @@ -2476,6 +2763,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato m_last_layer_z = 0.f; m_max_layer_z = 0.f; m_last_width = 0.f; + m_last_layer_accumulated_mass = 0.0; m_is_role_based_fan_on.fill(false); m_role_based_fan_marker_layer.fill(-1); @@ -2728,6 +3016,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato first_non_support_filaments.resize(print.config().nozzle_diameter.size(), -1); first_filaments.resize(print.config().nozzle_diameter.size(), -1); float max_additional_fan = 0.f; + // Sequential selector prints consume the per-object plans cached by Print::process — they were + // planned with cross-object nozzle-status threading and match the published stitched result; a + // fresh construction here would re-plan from a different seed. Static sequential prints keep + // the fresh per-object construction (byte-identical output). + const auto &seq_dynamic_orderings = print.sequential_dynamic_orderings(); + const bool use_seq_dynamic_cache = print.is_dynamic_group_reorder() && !seq_dynamic_orderings.empty(); if (print.config().print_sequence == PrintSequence::ByObject) { // Order object instances for sequential print. print_object_instances_ordering = sort_object_instances_by_model_order(print); @@ -2737,9 +3031,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato first_has_extrude_print_object = print_object_instance_sequential_active; bool find_fist_non_support_filament = false; for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) { - tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); - - tool_ordering.sort_and_build_data(*(*print_object_instance_sequential_active)->print_object,initial_extruder_id); + auto cached_ordering = use_seq_dynamic_cache ? seq_dynamic_orderings.find((*print_object_instance_sequential_active)->print_object) : seq_dynamic_orderings.end(); + if (cached_ordering != seq_dynamic_orderings.end()) { + tool_ordering = cached_ordering->second; + } else { + tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); + tool_ordering.sort_and_build_data(*(*print_object_instance_sequential_active)->print_object,initial_extruder_id); + } float temp_max_additional_fan = tool_ordering.cal_max_additional_fan(print.config()); if(temp_max_additional_fan > max_additional_fan ) max_additional_fan = temp_max_additional_fan; @@ -2848,23 +3146,49 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato //BBS match_physical_extruder_for_each_filament(first_non_support_filaments, m_config); + // Logical nozzle grouping for this print (null on paths that don't populate it). + auto group_result = m_print->get_layered_nozzle_group_result(); + std::vector first_non_support_hotends; + first_non_support_hotends.reserve(first_non_support_filaments.size()); + for (int filament_id : first_non_support_filaments) + first_non_support_hotends.push_back(filament_id < 0 ? -1 : + first_hotend_id_for_gcode_placeholder(m_config, group_result, filament_id, (int) get_extruder_id(filament_id))); + this->placeholder_parser().set("first_non_support_tools", new ConfigOptionInts(first_non_support_filaments)); this->placeholder_parser().set("first_non_support_filaments", new ConfigOptionInts(first_non_support_filaments)); + this->placeholder_parser().set("first_non_support_hotend", new ConfigOptionInts(first_non_support_hotends)); this->placeholder_parser().set("initial_no_support_tool", initial_non_support_extruder_id); this->placeholder_parser().set("initial_no_support_extruder", initial_non_support_extruder_id); + // initial_no_support_hotend/current_hotend (see first_hotend_id_for_gcode_placeholder): multi-nozzle + // H2C -> -1 (static; dynamic branch dormant), X2D -> -1, existing printers -> extruder id. this->placeholder_parser().set("initial_no_support_hotend", - hotend_id_for_gcode_placeholder(m_config, (int) get_extruder_id(initial_non_support_extruder_id))); + first_hotend_id_for_gcode_placeholder(m_config, group_result, (int) initial_non_support_extruder_id, (int) get_extruder_id(initial_non_support_extruder_id))); this->placeholder_parser().set("current_extruder", initial_extruder_id); - this->placeholder_parser().set("current_hotend", hotend_id_for_gcode_placeholder(m_config, extruder_id)); - //Orca: set the key for compatibilty - this->placeholder_parser().set("retraction_distance_when_cut", m_config.retraction_distances_when_cut.get_at(initial_extruder_id)); - this->placeholder_parser().set("long_retraction_when_cut", m_config.long_retractions_when_cut.get_at(initial_extruder_id)); - this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(initial_extruder_id)); - this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(initial_extruder_id)); + this->placeholder_parser().set("current_hotend", + first_hotend_id_for_gcode_placeholder(m_config, group_result, (int) initial_extruder_id, extruder_id)); + this->placeholder_parser().set("current_filament_id", (int) initial_extruder_id); + this->placeholder_parser().set("current_extruder_id", extruder_id); + this->placeholder_parser().set("current_nozzle_id", + first_nozzle_id_for_gcode_placeholder(group_result, (int) initial_extruder_id, extruder_id)); + // Initial filament/nozzle vocabulary + this->placeholder_parser().set("initial_filament_id", (int) initial_extruder_id); + this->placeholder_parser().set("initial_no_support_filament_id", (int) initial_non_support_extruder_id); + this->placeholder_parser().set("initial_nozzle_id", first_nozzle_id_for_gcode_placeholder(group_result, (int) initial_extruder_id, extruder_id)); + this->placeholder_parser().set("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + this->placeholder_parser().set("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); + //Orca: set the key for compatibilty, scalar values for the initial extruder (variant-aware) + { + size_t fi = get_filament_config_index(initial_extruder_id); + this->placeholder_parser().set("retraction_distance_when_cut", m_config.retraction_distances_when_cut.get_at(fi)); + this->placeholder_parser().set("long_retraction_when_cut", m_config.long_retractions_when_cut.get_at(fi)); + this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(fi)); + this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(fi)); + } this->placeholder_parser().set("temperature", new ConfigOptionInts(print.config().nozzle_temperature)); - - this->placeholder_parser().set("retraction_distances_when_cut", new ConfigOptionFloats(m_config.retraction_distances_when_cut)); + // retraction_distances_when_cut (array), flush_volumetric_speeds, flush_temperatures and + // filament_cooling_before_tower are set by update_placeholder_parser_with_variant_params() + // with variant-aware remapping. this->placeholder_parser().set("long_retractions_when_cut",new ConfigOptionBools(m_config.long_retractions_when_cut)); this->placeholder_parser().set("retraction_distances_when_ec", new ConfigOptionFloatsNullable(m_config.retraction_distances_when_ec)); this->placeholder_parser().set("long_retractions_when_ec",new ConfigOptionBoolsNullable(m_config.long_retractions_when_ec)); @@ -2874,25 +3198,34 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato this->placeholder_parser().set("close_additional_fan_first_x_layers", new ConfigOptionInts(m_config.close_additional_fan_first_x_layers)); this->placeholder_parser().set("additional_fan_full_speed_layer", new ConfigOptionInts(m_config.additional_fan_full_speed_layer)); - auto flush_v_speed = m_config.filament_flush_volumetric_speed.values; - auto flush_temps = m_config.filament_flush_temp.values; - for (size_t idx = 0; idx < flush_v_speed.size(); ++idx) { - if (flush_v_speed[idx] == 0) - flush_v_speed[idx] = m_config.filament_max_volumetric_speed.get_at(idx); - } - for (size_t idx = 0; idx < flush_temps.size(); ++idx) { - if (flush_temps[idx] == 0) - flush_temps[idx] = m_config.nozzle_temperature_range_high.get_at(idx); - } - this->placeholder_parser().set("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); - this->placeholder_parser().set("flush_temperatures", new ConfigOptionInts(flush_temps)); - this->placeholder_parser().set("filament_cooling_before_tower", new ConfigOptionFloatsNullable(m_config.filament_cooling_before_tower)); //Set variable for total layer count so it can be used in custom gcode. this->placeholder_parser().set("total_layer_count", m_layer_count); // Useful for sequential prints. this->placeholder_parser().set("current_object_idx", 0); // For the start / end G-code to do the priming and final filament pull in case there is no wipe tower provided. this->placeholder_parser().set("has_wipe_tower", has_wipe_tower); + + // Nozzle-heating center just outside the wipe tower. The tower side is chosen + // from the full-bed midpoint, then X is clamped to the region every extruder can reach (shared printable + // polygon) = the full printable_area for all current single/dual printers, so existing output is unchanged. + Vec2f wipe_tower_center = Vec2f::Zero(); + bool wipe_tower_center_valid = false; + if (has_wipe_tower) { + BoundingBoxf bbx = print.wipe_tower_data().bbx; + bbx.translate(print.get_fake_wipe_tower().pos.cast()); + BoundingBoxf printer_bed_bbx(m_config.printable_area.values); + if (bbx.center().x() < printer_bed_bbx.center().x()) + wipe_tower_center = Vec2f(float(bbx.max.x() + 2.f), float(bbx.center().y())); + else + wipe_tower_center = Vec2f(float(bbx.min.x() - 2.f), float(bbx.center().y())); + auto printer_bbx = unscaled(get_extents(print.get_extruder_shared_printable_polygon())); + if (wipe_tower_center.x() < printer_bbx.min[0]) wipe_tower_center.x() = float(printer_bbx.min[0]); + if (wipe_tower_center.x() > printer_bbx.max[0]) wipe_tower_center.x() = float(printer_bbx.max[0]); + wipe_tower_center_valid = true; + } + this->placeholder_parser().set("wipe_tower_center_pos_x", new ConfigOptionFloat(wipe_tower_center.x())); + this->placeholder_parser().set("wipe_tower_center_pos_y", new ConfigOptionFloat(wipe_tower_center.y())); + this->placeholder_parser().set("wipe_tower_center_pos_valid", new ConfigOptionBool(wipe_tower_center_valid)); this->placeholder_parser().set("has_single_extruder_multi_material_priming", wipe_tower_type == WipeTowerType::Type2 && has_wipe_tower && print.config().single_extruder_multi_material_priming); this->placeholder_parser().set("total_toolchanges", DoExport::resolve_total_toolchanges(print.wipe_tower_data(), print.tool_ordering())); this->placeholder_parser().set("num_extruders", int(print.config().nozzle_diameter.values.size())); @@ -3063,7 +3396,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato this->placeholder_parser().set("during_print_exhaust_fan_speed_num", new ConfigOptionInts(during_print_exhaust_fan_speed_num)); //BBS: calculate the volumetric speed of outer wall. Ignore pre-object setting and multi-filament, and just use the default setting - float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(m_config, print, initial_non_support_extruder_id, get_extruder_id(initial_non_support_extruder_id)); + float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(m_config, print, initial_non_support_extruder_id, + (int) get_filament_config_index((int) initial_non_support_extruder_id), + get_extruder_id(initial_non_support_extruder_id)); this->placeholder_parser().set("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed)); auto first_layer_filaments = print.get_slice_used_filaments(true); @@ -3116,6 +3451,9 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato this->placeholder_parser().set("print_time_sec", new ConfigOptionString(GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Print_Time_Sec_Placeholder))); this->placeholder_parser().set("used_filament_length", new ConfigOptionString(GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Used_Filament_Length_Placeholder))); + // Sync variant-mapped params into placeholder_parser before processing start gcode + update_placeholder_parser_with_variant_params(); + std::string machine_start_gcode = this->placeholder_parser_process("machine_start_gcode", print.config().machine_start_gcode.value, initial_extruder_id); if (print.config().gcode_flavor != gcfKlipper) { // Set bed temperature if the start G-code does not contain any bed temp control G-codes. @@ -3136,6 +3474,13 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Write the custom start G-code file.writeln(machine_start_gcode); + // Mark the end of the machine start g-code so the GCodeProcessor usage-block builder knows where user + // g-code ends and can start attributing filament/extruder usage. Gated on enable_pre_heating: only the + // injector fleet (H2D/X2D/H2D-Pro/H2C) emits it; the byte-frozen fleet (X1/P1/A1/H2S, flag false) never + // does, so their g-code is byte-identical. Without this marker handle_filament_change early-returns and + // no blocks are built, so this line is what actually activates the pre-heat injector. + if (m_config.enable_pre_heating.value) + file.write_format(";%s\n", GCodeProcessor::Machine_Start_GCode_End_Tag.c_str()); //BBS: gcode writer doesn't know where the real position of extruder is after inserting custom gcode m_writer.set_current_position_clear(false); @@ -3147,11 +3492,27 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato { DynamicConfig config; config.set_key_value("filament_extruder_id", new ConfigOptionInt((int)(initial_non_support_extruder_id))); + config.set_key_value("current_filament_id", new ConfigOptionInt((int)(initial_non_support_extruder_id))); + config.set_key_value("current_extruder_id", new ConfigOptionInt((int) get_extruder_id(initial_non_support_extruder_id))); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(first_nozzle_id_for_gcode_placeholder(group_result, (int) initial_non_support_extruder_id, (int) get_extruder_id(initial_non_support_extruder_id)))); + config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); std::string filament_start_gcode = this->placeholder_parser_process("filament_start_gcode", print.config().filament_start_gcode.values.at(initial_non_support_extruder_id), initial_non_support_extruder_id,&config); file.writeln(filament_start_gcode); - // mark the first filament used in print - file.write_format(";VT%d\n", initial_extruder_id); + // Mark the first filament used in print. Multi-nozzle printers (H2C) get ";VT%d H%d" where + // H = dynamic ? nozzle_id : -1; existing single-nozzle printers keep the bare ";VT%d" so their + // g-code stays byte-identical. (The dynamic branch is dormant, so H2C currently emits H-1.) + if (is_multi_nozzle_printer(m_config)) { + int initial_nozzle_id = -1; + if (group_result && group_result->is_support_dynamic_nozzle_map()) { + auto initial_nozzle = group_result->get_first_nozzle_for_filament(initial_extruder_id); + initial_nozzle_id = initial_nozzle ? initial_nozzle->group_id : -1; + } + file.write_format(";VT%d H%d\n", initial_extruder_id, initial_nozzle_id); + } else { + file.write_format(";VT%d\n", initial_extruder_id); + } } // Orca: add missing PA settings for initial filament if (m_config.enable_pressure_advance.get_at(initial_non_support_extruder_id)) { @@ -3186,10 +3547,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Orca: when activate_air_filtration is set on any extruder, find and set the highest during_print_exhaust_fan_speed for (const auto &extruder : m_writer.extruders()) { - if (m_config.activate_air_filtration.get_at(extruder.id()) && m_config.activate_air_filtration_during_print.get_at(extruder.id())) { + size_t fi = get_filament_config_index((int)extruder.id()); + if (m_config.activate_air_filtration.get_at(fi) && m_config.activate_air_filtration_during_print.get_at(fi)) { activate_air_filtration_during_print = true; during_print_exhaust_fan_speed = std::max(during_print_exhaust_fan_speed, - m_config.during_print_exhaust_fan_speed.get_at(extruder.id())); + m_config.during_print_exhaust_fan_speed.get_at(fi)); } } @@ -3285,8 +3647,15 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++ print_object_instance_sequential_active) { const PrintObject &object = *(*print_object_instance_sequential_active)->print_object; if (&object != prev_object || tool_ordering.first_extruder() != final_extruder_id) { - tool_ordering = ToolOrdering(object, final_extruder_id); - tool_ordering.sort_and_build_data(object, final_extruder_id); + auto cached_ordering = use_seq_dynamic_cache ? seq_dynamic_orderings.find(&object) : seq_dynamic_orderings.end(); + if (cached_ordering != seq_dynamic_orderings.end()) { + // Never re-plan a selector object mid-export: the cached plan is what the + // published stitched result was built from. + tool_ordering = cached_ordering->second; + } else { + tool_ordering = ToolOrdering(object, final_extruder_id); + tool_ordering.sort_and_build_data(object, final_extruder_id); + } unsigned int new_extruder_id = tool_ordering.first_extruder(); if (new_extruder_id == (unsigned int)-1) // Skip this object. @@ -3319,7 +3688,7 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato } else { file.write(this->retract()); } - file.write(m_writer.travel_to_z(m_max_layer_z + m_writer.config.z_hop.get_at(initial_extruder_id))); + file.write(m_writer.travel_to_z(m_max_layer_z + m_writer.config.z_hop.get_at(get_filament_config_index((int)initial_extruder_id)))); file.write(this->travel_to(Point(0, 0), erNone, "move to origin position for next object")); m_enable_cooling_markers = true; // Disable motion planner when traveling to first object point. @@ -3471,6 +3840,12 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // adds tag for processor file.write_format(";%s%s\n", GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Role).c_str(), ExtrusionEntity::role_to_string(erCustom).c_str()); + // Mark the start of the machine end g-code so the usage-block builder closes its open blocks here and + // ignores filament changes inside the end g-code. Same enable_pre_heating gate as the start marker → + // byte-frozen fleet unaffected. + if (m_config.enable_pre_heating.value) + file.write_format(";%s\n", GCodeProcessor::Machine_End_GCode_Start_Tag.c_str()); + // Process filament-specific gcode in extruder order. { DynamicConfig config; @@ -3478,16 +3853,24 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato //BBS config.set_key_value("layer_z", new ConfigOptionFloat(m_writer.get_position()(2) - m_config.z_offset.value)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); + config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); if (print.config().single_extruder_multi_material) { // Process the filament_end_gcode for the active filament only. int extruder_id = m_writer.filament()->id(); config.set_key_value("filament_extruder_id", new ConfigOptionInt(extruder_id)); + config.set_key_value("current_filament_id", new ConfigOptionInt(extruder_id)); + config.set_key_value("current_extruder_id", new ConfigOptionInt((int) get_extruder_id(extruder_id))); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, extruder_id, (int) get_extruder_id(extruder_id), m_layer_index))); file.writeln(this->placeholder_parser_process("filament_end_gcode", print.config().filament_end_gcode.get_at(extruder_id), extruder_id, &config)); } else { for (const std::string &end_gcode : print.config().filament_end_gcode.values) { int extruder_id = (unsigned int)(&end_gcode - &print.config().filament_end_gcode.values.front()); config.set_key_value("filament_extruder_id", new ConfigOptionInt(extruder_id)); + config.set_key_value("current_filament_id", new ConfigOptionInt(extruder_id)); + config.set_key_value("current_extruder_id", new ConfigOptionInt((int) get_extruder_id(extruder_id))); + config.set_key_value("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, extruder_id, (int) get_extruder_id(extruder_id), m_layer_index))); file.writeln(this->placeholder_parser_process("filament_end_gcode", end_gcode, extruder_id, &config)); } } @@ -3506,9 +3889,10 @@ void GCode::_do_export(Print& print, GCodeOutputStream &file, ThumbnailsGenerato // Orca: when activate_air_filtration is set on any extruder, find and set the highest complete_print_exhaust_fan_speed for (const auto& extruder : m_writer.extruders()) { - if (m_config.activate_air_filtration.get_at(extruder.id()) && m_config.activate_air_filtration_on_completion.get_at(extruder.id())) { + size_t fi = get_filament_config_index((int)extruder.id()); + if (m_config.activate_air_filtration.get_at(fi) && m_config.activate_air_filtration_on_completion.get_at(fi)) { activate_air_filtration_on_completion = true; - complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(extruder.id())); + complete_print_exhaust_fan_speed = std::max(complete_print_exhaust_fan_speed, m_config.complete_print_exhaust_fan_speed.get_at(fi)); } } @@ -3581,7 +3965,18 @@ void GCode::export_layer_filaments(GCodeProcessorResult* result) std::vectorprev_filament(m_config.nozzle_diameter.size(), -1); for (size_t idx = 0; idx < m_sorted_layer_filaments.size(); ++idx) { for (auto f : m_sorted_layer_filaments[idx]) { + // Mirror the guard in the sibling sequence loop below (the `filament_id < filament_map.size() && + // filament_map[filament_id] > 0` check): the H2C dynamic engine can yield a + // per-layer filament set whose ids fall outside filament_map, or a filament_map value beyond the + // physical-extruder count (prev_filament is sized nozzle_diameter.size()). Either an unguarded read + // (filament_map[f], prev_filament[extruder_idx]) or the write below would be out of bounds and + // corrupt the heap. Skipping such filaments keeps every access in range; on any valid slice the + // guard never fires, so the shipping/static path is byte-identical. + if (f >= filament_map.size() || filament_map[f] <= 0) + continue; int extruder_idx = filament_map[f] - 1; + if (extruder_idx >= (int) prev_filament.size()) + continue; if (prev_filament[extruder_idx] != -1 && f != prev_filament[extruder_idx]) { std::pair from_to_pair = { prev_filament[extruder_idx],f }; auto iter = result->filament_change_count_map.find(from_to_pair); @@ -3662,6 +4057,25 @@ size_t GCode::get_extruder_id(unsigned int filament_id) const return 0; } +size_t GCode::get_filament_config_index(int filament_id) const +{ + if (m_print) { + return m_print->get_filament_config_indx(filament_id, m_cur_layer_idx); + } + // Orca: without a Print the filament-indexed arrays are unexpanded, so the + // filament id itself is the only meaningful column. + return filament_id; +} + +size_t GCode::get_nozzle_config_index(int filament_id) const +{ + if (m_print) { + return m_print->get_nozzle_config_index(filament_id, m_cur_layer_idx); + } + // Orca: same reasoning; degenerate to the filament's extruder column. + return get_extruder_id(filament_id); +} + // Process all layers of all objects (non-sequential mode) with a parallel pipeline: // Generate G-code, run the filters (vase mode, cooling buffer), run the G-code analyser // and export G-code into file. @@ -4095,7 +4509,7 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr bool include_g10 = print.config().gcode_flavor == gcfRepRapFirmware; if (custom_gcode_sets_temperature(gcode, 104, 109, include_g10, temp_by_gcode)) { // Set the extruder temperature at m_writer, but throw away the generated G-code as it will be written with the custom G-code. - int temp = print.config().nozzle_temperature_initial_layer.get_at(first_printing_extruder_id); + int temp = print.config().nozzle_temperature_initial_layer.get_at(get_filament_config_index((int)first_printing_extruder_id)); if (temp_by_gcode >= 0 && temp_by_gcode < 1000) temp = temp_by_gcode; m_writer.set_temperature(temp, wait, first_printing_extruder_id); @@ -4103,13 +4517,13 @@ void GCode::_print_first_layer_extruder_temperatures(GCodeOutputStream &file, Pr // Custom G-code does not set the extruder temperature. Do it now. if (print.config().single_extruder_multi_material.value) { // Set temperature of the first printing extruder only. - int temp = print.config().nozzle_temperature_initial_layer.get_at(first_printing_extruder_id); + int temp = print.config().nozzle_temperature_initial_layer.get_at(get_filament_config_index((int)first_printing_extruder_id)); if (temp > 0) file.write(m_writer.set_temperature(temp, wait, first_printing_extruder_id)); } else { // Set temperatures of all the printing extruders. for (unsigned int tool_id : print.extruders()) { - int temp = print.config().nozzle_temperature_initial_layer.get_at(tool_id); + int temp = print.config().nozzle_temperature_initial_layer.get_at(get_filament_config_index((int)tool_id)); if (m_ooze_prevention.enable && tool_id != first_printing_extruder_id) { if (print.config().idle_temperature.get_at(tool_id) == 0) temp += print.config().standby_temperature_delta.value; @@ -4564,6 +4978,289 @@ std::string GCode::generate_object_brim(const Print &print, const PrintObject &o return emit_brim(brim_it->second, { object.id() }); } +// Bedslinger model. The heavier the bed load, the lower the achievable Y acceleration for a given +// drive force (a = F / (bed_mass + printed_mass)). Reads machine_max_force_Y / machine_bed_mass_Y (both +// default 0, i.e. absent on every existing printer), in which case it just returns the min configured Y +// acceleration. +void GCode::mass_load_limited_machine_acceleration( + const PrintStatistics &curr_print_statistics, + const Print &print, // input + double &y_acceleration_limit_res, // output + double &accumulated_mass_res) +{ + double curr_acceleration_y_config = 1e10; + auto &machine_max_acceleration_y = print.config().machine_max_acceleration_y.values; + for (auto &temp : machine_max_acceleration_y) + if (curr_acceleration_y_config > temp) curr_acceleration_y_config = temp; + accumulated_mass_res = curr_print_statistics.total_weight; + // mass in g, acceleration in mm/s2 + double machine_max_force_Y = print.config().machine_max_force_Y.getFloat(), + machine_bed_mass_Y = print.config().machine_bed_mass_Y.getFloat(); + if (machine_max_force_Y > EPSILON && machine_bed_mass_Y > EPSILON) { + // This item is not applicable to this printer FIXME-other printers need acceleration limit? + double virtual_force_g_mms2 = machine_max_force_Y * 1e6, // x N =x * 1e6 g*mm/s2 + curr_acceleration_temp = curr_acceleration_y_config; // temps + if (accumulated_mass_res > EPSILON) { + curr_acceleration_temp = virtual_force_g_mms2 / (machine_bed_mass_Y + accumulated_mass_res); + y_acceleration_limit_res = std::min(curr_acceleration_temp, curr_acceleration_y_config); + } else { + y_acceleration_limit_res = curr_acceleration_y_config; + BOOST_LOG_TRIVIAL(info) << "mass_load_limited_machine_acceleration: Printed mass not detected"; + } + } else { + y_acceleration_limit_res = curr_acceleration_y_config; + } +} + +// Farthest-point timelapse. Scan every extrusion path on this layer and record the point +// farthest from the camera (bed origin 0,0), plus which extruder prints it and whether that extruder is +// the photo head (most_used_extruder). Called only when the subsystem is enabled, so it is a no-op for +// every printer that does not set farthest_point_timelapse. +// Orca: the PrintRegionConfig filament keys are named outer_wall_filament_id / sparse_infill_filament_id / +// internal_solid_filament_id (handle_legacy renames), so the region reads use those names. +void GCode::compute_farthest_point(const std::vector &layers, int most_used_extruder, + const std::map, unsigned int> &support_filaments) +{ + m_farthest_point_timelapse.farthest_point = Point(0, 0); + m_farthest_point_timelapse.farthest_gcode_pos = Vec2d(0, 0); + m_farthest_point_timelapse.farthest_extruder_id = 0; + m_farthest_point_timelapse.farthest_is_photo_head = false; + + // Track farthest point for external perimeters and fallback (infill/support) separately + int64_t max_dist_sq_ext = -1; + Point farthest_point_ext; + int farthest_extruder_ext = 0; + + int64_t max_dist_sq_fallback = -1; + Point farthest_point_fallback; + int farthest_extruder_fallback = 0; + + // Recursive visitor: call fn(const ExtrusionPath&) for every leaf path + auto for_each_path = [](const ExtrusionEntity *entity, const auto &fn, const auto &self) -> void { + if (entity->is_collection()) { + for (const auto *child : static_cast(entity)->entities) + self(child, fn, self); + } else if (entity->is_loop()) { + for (const ExtrusionPath &p : static_cast(entity)->paths) + fn(p); + } else if (const auto *mp = dynamic_cast(entity)) { + for (const ExtrusionPath &p : mp->paths) + fn(p); + } else { + fn(static_cast(*entity)); + } + }; + + auto is_ext_perimeter_role = [](ExtrusionRole role) -> bool { + return role == erExternalPerimeter; + }; + auto is_fallback_role = [](ExtrusionRole role) -> bool { + return role == erInternalInfill || role == erSolidInfill || role == erTopSolidInfill; + }; + auto is_candidate_support_role = [](ExtrusionRole role) -> bool { + return role == erSupportMaterial || role == erSupportMaterialInterface || role == erSupportTransition; + }; + + // Update a (max_dist_sq, point, extruder_id) triple + auto update_max = [](int64_t &max_dsq, Point &out_point, int &out_ext, + const Point &p, const Point &shift, int extruder_id) { + Point global = p + shift; + int64_t dsq = (int64_t)global.x() * global.x() + (int64_t)global.y() * global.y(); + if (dsq > max_dsq) { + max_dsq = dsq; + out_point = global; + out_ext = extruder_id; + } + }; + + // Collect candidate endpoints from one ExtrusionPath, handling arc fitting. + // Orca: ExtrusionPath::polyline is a Polyline3 (Point3 points) rather than a 2D Polyline, so each + // stored point is projected to 2D via to_point() before the distance test (Z is irrelevant here). + auto collect_from_path = [&update_max](int64_t &max_dsq, Point &out_point, int &out_ext, + const ExtrusionPath &path, const Point &shift, int extruder_id) { + const Polyline3 &poly = path.polyline; + if (poly.points.empty()) return; + + if (!poly.fitting_result.empty()) { + if (poly.fitting_result.front().start_point_index < poly.points.size()) + update_max(max_dsq, out_point, out_ext, + poly.points[poly.fitting_result.front().start_point_index].to_point(), shift, extruder_id); + + for (const PathFittingData &seg : poly.fitting_result) { + if (seg.path_type == EMovePathType::Linear_move) { + for (size_t i = seg.start_point_index; i <= seg.end_point_index && i < poly.points.size(); ++i) + update_max(max_dsq, out_point, out_ext, poly.points[i].to_point(), shift, extruder_id); + } else if (seg.path_type == EMovePathType::Arc_move_cw || seg.path_type == EMovePathType::Arc_move_ccw) { + update_max(max_dsq, out_point, out_ext, seg.arc_data.end_point, shift, extruder_id); + } + } + } else { + for (const Point3 &pt : poly.points) + update_max(max_dsq, out_point, out_ext, pt.to_point(), shift, extruder_id); + } + }; + + // Single pass: scan all paths, collecting ext-perimeter and fallback candidates. + // Use original_object (not ltp.object()) to get instance shifts, because + // ltp.object() may return a shared/merged PrintObject whose instances() only + // reflects one copy's shift. original_object preserves the per-ModelObject + // PrintObject with correct instance positions. + for (const LayerToPrint <p : layers) { + const PrintObject *print_obj = ltp.original_object; + if (!print_obj) continue; + + for (const PrintInstance &inst : print_obj->instances()) { + const Point &shift = inst.shift; + + if (ltp.object_layer) { + for (const LayerRegion *region : ltp.object_layer->regions()) { + const PrintRegionConfig &rcfg = region->region().config(); + + for (const ExtrusionEntity *entity : region->perimeters.entities) { + for_each_path(entity, [&](const ExtrusionPath &path) { + if (is_ext_perimeter_role(path.role())) + collect_from_path(max_dist_sq_ext, farthest_point_ext, farthest_extruder_ext, + path, shift, (int)get_extruder_id(rcfg.outer_wall_filament_id.value - 1)); + }, for_each_path); + } + + for (const ExtrusionEntity *entity : region->fills.entities) { + for_each_path(entity, [&](const ExtrusionPath &path) { + if (!is_fallback_role(path.role())) return; + int eid = (path.role() == erInternalInfill) + ? (int)get_extruder_id(rcfg.sparse_infill_filament_id.value - 1) + : (int)get_extruder_id(rcfg.internal_solid_filament_id.value - 1); + collect_from_path(max_dist_sq_fallback, farthest_point_fallback, farthest_extruder_fallback, + path, shift, eid); + }, for_each_path); + } + } + } + + if (ltp.support_layer) { + for (const ExtrusionEntity *entity : ltp.support_layer->support_fills.entities) { + for_each_path(entity, [&](const ExtrusionPath &path) { + if (!is_candidate_support_role(path.role())) return; + auto support_filament = support_filaments.find({ ltp.support_layer, path.role() }); + if (support_filament == support_filaments.end()) return; + int eid = (int)get_extruder_id(support_filament->second); + collect_from_path(max_dist_sq_fallback, farthest_point_fallback, farthest_extruder_fallback, + path, shift, eid); + }, for_each_path); + } + } + } + } + + // Prefer external perimeter result; fall back to infill/support + int64_t max_dist_sq; + if (max_dist_sq_ext > 0) { + max_dist_sq = max_dist_sq_ext; + m_farthest_point_timelapse.farthest_point = farthest_point_ext; + m_farthest_point_timelapse.farthest_extruder_id = farthest_extruder_ext; + } else { + max_dist_sq = max_dist_sq_fallback; + m_farthest_point_timelapse.farthest_point = farthest_point_fallback; + m_farthest_point_timelapse.farthest_extruder_id = farthest_extruder_fallback; + } + + if (max_dist_sq > 0) { + m_farthest_point_timelapse.farthest_gcode_pos = unscale(m_farthest_point_timelapse.farthest_point); + // Single nozzle with AMS: all virtual extruders share one physical nozzle, + // so the nozzle is always the photo head regardless of which filament is used. + bool single_nozzle = (m_config.nozzle_diameter.size() <= 1); + m_farthest_point_timelapse.farthest_is_photo_head = single_nozzle || (m_farthest_point_timelapse.farthest_extruder_id == most_used_extruder); + } +} + +// Build the per-layer timelapse snapshot g-code. Extracted from the former process_layer +// `insert_timelapse_gcode` lambda so the per-extrusion inline hook in _extrude() can call it too. +// Byte-identical to the old lambda whenever the farthest-point subsystem is off (skip_pos_pick=false + +// m_farthest_point_timelapse.enabled=false → farthest_point unset in the picker ctx and +// farthest_point_timelapse_enabled=false in the template). +// Orca: returns the g-code string directly (Orca's timelapse path never tracked a final_pos travel +// optimization). +std::string GCode::generate_timelapse_gcode(const Print &print, coordf_t print_z, int most_used_extruder, + const std::set *layer_object_label_ids, + const std::vector *printed_objects, + bool skip_pos_pick) +{ + if (!m_writer.filament()) + return {}; + + PosPickCtx ctx; + ctx.curr_pos = { (coord_t)(scale_(m_writer.get_position().x())),(coord_t)(scale_(m_writer.get_position().y())) }; + ctx.curr_layer = this->layer(); + ctx.curr_extruder_id = m_writer.filament()->extruder_id(); + ctx.picture_extruder_id = most_used_extruder; + if (m_farthest_point_timelapse.enabled) { + // farthest_point is stored in the global print frame (includes plate origin); the picker works in + // the plate-relative frame, so subtract the plate origin here. + Vec3d po = print.get_plate_origin(); + ctx.farthest_point = m_farthest_point_timelapse.farthest_point - Point(scale_(po.x()), scale_(po.y())); + } + if (m_config.print_sequence == PrintSequence::ByObject && printed_objects) + ctx.printed_objects = *printed_objects; + + auto timelapse_pos = skip_pos_pick ? DefaultTimelapsePos : m_timelapse_pos_picker.pick_pos(ctx); + + std::string timelapse_gcode; + if (!print.config().time_lapse_gcode.value.empty()) { + DynamicConfig config; + config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); + config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); + config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); + config.set_key_value("most_used_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(most_used_extruder))); + config.set_key_value("curr_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(ctx.curr_extruder_id))); + config.set_key_value("timelapse_pos_x", new ConfigOptionInt((int)timelapse_pos.x())); + config.set_key_value("timelapse_pos_y", new ConfigOptionInt((int)timelapse_pos.y())); + config.set_key_value("has_timelapse_safe_pos", new ConfigOptionBool(timelapse_pos != DefaultTimelapsePos)); + // Timelapse-context vars. + config.set_key_value("timelapse_inline_photo", new ConfigOptionBool(skip_pos_pick)); + // Drive the template ternary Z{layer_z + (farthest_point_timelapse_enabled ? 0.0 : 0.4)} from the + // effective (per-layer, config+traditional+non-i3-folded) enabled state. False for every printer + // that leaves the toggle off, so their template evaluates to the pre-existing +0.4 lift byte-for-byte. + config.set_key_value("farthest_point_timelapse_enabled", new ConfigOptionBool(m_farthest_point_timelapse.enabled)); + config.set_key_value("clear_to_x0", new ConfigOptionBool(m_timelapse_pos_picker.get_is_clear_to_x0(ctx))); + timelapse_gcode = this->placeholder_parser_process("timelapse_gcode", print.config().time_lapse_gcode.value, m_writer.filament()->id(), &config) + "\n"; + } + + if (!timelapse_gcode.empty()) { + m_writer.set_current_position_clear(false); + + double temp_z_after_tool_change; + if (GCodeProcessor::get_last_z_from_gcode(timelapse_gcode, temp_z_after_tool_change)) { + Vec3d pos = m_writer.get_position(); + pos(2) = temp_z_after_tool_change; + m_writer.set_position(pos); + } + } + + // (layer_object_label_ids->size() < 64) this restriction comes from _encode_label_ids_to_base64() + if (layer_object_label_ids && + is_BBL_Printer() && + (print.num_object_instances() <= g_max_label_object) && // Don't support too many objects on one plate + (print.num_object_instances() > 1) && // Don't support skipping single object + (!layer_object_label_ids->empty()) && + (print.calib_params().mode == CalibMode::Calib_None)) { + std::ostringstream oss; + for (auto it = layer_object_label_ids->begin(); it != layer_object_label_ids->end(); ++it) { + if (it != layer_object_label_ids->begin()) oss << ","; + oss << *it; + } + + std::string start_str = std::string("; object ids of layer ") + std::to_string(m_layer_index + 1) + (" start: ") + oss.str() + "\n"; + start_str += "M624 " + _encode_label_ids_to_base64(std::vector(layer_object_label_ids->begin(), layer_object_label_ids->end())) + "\n"; + + std::string end_str = std::string("; object ids of this layer") + std::to_string(m_layer_index + 1) + (" end: ") + oss.str() + "\n"; + end_str += "M625\n"; + + timelapse_gcode = start_str + timelapse_gcode + end_str; + } + + return timelapse_gcode; +} + // In sequential mode, process_layer is called once per each object and its copy, // therefore layers will contain a single entry and single_object_instance_idx will point to the copy of the object. // In non-sequential mode, process_layer is called per each print_z height with all object and support layers accumulated. @@ -4609,6 +5306,11 @@ LayerResult GCode::process_layer( else if (support_layer != nullptr) layer_ptr = support_layer; const Layer& layer = *layer_ptr; + m_cur_layer_idx = layer.id(); + // A per-layer nozzle grouping can move the active filament to another variant column on a + // layer boundary without a toolchange, so re-resolve the writer's config column here. + if (Extruder *cur_filament = m_writer.filament()) + cur_filament->set_config_index((int)get_filament_config_index((int)cur_filament->id())); LayerResult result { {}, layer.id(), false, last_layer }; if (layer_tools.extruders.empty()) // Nothing to extrude. @@ -4678,6 +5380,16 @@ LayerResult GCode::process_layer( bool is_i3_printer = printer_structure == PrinterStructure::psI3; bool is_multi_extruder = m_config.nozzle_diameter.size() > 1; + // Farthest-point timelapse enable-fold. Corexy-only: gated OFF for i3 (psI3 → A1/A2L), for + // smooth timelapse, and whenever the toggle is unset. When false every downstream hook (compute, + // _extrude inline photo, process_layer case gates, template ternary) is inert, so the whole shipping + // fleet that does not set farthest_point_timelapse is byte-identical to the pre-existing behavior. + m_farthest_point_timelapse.enabled = m_config.farthest_point_timelapse.value + && m_config.timelapse_type.value == TimelapseType::tlTraditional + && printer_structure != PrinterStructure::psI3; + m_farthest_point_timelapse.most_used_extruder = most_used_extruder; + m_farthest_point_timelapse.inserted_this_layer = false; + bool need_insert_timelapse_gcode_for_traditional = false; if ((!m_wipe_tower || !m_wipe_tower->enable_timelapse_print()) && (is_BBL_Printer() || !m_config.time_lapse_gcode.value.empty())) { need_insert_timelapse_gcode_for_traditional = ((is_i3_printer && !m_spiral_vase) || is_multi_extruder); @@ -4694,6 +5406,8 @@ LayerResult GCode::process_layer( // BBS: don't use lazy_raise when enable spiral vase gcode += this->change_layer(print_z); // this will increase m_layer_index + update_layer_related_config(m_layer_index); + update_placeholder_parser_with_variant_params(); m_layer = &layer; m_object_layer_over_raft = false; @@ -4712,6 +5426,35 @@ LayerResult GCode::process_layer( config.set_key_value("most_used_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(most_used_extruder))); config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); + { + const int cur_filament_id = (int) m_writer.filament()->id(); + const auto group_result = m_print->get_layered_nozzle_group_result(); + config.set_key_value("current_filament_id", new ConfigOptionInt(cur_filament_id)); + config.set_key_value("current_nozzle_id", new ConfigOptionInt( + nozzle_id_for_gcode_placeholder(group_result, cur_filament_id, (int) m_writer.filament()->extruder_id(), m_layer_index))); + } + + // Bedslinger mass model. Compute the running printed mass at this layer (same weight calc as + // DoExport::update_print_stats_and_format_filament_stats) and the Y acceleration limit it implies. + // These are new placeholder vars no existing template reads, and mass_load_limited_machine_acceleration + // returns the plain min Y accel unless the A2L force/bed-mass keys are set, so this is inert for every + // existing printer. + PrintStatistics curr_print_statistics; + for (const Extruder &extruder : m_writer.extruders()) { + double extruded_volume = extruder.extruded_volume() + (has_wipe_tower ? print.wipe_tower_data().used_filament[extruder.id()] * 2.4052f : 0.f); // assumes 1.75mm filament diameter + double filament_weight = extruded_volume * extruder.filament_density() * 0.001; + if (filament_weight > 0.) + curr_print_statistics.total_weight += filament_weight; + } + double curr_y_acceleration_limit = -1, curr_accumulated_mass = -1; + mass_load_limited_machine_acceleration(curr_print_statistics, print, curr_y_acceleration_limit, curr_accumulated_mass); + double curr_layer_mass = curr_print_statistics.total_weight - m_last_layer_accumulated_mass; + if (curr_layer_mass <= EPSILON) curr_layer_mass = 0.0; + m_last_layer_accumulated_mass = curr_print_statistics.total_weight; + config.set_key_value("curr_y_acceleration_limit", new ConfigOptionFloat(curr_y_acceleration_limit)); + config.set_key_value("curr_accumulated_mass", new ConfigOptionFloat(curr_accumulated_mass)); + config.set_key_value("curr_layer_mass", new ConfigOptionFloat(curr_layer_mass)); + gcode += this->placeholder_parser_process("layer_change_gcode", print.config().layer_change_gcode.value, m_writer.filament()->id(), &config) + "\n"; @@ -4839,8 +5582,9 @@ LayerResult GCode::process_layer( extruder.id() != m_writer.filament()->id()) // In single extruder multi material mode, set the temperature for the current extruder only. continue; - int temperature = print.config().nozzle_temperature.get_at(extruder.id()); - if (temperature > 0 && temperature != print.config().nozzle_temperature_initial_layer.get_at(extruder.id())) + size_t fi = get_filament_config_index((int)extruder.id()); + int temperature = print.config().nozzle_temperature.get_at(fi); + if (temperature > 0 && temperature != print.config().nozzle_temperature_initial_layer.get_at(fi)) gcode += m_writer.set_temperature(temperature, false, extruder.id()); } @@ -4885,7 +5629,7 @@ LayerResult GCode::process_layer( if (layer_to_print.object_layer) { const auto& regions = layer_to_print.object_layer->regions(); const bool enable_overhang_speed = std::any_of(regions.begin(), regions.end(), [this](const LayerRegion* r) { - return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(cur_extruder_index()); + return r->has_extrusions() && r->region().config().enable_overhang_speed.get_at(get_nozzle_config_index(m_writer.filament()->id())); }); if (enable_overhang_speed) { m_extrusion_quality_estimator.prepare_for_new_layer(layer_to_print.original_object, @@ -4896,6 +5640,10 @@ LayerResult GCode::process_layer( // Group extrusions by an extruder, then by an object, an island and a region. std::map> by_extruder; + // Farthest-point timelapse: per-support-layer/role → extruder map, consumed only by + // compute_farthest_point (below, gated on m_farthest_point_timelapse.enabled). Populated alongside the + // existing support-extruder assignment; unused (and thus output-neutral) when the subsystem is off. + std::map, unsigned int> support_filaments; std::vector> split_perimeter_storage; bool is_anything_overridden = const_cast(layer_tools).wiping_extrusions().is_anything_overridden(); for (const LayerToPrint &layer_to_print : layers) { @@ -4989,6 +5737,16 @@ LayerResult GCode::process_layer( // Both the support and the support interface are printed with the same extruder, therefore // the interface may be interleaved with the support base. bool single_extruder = ! has_support || support_extruder == interface_extruder; + // Farthest-point timelapse: record the extruder for each support role so + // compute_farthest_point can attribute farthest support points correctly. + if (has_support) { + support_filaments[{ &support_layer, erSupportMaterial }] = support_extruder; + support_filaments[{ &support_layer, erSupportTransition }] = support_extruder; + } + if (has_interface) { + support_filaments[{ &support_layer, erSupportMaterialInterface }] = + single_extruder ? (has_support ? support_extruder : interface_extruder) : interface_extruder; + } // Assign an extruder to the base. ObjectByExtruder &obj = object_by_extruder(by_extruder, has_support ? support_extruder : interface_extruder, &layer_to_print - layers.data(), layers.size()); obj.support = &support_layer.support_fills; @@ -5136,6 +5894,11 @@ LayerResult GCode::process_layer( } } // for objects + // Farthest-point timelapse: once all this layer's extrusions are grouped, find the point + // farthest from the camera. No-op when the subsystem is disabled. + if (m_farthest_point_timelapse.enabled) + compute_farthest_point(layers, most_used_extruder, support_filaments); + std::map> filament_to_print_instances; { for (unsigned int filament_id : layer_tools.extruders) { @@ -5175,67 +5938,20 @@ LayerResult GCode::process_layer( } } - auto insert_timelapse_gcode = [this, print_z, &print, &most_used_extruder, &layer_object_label_ids,&printed_objects = std::as_const(m_printed_objects)]() -> std::string { - PosPickCtx ctx; - ctx.curr_pos = { (coord_t)(scale_(m_writer.get_position().x())),(coord_t)(scale_(m_writer.get_position().y())) }; - ctx.curr_layer = this->layer(); - ctx.curr_extruder_id = m_writer.filament()->extruder_id(); - ctx.picture_extruder_id = most_used_extruder; - if (m_config.print_sequence == PrintSequence::ByObject) - ctx.printed_objects = printed_objects; + m_farthest_point_timelapse.layer_object_label_ids = layer_object_label_ids; - auto timelapse_pos=m_timelapse_pos_picker.pick_pos(ctx); - - std::string timelapse_gcode; - if (!print.config().time_lapse_gcode.value.empty()) { - DynamicConfig config; - config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); - config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); - config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); - config.set_key_value("most_used_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(most_used_extruder))); - config.set_key_value("curr_physical_extruder_id", new ConfigOptionInt(m_config.physical_extruder_map.get_at(ctx.curr_extruder_id))); - config.set_key_value("timelapse_pos_x", new ConfigOptionInt((int)timelapse_pos.x())); - config.set_key_value("timelapse_pos_y", new ConfigOptionInt((int)timelapse_pos.y())); - config.set_key_value("has_timelapse_safe_pos", new ConfigOptionBool(timelapse_pos != DefaultTimelapsePos)); - timelapse_gcode = this->placeholder_parser_process("timelapse_gcode", print.config().time_lapse_gcode.value, m_writer.filament()->id(), &config) + "\n"; - } - - if (!timelapse_gcode.empty()) { - m_writer.set_current_position_clear(false); - - double temp_z_after_tool_change; - if (GCodeProcessor::get_last_z_from_gcode(timelapse_gcode, temp_z_after_tool_change)) { - Vec3d pos = m_writer.get_position(); - pos(2) = temp_z_after_tool_change; - m_writer.set_position(pos); - } - } - - // (layer_object_label_ids.size() < 64) this restriction comes from _encode_label_ids_to_base64() - if (is_BBL_Printer() && - (print.num_object_instances() <= g_max_label_object) && // Don't support too many objects on one plate - (print.num_object_instances() > 1) && // Don't support skipping single object - (layer_object_label_ids.size() > 0) && - (print.calib_params().mode == CalibMode::Calib_None)) { - std::ostringstream oss; - for (auto it = layer_object_label_ids.begin(); it != layer_object_label_ids.end(); ++it) { - if (it != layer_object_label_ids.begin()) oss << ","; - oss << *it; - } - - std::string start_str = std::string("; object ids of layer ") + std::to_string(m_layer_index + 1) + (" start: ") + oss.str() + "\n"; - start_str += "M624 " + _encode_label_ids_to_base64(std::vector(layer_object_label_ids.begin(), layer_object_label_ids.end())) + "\n"; - - std::string end_str = std::string("; object ids of this layer") + std::to_string(m_layer_index + 1) + (" end: ") + oss.str() + "\n"; - end_str += "M625\n"; - - timelapse_gcode = start_str + timelapse_gcode + end_str; - } - - return timelapse_gcode; + // skip_pos_pick: when true the head takes an inline photo at its current spot instead of moving to a + // picked safe position. Delegates to the extracted member so the per-extrusion farthest-point hook in + // _extrude() shares the exact same generation path. Every existing call site uses the default (false). + auto insert_timelapse_gcode = [this, print_z, &print, &most_used_extruder, &layer_object_label_ids,&printed_objects = std::as_const(m_printed_objects)](bool skip_pos_pick = false) -> std::string { + return generate_timelapse_gcode(print, print_z, most_used_extruder, &layer_object_label_ids, &printed_objects, skip_pos_pick); }; - if (!need_insert_timelapse_gcode_for_traditional && is_BBL_Printer()) { // Equivalent to the timelapse gcode placed in layer_change_gcode + // With farthest-point-is-photo-head active, the snapshot is deferred to the inline _extrude + // hook / layer-end fallback, so skip the layer-start placement here. The extra clause is inert (true) + // whenever the subsystem is off → pre-existing behavior byte-for-byte. + if (!need_insert_timelapse_gcode_for_traditional && is_BBL_Printer() + && !(m_farthest_point_timelapse.enabled && m_farthest_point_timelapse.farthest_is_photo_head)) { // Equivalent to the timelapse gcode placed in layer_change_gcode if (FILAMENT_CONFIG(retract_when_changing_layer)) { gcode += this->retract(false, false, auto_lift_type, true); } @@ -5291,15 +6007,24 @@ LayerResult GCode::process_layer( m_filament_instances_code = _encode_label_ids_to_base64(filament_instances_id); } + // The inline _extrude hook may already have taken the snapshot mid-extrusion on a + // previous extruder; sync so we don't insert it a second time. + has_insert_timelapse_gcode |= m_farthest_point_timelapse.inserted_this_layer; + std::string gcode_toolchange; if (has_wipe_tower) { if (!m_wipe_tower->is_empty_wipe_tower_gcode(*this, extruder_id, extruder_id == layer_tools.extruders.back())) { - if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode) { + if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode + && !(m_farthest_point_timelapse.enabled && m_farthest_point_timelapse.farthest_is_photo_head)) { bool should_insert = true; if (m_config.nozzle_diameter.values.size() == 2){ - if (!writer().filament() || get_extruder_id(writer().filament()->id()) != most_used_extruder) { - should_insert = false; - } + bool curr_is_photo_head = writer().filament() && + get_extruder_id(writer().filament()->id()) == most_used_extruder; + // Case B (farthest point printed by a non-photo head): the firmware + // snapshots at the picked safe pos, so insert when leaving the photo head instead. + // is_case_b is false whenever the subsystem is off → should_insert == pre-existing value. + bool is_case_b = m_farthest_point_timelapse.enabled && !m_farthest_point_timelapse.farthest_is_photo_head; + should_insert = is_case_b ? !curr_is_photo_head : curr_is_photo_head; } if (should_insert) { @@ -5319,17 +6044,24 @@ LayerResult GCode::process_layer( gcode_toolchange = m_wipe_tower->tool_change(*this, extruder_id, extruder_id == layer_tools.extruders.back()); } } else { + // Same case-A/case-B split for the non-wipe-tower path. With the subsystem off, + // is_case_b is false and should_insert == (curr == most_used) = pre-existing behavior. if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode && + !(m_farthest_point_timelapse.enabled && m_farthest_point_timelapse.farthest_is_photo_head) && m_writer.need_toolchange(extruder_id) && m_config.nozzle_diameter.values.size() == 2 && - writer().filament() && - (get_extruder_id(writer().filament()->id()) == most_used_extruder)) { - gcode += this->retract(false, false, auto_lift_type, true); - m_writer.add_object_change_labels(gcode); + writer().filament()) { + bool curr_is_photo_head = get_extruder_id(writer().filament()->id()) == most_used_extruder; + bool is_case_b = m_farthest_point_timelapse.enabled && !m_farthest_point_timelapse.farthest_is_photo_head; + bool should_insert = is_case_b ? !curr_is_photo_head : curr_is_photo_head; + if (should_insert) { + gcode += this->retract(false, false, auto_lift_type, true); + m_writer.add_object_change_labels(gcode); - gcode += insert_timelapse_gcode(); - has_insert_timelapse_gcode = true; + gcode += insert_timelapse_gcode(); + has_insert_timelapse_gcode = true; + } } if (print.config().enable_wrapping_detection && !has_insert_wrapping_detection_gcode) { @@ -5557,6 +6289,22 @@ LayerResult GCode::process_layer( BOOST_LOG_TRIVIAL(trace) << "Exported layer " << layer.id() << " print_z " << print_z << log_memory_info(); + // The inline _extrude hook may have taken the snapshot; sync. + has_insert_timelapse_gcode |= m_farthest_point_timelapse.inserted_this_layer; + + // Farthest-point-is-photo-head layer-end fallback. If the head never passed within tolerance of + // the farthest point during extrusion (so the inline hook never fired) insert the snapshot here — + // single-extruder prints have no traditional multi-extruder fallback below. Guarded on enabled, so this + // block never runs for a printer with the subsystem off. + if (m_farthest_point_timelapse.enabled && m_farthest_point_timelapse.farthest_is_photo_head && !has_insert_timelapse_gcode) { + if (FILAMENT_CONFIG(retract_when_changing_layer)) { + gcode += this->retract(false, false, auto_lift_type, true); + } + m_writer.add_object_change_labels(gcode); + gcode += insert_timelapse_gcode(); + has_insert_timelapse_gcode = true; + } + if (need_insert_timelapse_gcode_for_traditional && !has_insert_timelapse_gcode) { // The traditional model of thin-walled object will have flaws for I3 if (m_support_traditional_timelapse @@ -5625,7 +6373,10 @@ void GCode::append_full_config(const Print &print, std::string &str) { DynamicPrintConfig cfg = print.full_print_config(); { // correct the flush_volumes_matrix with flush_multiplier values - std::vector temp_cfg_flush_multiplier = cfg.option("flush_multiplier")->values; + // Fast purge mode uses flush_multiplier_fast; Default is inert. + std::vector temp_cfg_flush_multiplier = (print.config().prime_volume_mode == PrimeVolumeMode::pvmFast) + ? cfg.option("flush_multiplier_fast")->values + : cfg.option("flush_multiplier")->values; std::vector temp_flush_volumes_matrix = cfg.option("flush_volumes_matrix")->values; auto temp_filament_color = cfg.option("filament_colour")->values; size_t heads_count_tmp = temp_cfg_flush_multiplier.size(), @@ -5646,8 +6397,36 @@ void GCode::append_full_config(const Print &print, std::string &str) throw Slic3r::SlicingError(_(L("Flush volumes matrix do not match to the correct size!"))); } } + // filament_map_2 (the per-filament (extruder x volume-type) slot map) is computed during apply / + // write-back and lives in the applied print config only; the pre-expansion snapshot this dump is + // built from still carries the registered default. Copy the real values so the header line is + // diagnostic (nothing parses it back). + cfg.option("filament_map_2", true)->values = print.config().filament_map_2.values; // Sorted list of config keys, which shall not be stored into the G-code. Initializer list. static const std::set banned_keys( { + // filament_extruder_compatibility is a device-side (blacklist) compatibility hint read from the + // loaded presets, never consumed by slicing or firmware. Keep it out of the G-code config block so + // the config key stays inert to g-code (byte-identical output). + "filament_extruder_compatibility"sv, + // The fast-purge / prime-volume-mode keys are new static-member registrations. Excluding them from + // the config block keeps registration byte-identical for the shipping fleet (default + // prime_volume_mode==Default leaves the slicing body unchanged; only the config-dump would otherwise + // gain lines). They only affect output on the pvmFast / pvmSaving branch. + "prime_volume_mode"sv, + "flush_multiplier_fast"sv, + "filament_flush_temp_fast"sv, + "support_fast_purge_mode"sv, + // deretract_speed_extruder_change is a device/firmware-facing machine-profile key with no slicer + // consumer. Banning it from the g-code config dump keeps the H2D/A2L/X2D/P2S leaves that carry it + // byte-identical, while still registering it as a known, validated config key. + "deretract_speed_extruder_change"sv, + // farthest_point_timelapse is a newly-registered printer key (corexy-only timelapse refinement). + // Excluding it from the config block keeps the config-dump byte-identical for the whole shipping + // fleet — otherwise every printer's dump would gain a `= 0` line vs the previous baseline, and + // H2C/H2D would gain a non-timelapse `= 1` line. The key is read at slice time from m_config, so + // banning it from the dump has no effect on the feature; the only H2C/H2D delta is the M9711/M971 + // snapshot reposition. + "farthest_point_timelapse"sv, "compatible_printers"sv, "compatible_prints"sv, "print_host"sv, @@ -6215,7 +6994,8 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill static constexpr const char* support_transition_label = "support transition"; static constexpr const char* support_ironing_label = "support ironing"; - static const auto speed_for_path = [&](double length, ExtrusionRole role, double default_speed = -1.0) { + // Not static: it captures `this` by reference. + const auto speed_for_path = [&](double length, ExtrusionRole role, double default_speed = -1.0) { if (!is_support(role) || length > SMALL_PERIMETER_LENGTH(NOZZLE_CONFIG(small_support_perimeter_threshold))) return default_speed; @@ -6469,12 +7249,12 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } else if (this->object_layer_over_raft() && m_config.first_layer_acceleration_over_raft.value > 0) { acceleration = m_config.first_layer_acceleration_over_raft.value; #endif - } else if (m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index()) > 0 && is_bridge(path.role())) { - acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index()); - } else if (m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erInternalInfill)) { - acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", cur_extruder_index()); - } else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index()) > 0 && (path.role() == erSolidInfill)) { - acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", cur_extruder_index()); + } else if (m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && is_bridge(path.role())) { + acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + } else if (m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && (path.role() == erInternalInfill)) { + acceleration = m_config.get_abs_value_at("sparse_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + } else if (m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())) > 0 && (path.role() == erSolidInfill)) { + acceleration = m_config.get_abs_value_at("internal_solid_infill_acceleration", get_nozzle_config_index(m_writer.filament()->id())); } else if (NOZZLE_CONFIG(outer_wall_acceleration) > 0 && is_external_perimeter(path.role())) { acceleration = NOZZLE_CONFIG(outer_wall_acceleration); } else if (NOZZLE_CONFIG(inner_wall_acceleration) > 0 && is_internal_perimeter(path.role())) { @@ -6575,7 +7355,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, } } else if(path.role() == erInternalBridgeInfill) { - speed = m_config.get_abs_value_at("internal_bridge_speed", cur_extruder_index()); + speed = m_config.get_abs_value_at("internal_bridge_speed", get_nozzle_config_index(m_writer.filament()->id())); } else if (path.role() == erOverhangPerimeter || path.role() == erSupportTransition || path.role() == erBridgeInfill) { speed = NOZZLE_CONFIG(bridge_speed); } else if (path.role() == erInternalInfill) { @@ -6969,6 +7749,34 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, ironing_fan_speed >= 0 && path.role() == erIroning); }; + // Farthest-point timelapse inline hook. When the photo head reaches (within 0.5 mm of) the + // farthest-from-camera point while extruding, take the snapshot in place (skip_pos_pick → M971 inline + // photo, no travel). Early-returns unless the subsystem is enabled AND the farthest point is on the + // photo head, so it is a no-op for every printer that leaves the toggle off. + auto check_and_insert_timelapse = [this, &gcode](const Point &endpoint_scaled) { + if (!m_farthest_point_timelapse.enabled || !m_farthest_point_timelapse.farthest_is_photo_head || m_farthest_point_timelapse.inserted_this_layer) + return; + // Inline M971 only when current extruder is the photo head; other nozzles may pass through nearby + // coordinates but their physical position differs. + if (!m_writer.filament() || get_extruder_id(m_writer.filament()->id()) != m_farthest_point_timelapse.most_used_extruder) + return; + // Compare in the global print frame to match farthest_gcode_pos, which is unscale(farthest_point) + // without the per-extruder nozzle offset. Using point_to_gcode() here would subtract extruder_offset + // on this side only, leaving a constant mismatch that could prevent the inline photo from ever + // triggering on machines with a non-zero photo-head extruder_offset. + Vec2d endpoint_mm = unscale(endpoint_scaled) + m_origin; + if ((endpoint_mm - m_farthest_point_timelapse.farthest_gcode_pos).norm() >= 0.5) + return; + if (!m_print || !m_layer) + return; + std::string timelapse_gcode = generate_timelapse_gcode(*m_print, m_layer->print_z, m_farthest_point_timelapse.most_used_extruder, + &m_farthest_point_timelapse.layer_object_label_ids, &m_printed_objects, true); + if (!timelapse_gcode.empty()) { + gcode += timelapse_gcode; + m_farthest_point_timelapse.inserted_this_layer = true; + } + }; + if (!variable_speed) { // F is mm per minute. if( (std::abs(writer().get_current_speed() - F) > EPSILON) || (std::abs(_mm3_per_mm - m_last_mm3_mm) > EPSILON) ){ @@ -7092,6 +7900,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, dE * e_ratio, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); } + check_and_insert_timelapse(line.b.to_point()); // Inline farthest-point snapshot } } else { // BBS: start to generate gcode from arc fitting data which includes line and arc @@ -7121,6 +7930,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, this->point_to_gcode(line.b), dE, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); + check_and_insert_timelapse(line.b); // Inline farthest-point snapshot } break; } @@ -7146,6 +7956,7 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, dE, arc.direction == ArcDirection::Arc_Dir_CCW, GCodeWriter::full_gcode_comment ? tempDescription : "", path.is_force_no_extrusion()); + check_and_insert_timelapse(arc.end_point); // Inline farthest-point snapshot break; } default: @@ -7292,6 +8103,10 @@ std::string GCode::_extrude(const ExtrusionPath &path, std::string description, gcode += m_writer.extrude_to_xyz(dest3d, dE * e_ratio, GCodeWriter::full_gcode_comment ? tempDescription : ""); } + // Inline farthest-point snapshot on the variable-speed emission path. Inert unless the + // farthest-point subsystem is on, matching the other paths. + check_and_insert_timelapse(processed_point.p.to_point()); + prev = p; } @@ -7416,8 +8231,8 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string unsigned int acceleration_to_set = 0; if (this->on_first_layer()) { - unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", cur_extruder_index()); - double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", cur_extruder_index()); + unsigned int initial_layer_travel_acceleration = m_config.get_abs_value_at("initial_layer_travel_acceleration", get_nozzle_config_index(m_writer.filament()->id())); + double initial_layer_travel_jerk = m_config.get_abs_value_at("initial_layer_travel_jerk", get_nozzle_config_index(m_writer.filament()->id())); if (NOZZLE_CONFIG(default_acceleration) > 0 && initial_layer_travel_acceleration > 0) { acceleration_to_set = (unsigned int) floor(initial_layer_travel_acceleration + 0.5); @@ -7430,7 +8245,7 @@ std::string GCode::travel_to(const Point& point, ExtrusionRole role, std::string if (NOZZLE_CONFIG(default_acceleration) > 0) { if (role == erOverhangPerimeter && is_short_travel) { - const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", cur_extruder_index()); + const double bridge_acceleration = m_config.get_abs_value_at("bridge_acceleration", get_nozzle_config_index(m_writer.filament()->id())); if (bridge_acceleration > 0) acceleration_to_set = (unsigned int) floor(bridge_acceleration + 0.5); @@ -7707,8 +8522,12 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li // wipe (if it's enabled for this extruder and we have a stored wipe path and no-zero wipe distance) if (FILAMENT_CONFIG(wipe) && m_wipe.has_path() && scale_(FILAMENT_CONFIG(wipe_distance)) > SCALED_EPSILON) { Wipe::RetractionValues wipeRetractions = m_wipe.calculateWipeRetractionLengths(*this, toolchange); - gcode += toolchange ? m_writer.retract_for_toolchange(true,wipeRetractions.retractLengthBeforeWipe) : m_writer.retract(true, wipeRetractions.retractLengthBeforeWipe); - gcode += m_wipe.wipe(*this,wipeRetractions.retractLengthDuringWipe, toolchange, is_last_retraction); + gcode += toolchange ? m_writer.retract_for_toolchange(true, wipeRetractions.retraction_length_before_wipe) : + m_writer.retract(true, wipeRetractions.retraction_length_before_wipe); + gcode += m_wipe.wipe(*this, wipeRetractions.retraction_length_during_wipe, toolchange, is_last_retraction); + + // Orca: wipeRetractions.retraction_length_after_wipe is not being used explicitly, + // the remaining retraction after wipe is handled by the subsequent m_writer.retract() call } /* The parent class will decide whether we need to perform an actual retraction @@ -7755,6 +8574,87 @@ std::string GCode::retract(bool toolchange, bool is_last_retraction, LiftType li return gcode; } +void GCode::update_layer_related_config(int layer_id){ + auto group_result = m_print->get_layered_nozzle_group_result(); + // Orca: defensive — with no published group result the statically applied config maps stay + // authoritative. + if(!group_result) + return; + + auto extruder_map = group_result->get_extruder_map(false,layer_id); + auto volume_map = group_result->get_volume_map(layer_id); + auto nozzle_map = group_result->get_nozzle_map(layer_id); + + m_config.filament_map.values = extruder_map; + m_config.filament_volume_map.values = volume_map; + m_config.filament_nozzle_map.values = nozzle_map; + + m_writer.config.filament_map.values = extruder_map; + m_writer.config.filament_volume_map.values = volume_map; + m_writer.config.filament_nozzle_map.values = nozzle_map; + +} + +void GCode::update_placeholder_parser_with_variant_params() +{ + if (!m_print) + return; + + size_t num_filaments = m_config.filament_type.values.size(); + if (num_filaments == 0) + return; + + // Helpers: remap config arrays from variant index space to filament_id index space. + // After remapping, gcode templates can use param[filament_id] directly. + auto remap_floats_by_filament = [&](const auto &src) { + std::vector dst(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) + dst[i] = src.get_at(get_filament_config_index(i)); + return dst; + }; + auto remap_ints_by_filament = [&](const auto &src) { + std::vector dst(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) + dst[i] = src.get_at(get_filament_config_index(i)); + return dst; + }; + + // --- filament_options_with_variant: gcode indexes by filament_id --- + this->placeholder_parser().set("filament_max_volumetric_speed", new ConfigOptionFloats(remap_floats_by_filament(m_config.filament_max_volumetric_speed))); + this->placeholder_parser().set("filament_pre_cooling_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.filament_pre_cooling_temperature))); + this->placeholder_parser().set("filament_pre_cooling_temperature_nc", new ConfigOptionInts(remap_ints_by_filament(m_config.filament_pre_cooling_temperature_nc))); + this->placeholder_parser().set("filament_cooling_before_tower", new ConfigOptionFloats(remap_floats_by_filament(m_config.filament_cooling_before_tower))); + this->placeholder_parser().set("nozzle_temperature_initial_layer", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature_initial_layer))); + this->placeholder_parser().set("nozzle_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature))); + // first_layer_temperature is a legacy alias of nozzle_temperature_initial_layer + this->placeholder_parser().set("first_layer_temperature", new ConfigOptionInts(remap_ints_by_filament(m_config.nozzle_temperature_initial_layer))); + + // --- printer_options_with_variant_1: in m_config these are already merged as filament-indexed --- + this->placeholder_parser().set("retraction_distances_when_cut", new ConfigOptionFloats(remap_floats_by_filament(m_config.retraction_distances_when_cut))); + // hotend_cooling_rate / hotend_heating_rate: gcode uses [filament_map[x]-1] (extruder_id), no remap needed + + // --- filament_map: per-layer dynamic, sync from m_config to placeholder_parser --- + this->placeholder_parser().set("filament_map", new ConfigOptionInts(m_config.filament_map)); + + // --- flush_volumetric_speeds / flush_temperatures: derived with fallback --- + { + // Fast purge mode uses filament_flush_temp_fast; Default is inert. + bool use_fast_flush = m_config.prime_volume_mode == PrimeVolumeMode::pvmFast; + auto flush_v_speed = remap_floats_by_filament(m_config.filament_flush_volumetric_speed); + auto filament_max_v = remap_floats_by_filament(m_config.filament_max_volumetric_speed); + auto flush_temps = remap_ints_by_filament(use_fast_flush ? m_config.filament_flush_temp_fast + : m_config.filament_flush_temp); + for (size_t i = 0; i < num_filaments; ++i) { + if (flush_v_speed[i] == 0) + flush_v_speed[i] = filament_max_v[i]; + if (flush_temps[i] == 0) + flush_temps[i] = m_config.nozzle_temperature_range_high.get_at(i); + } + this->placeholder_parser().set("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); + this->placeholder_parser().set("flush_temperatures", new ConfigOptionInts(flush_temps)); + } +} + std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bool by_object, int toolchange_temp_override) { int new_extruder_id = get_extruder_id(new_filament_id); @@ -7764,8 +8664,16 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo // if we are running a single-extruder setup, just set the extruder and return nothing if (!m_writer.multiple_extruders) { this->placeholder_parser().set("current_extruder", new_filament_id); - this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(new_filament_id)); - this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(new_filament_id)); + // Orca: keep the global current-tool identity coherent even on the single-extruder path (see append_tcr). + this->placeholder_parser().set("current_filament_id", (int) new_filament_id); + this->placeholder_parser().set("current_extruder_id", new_extruder_id); + this->placeholder_parser().set("current_nozzle_id", + nozzle_id_for_gcode_placeholder(m_print->get_layered_nozzle_group_result(), (int) new_filament_id, new_extruder_id, m_layer_index)); + { + size_t fi = get_filament_config_index(new_filament_id); + this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(fi)); + this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(fi)); + } std::string gcode; // Append the filament start G-code. @@ -7777,9 +8685,12 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo config.set_key_value("layer_z", new ConfigOptionFloat(this->writer().get_position().z() - m_config.z_offset.value)); config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(new_filament_id))); - config.set_key_value("retraction_distance_when_cut", - new ConfigOptionFloat(m_config.retraction_distances_when_cut.get_at(new_filament_id))); - config.set_key_value("long_retraction_when_cut", new ConfigOptionBool(m_config.long_retractions_when_cut.get_at(new_filament_id))); + { + size_t fi = get_filament_config_index(new_filament_id); + config.set_key_value("retraction_distance_when_cut", + new ConfigOptionFloat(m_config.retraction_distances_when_cut.get_at(fi))); + config.set_key_value("long_retraction_when_cut", new ConfigOptionBool(m_config.long_retractions_when_cut.get_at(fi))); + } gcode += this->placeholder_parser_process("filament_start_gcode", filament_start_gcode, new_filament_id, &config); check_add_eol(gcode); @@ -7791,7 +8702,9 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo m_pa_processor->resetPreviousPA(m_config.pressure_advance.get_at(new_filament_id)); } - gcode += m_writer.toolchange(new_filament_id); + gcode += m_writer.toolchange(new_filament_id, new_extruder_id); + if (Extruder *fil = m_writer.filament()) + fil->set_config_index((int)get_filament_config_index((int)fil->id())); return gcode; } @@ -7837,12 +8750,15 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo gcode += m_ooze_prevention.pre_toolchange(*this); // BBS - float new_retract_length = m_config.retraction_length.get_at(new_filament_id); + // Per-variant filament arrays can hold one column per variant a filament uses under a + // per-layer nozzle grouping; resolve the column instead of indexing by the filament id. + size_t new_fi = get_filament_config_index((int)new_filament_id); + float new_retract_length = m_config.retraction_length.get_at(new_fi); float new_retract_length_toolchange = m_config.retract_length_toolchange.get_at(new_filament_id); - int new_filament_temp = this->on_first_layer() ? m_config.nozzle_temperature_initial_layer.get_at(new_filament_id) : m_config.nozzle_temperature.get_at(new_filament_id); + int new_filament_temp = this->on_first_layer() ? m_config.nozzle_temperature_initial_layer.get_at(new_fi) : m_config.nozzle_temperature.get_at(new_fi); // BBS: if print_z == 0 use first layer temperature if (abs(print_z) < EPSILON) - new_filament_temp = m_config.nozzle_temperature_initial_layer.get_at(new_filament_id); + new_filament_temp = m_config.nozzle_temperature_initial_layer.get_at(new_fi); if (toolchange_temp_override > 0) new_filament_temp = toolchange_temp_override; @@ -7865,9 +8781,12 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo old_filament_id = m_writer.filament() != nullptr ? m_writer.filament()->id() : m_start_gcode_filament; old_extruder_id = m_writer.filament() != nullptr ? m_writer.filament()->extruder_id() : get_extruder_id(m_start_gcode_filament); - old_retract_length = m_config.retraction_length.get_at(old_filament_id); + // Resolving the old filament at the current layer is safe: the per-layer nozzle maps are + // gap-filled carry-forward, so its current-layer column matches the nozzle it occupies. + size_t old_fi = get_filament_config_index(old_filament_id); + old_retract_length = m_config.retraction_length.get_at(old_fi); old_retract_length_toolchange = m_config.retract_length_toolchange.get_at(old_filament_id); - old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(old_filament_id) : m_config.nozzle_temperature.get_at(old_filament_id); + old_filament_temp = this->on_first_layer()? m_config.nozzle_temperature_initial_layer.get_at(old_fi) : m_config.nozzle_temperature.get_at(old_fi); //During the filament change, the extruder will extrude an extra length of grab_length for the corresponding detection, so the purge can reduce this length. float grab_purge_volume = m_config.grab_length.get_at(new_extruder_id) * 2.4; @@ -7887,7 +8806,7 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo } wipe_volume = std::max(0.f, wipe_volume-grab_purge_volume); - old_filament_e_feedrate = (int) (60.0 * m_config.filament_max_volumetric_speed.get_at(old_filament_id) / filament_area); + old_filament_e_feedrate = (int) (60.0 * m_config.filament_max_volumetric_speed.get_at(old_fi) / filament_area); old_filament_e_feedrate = old_filament_e_feedrate == 0 ? 100 : old_filament_e_feedrate; //BBS: must clean m_start_gcode_filament m_start_gcode_filament = -1; @@ -7899,19 +8818,46 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo old_filament_e_feedrate = 200; } float wipe_length = wipe_volume / filament_area; - int new_filament_e_feedrate = (int)(60.0 * m_config.filament_max_volumetric_speed.get_at(new_filament_id) / filament_area); + int new_filament_e_feedrate = (int)(60.0 * m_config.filament_max_volumetric_speed.get_at(new_fi) / filament_area); new_filament_e_feedrate = new_filament_e_feedrate == 0 ? 100 : new_filament_e_feedrate; // set volumetric speed of outer wall ,ignore per obejct,just use default setting - float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(m_config, *m_print, new_filament_id, get_extruder_id(new_filament_id)); + float outer_wall_volumetric_speed = get_outer_wall_volumetric_speed(m_config, *m_print, new_filament_id, (int)new_fi, get_extruder_id(new_filament_id)); float wipe_avoid_pos_x = 110.f; + // Logical nozzle grouping (null on paths that don't populate it) + null-safe nozzle ids. + auto group_result = m_print->get_layered_nozzle_group_result(); + int old_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, old_filament_id, old_extruder_id, m_layer_index); + int next_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, (int) new_filament_id, new_extruder_id, m_layer_index); DynamicConfig dyn_config; dyn_config.set_key_value("outer_wall_volumetric_speed", new ConfigOptionFloat(outer_wall_volumetric_speed)); dyn_config.set_key_value("previous_extruder", new ConfigOptionInt(old_filament_id)); dyn_config.set_key_value("next_extruder", new ConfigOptionInt((int)new_filament_id)); - dyn_config.set_key_value("current_hotend", - new ConfigOptionInt(old_filament_id >= 0 ? hotend_id_for_gcode_placeholder(m_config, old_extruder_id) : -1)); - dyn_config.set_key_value("next_hotend", new ConfigOptionInt(hotend_id_for_gcode_placeholder(m_config, new_extruder_id))); + // current_hotend/next_hotend (see hotend_id_for_gcode_placeholder): multi-nozzle H2C -> -1 + // (static; dynamic branch dormant), X2D -> -1, existing printers -> extruder id. + dyn_config.set_key_value("current_hotend", new ConfigOptionInt( + hotend_id_for_gcode_placeholder(m_config, group_result, old_filament_id, old_extruder_id, m_layer_index))); + dyn_config.set_key_value("next_hotend", new ConfigOptionInt( + hotend_id_for_gcode_placeholder(m_config, group_result, (int) new_filament_id, new_extruder_id, m_layer_index))); + dyn_config.set_key_value("current_nozzle_id", new ConfigOptionInt(old_nozzle_id)); + dyn_config.set_key_value("next_nozzle_id", new ConfigOptionInt(next_nozzle_id)); + dyn_config.set_key_value("current_filament_id", new ConfigOptionInt(old_filament_id)); + dyn_config.set_key_value("next_filament_id", new ConfigOptionInt((int)new_filament_id)); + // Orca: nozzle-volume variant of the old/new extruder (see append_tcr). Null-safe: old_extruder_id may be -1. + { + const auto &extruder_variants = m_config.printer_extruder_variant.values; + dyn_config.set_key_value("old_extruder_variant", new ConfigOptionString( + (old_extruder_id >= 0 && old_extruder_id < (int) extruder_variants.size()) ? extruder_variants[old_extruder_id] : std::string())); + dyn_config.set_key_value("new_extruder_variant", new ConfigOptionString( + (new_extruder_id >= 0 && new_extruder_id < (int) extruder_variants.size()) ? extruder_variants[new_extruder_id] : std::string())); + } + dyn_config.set_key_value("nozzle_diameter_at_nozzle_id", new ConfigOptionFloats(get_nozzle_diameters_by_nozzle_id(group_result.get()))); + dyn_config.set_key_value("nozzle_volume_types", new ConfigOptionStrings(get_nozzle_volume_types_by_nozzle_id(group_result.get()))); + // Old filament's nozzle-change retract length (filament_retract_length_nc; nil/-1 -> 0). + dyn_config.set_key_value("filament_retract_length_nc", new ConfigOptionFloat( + (old_filament_id != -1) ? (float) m_config.filament_retract_length_nc.get_at(get_filament_config_index(old_filament_id)) : 0.f)); + // Current parked-retract length of the incoming filament's extruder. + dyn_config.set_key_value("new_extruder_retracted_length", + new ConfigOptionFloat(m_writer.get_extruder_retracted_length((int) new_filament_id))); dyn_config.set_key_value("layer_num", new ConfigOptionInt(m_layer_index)); dyn_config.set_key_value("layer_z", new ConfigOptionFloat(print_z)); dyn_config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); @@ -7950,36 +8896,49 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo dyn_config.set_key_value("filament_tower_interface_print_temp", new ConfigOptionInt(interface_temp)); } if (toolchange_temp_override > 0) { - auto temps = m_config.nozzle_temperature.values; + // Rebuild in filament order: the config arrays may carry per-variant columns, while + // these placeholder vectors are consumed indexed by filament id. + size_t num_filaments = m_print->config().filament_type.values.size(); + std::vector temps(num_filaments); + std::vector first_layer_temps(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) { + size_t fi_i = get_filament_config_index((int)i); + temps[i] = m_config.nozzle_temperature.get_at(fi_i); + first_layer_temps[i] = m_config.nozzle_temperature_initial_layer.get_at(fi_i); + } if (new_filament_id < temps.size()) temps[new_filament_id] = toolchange_temp_override; dyn_config.set_key_value("temperature", new ConfigOptionInts(temps)); dyn_config.set_key_value("nozzle_temperature", new ConfigOptionInts(temps)); - - auto first_layer_temps = m_config.nozzle_temperature_initial_layer.values; if (new_filament_id < first_layer_temps.size()) first_layer_temps[new_filament_id] = toolchange_temp_override; dyn_config.set_key_value("first_layer_temperature", new ConfigOptionInts(first_layer_temps)); dyn_config.set_key_value("nozzle_temperature_initial_layer", new ConfigOptionInts(first_layer_temps)); } - auto flush_v_speed = m_print->config().filament_flush_volumetric_speed.values; - auto flush_temps = m_print->config().filament_flush_temp.values; - auto filament_cooling_before_tower = m_print->config().filament_cooling_before_tower.values; - for (size_t idx = 0; idx < flush_v_speed.size(); ++idx) { - if (flush_v_speed[idx] == 0) - flush_v_speed[idx] = m_print->config().filament_max_volumetric_speed.get_at(idx); + { + size_t num_filaments = m_print->config().filament_type.values.size(); + // Fast purge mode uses filament_flush_temp_fast; Default is inert. + bool use_fast_flush = m_print->config().prime_volume_mode == PrimeVolumeMode::pvmFast; + std::vector flush_v_speed(num_filaments); + std::vector flush_temps(num_filaments); + std::vector filament_cooling_before_tower(num_filaments); + for (size_t idx = 0; idx < num_filaments; ++idx) { + size_t fi = get_filament_config_index(idx); + flush_v_speed[idx] = m_print->config().filament_flush_volumetric_speed.get_at(fi); + if (flush_v_speed[idx] == 0) + flush_v_speed[idx] = m_print->config().filament_max_volumetric_speed.get_at(fi); + flush_temps[idx] = use_fast_flush ? m_print->config().filament_flush_temp_fast.get_at(fi) + : m_print->config().filament_flush_temp.get_at(fi); + if (flush_temps[idx] == 0) + flush_temps[idx] = m_print->config().nozzle_temperature_range_high.get_at(idx); + filament_cooling_before_tower[idx] = m_print->config().filament_cooling_before_tower.get_at(fi); + } + std::fill(filament_cooling_before_tower.begin(), filament_cooling_before_tower.end(), 0); + dyn_config.set_key_value("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); + dyn_config.set_key_value("flush_temperatures", new ConfigOptionInts(flush_temps)); + dyn_config.set_key_value("filament_cooling_before_tower", new ConfigOptionFloats(filament_cooling_before_tower)); } - for (size_t idx = 0; idx < flush_temps.size(); ++idx) { - if (flush_temps[idx] == 0) - flush_temps[idx] = m_print->config().nozzle_temperature_range_high.get_at(idx); - } - if (filament_cooling_before_tower.size() < m_print->config().filament_type.values.size()) - filament_cooling_before_tower.resize(m_print->config().filament_type.values.size(), m_print->config().filament_cooling_before_tower.get_at(0)); - std::fill(filament_cooling_before_tower.begin(), filament_cooling_before_tower.end(), 0); - dyn_config.set_key_value("flush_volumetric_speeds", new ConfigOptionFloats(flush_v_speed)); - dyn_config.set_key_value("flush_temperatures", new ConfigOptionInts(flush_temps)); - dyn_config.set_key_value("filament_cooling_before_tower", new ConfigOptionFloats(filament_cooling_before_tower)); dyn_config.set_key_value("flush_length", new ConfigOptionFloat(wipe_length)); int flush_count = std::min(g_max_flush_count, (int)std::round(wipe_volume / g_purge_volume_one_time)); @@ -8036,7 +8995,9 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo //BBS: don't add T[next extruder] if there is no T cmd on filament change //We inform the writer about what is happening, but we may not use the resulting gcode. - std::string toolchange_command = m_writer.toolchange(new_filament_id); + std::string toolchange_command = m_writer.toolchange(new_filament_id, next_nozzle_id); + if (Extruder *fil = m_writer.filament()) + fil->set_config_index((int)get_filament_config_index((int)fil->id())); if (!custom_gcode_changes_tool(toolchange_gcode_parsed, m_writer.toolchange_prefix(), new_filament_id)) gcode += toolchange_command; else { @@ -8045,18 +9006,27 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo // Set the temperature if the wipe tower didn't (not needed for non-single extruder MM) if (m_config.single_extruder_multi_material && !m_config.enable_prime_tower) { - int temp = (m_layer_index <= 0 ? m_config.nozzle_temperature_initial_layer.get_at(new_filament_id) : - m_config.nozzle_temperature.get_at(new_filament_id)); + size_t new_fi = get_filament_config_index(new_filament_id); + int temp = (m_layer_index <= 0 ? m_config.nozzle_temperature_initial_layer.get_at(new_fi) : + m_config.nozzle_temperature.get_at(new_fi)); gcode += m_writer.set_temperature(temp, false); } this->placeholder_parser().set("current_extruder", new_filament_id); - this->placeholder_parser().set("current_hotend", hotend_id_for_gcode_placeholder(m_config, new_extruder_id)); - this->placeholder_parser().set("retraction_distance_when_cut", m_config.retraction_distances_when_cut.get_at(new_filament_id)); - this->placeholder_parser().set("long_retraction_when_cut", m_config.long_retractions_when_cut.get_at(new_filament_id)); - this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(new_filament_id)); - this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(new_filament_id)); + this->placeholder_parser().set("current_hotend", + hotend_id_for_gcode_placeholder(m_config, group_result, (int) new_filament_id, new_extruder_id, m_layer_index)); + // Orca: keep the global current-tool identity coherent for later contexts (see append_tcr). + this->placeholder_parser().set("current_filament_id", (int) new_filament_id); + this->placeholder_parser().set("current_extruder_id", new_extruder_id); + this->placeholder_parser().set("current_nozzle_id", next_nozzle_id); + { + size_t fi = get_filament_config_index(new_filament_id); + this->placeholder_parser().set("retraction_distance_when_cut", m_config.retraction_distances_when_cut.get_at(fi)); + this->placeholder_parser().set("long_retraction_when_cut", m_config.long_retractions_when_cut.get_at(fi)); + this->placeholder_parser().set("retraction_distance_when_ec", m_config.retraction_distances_when_ec.get_at(fi)); + this->placeholder_parser().set("long_retraction_when_ec", m_config.long_retractions_when_ec.get_at(fi)); + } // Append the filament start G-code. @@ -8069,13 +9039,20 @@ std::string GCode::set_extruder(unsigned int new_filament_id, double print_z, bo config.set_key_value("max_layer_z", new ConfigOptionFloat(m_max_layer_z)); config.set_key_value("filament_extruder_id", new ConfigOptionInt(int(new_filament_id))); if (toolchange_temp_override > 0) { - auto temps = m_config.nozzle_temperature.values; + // Rebuild in filament order: the config arrays may carry per-variant columns, while + // these placeholder vectors are consumed indexed by filament id. + size_t num_filaments = m_print->config().filament_type.values.size(); + std::vector temps(num_filaments); + std::vector first_layer_temps(num_filaments); + for (size_t i = 0; i < num_filaments; ++i) { + size_t fi_i = get_filament_config_index((int)i); + temps[i] = m_config.nozzle_temperature.get_at(fi_i); + first_layer_temps[i] = m_config.nozzle_temperature_initial_layer.get_at(fi_i); + } if (new_filament_id < temps.size()) temps[new_filament_id] = toolchange_temp_override; config.set_key_value("temperature", new ConfigOptionInts(temps)); config.set_key_value("nozzle_temperature", new ConfigOptionInts(temps)); - - auto first_layer_temps = m_config.nozzle_temperature_initial_layer.values; if (new_filament_id < first_layer_temps.size()) first_layer_temps[new_filament_id] = toolchange_temp_override; config.set_key_value("first_layer_temperature", new ConfigOptionInts(first_layer_temps)); diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp index 01c253a4fc..e6cf9c914e 100644 --- a/src/libslic3r/GCode.hpp +++ b/src/libslic3r/GCode.hpp @@ -60,15 +60,20 @@ class Wipe { public: bool enable; Polyline path; + + // Orca: struct RetractionValues{ - double retractLengthBeforeWipe; - double retractLengthDuringWipe; + double retraction_length_before_wipe = 0.; + double retraction_length_during_wipe = 0.; + double retraction_length_after_wipe = 0.; }; Wipe() : enable(false) {} bool has_path() const { return !this->path.points.empty(); } void reset_path() { this->path = Polyline(); } std::string wipe(GCode &gcodegen, double length, bool toolchange = false, bool is_last = false); + + // Orca: RetractionValues calculateWipeRetractionLengths(GCode& gcodegen, bool toolchange); }; @@ -252,7 +257,8 @@ public: std::string travel_to(const Point& point, ExtrusionRole role, std::string comment, double z = DBL_MAX); bool needs_retraction(const Polyline& travel, ExtrusionRole role, LiftType& lift_type); std::string retract(bool toolchange = false, bool is_last_retraction = false, LiftType lift_type = LiftType::NormalLift, bool apply_instantly = false, ExtrusionRole role = erNone); - std::string unretract() { return m_writer.unlift() + m_writer.unretract(); } + // extra_retract forwards a PETG pre-extrusion over-extrusion; default 0 -> identical to the plain deretract. + std::string unretract(float extra_retract = 0.f) { return m_writer.unlift() + m_writer.unretract(extra_retract); } std::string set_extruder(unsigned int extruder_id, double print_z, bool by_object=false, int toolchange_temp_override = -1); bool is_BBL_Printer(); WipeTowerType wipe_tower_type(); @@ -263,6 +269,12 @@ public: // append full config to the given string static void append_full_config(const Print& print, std::string& str); + // Per-filament config-slot resolvers for the current layer (m_cur_layer_idx): the filament + // resolver keys filament-indexed arrays, the nozzle resolver keys (extruder x volume-type) + // slot arrays. Both degenerate to filament_id / extruder index on single-volume printers. + size_t get_filament_config_index(int filament_id) const; + size_t get_nozzle_config_index(int filament_id) const; + // Object and support extrusions of the same PrintObject at the same print_z. // public, so that it could be accessed by free helper functions from GCode.cpp struct LayerToPrint @@ -394,6 +406,7 @@ private: void check_placeholder_parser_failed(); size_t cur_extruder_index() const; size_t get_extruder_id(unsigned int filament_id) const; + void update_placeholder_parser_with_variant_params(); void set_last_pos(const Point &pos) { m_last_pos = Point3(pos, 0); m_last_pos_defined = true; } void set_last_pos(const Point3 &pos) { m_last_pos = pos; m_last_pos_defined = true; } @@ -402,6 +415,11 @@ private: std::string preamble(); // BBS std::string change_layer(coordf_t print_z); + // Bedslinger model: derive the Y-axis acceleration limit from the machine force/bed-mass config + // and the mass already printed. Yields the min machine Y acceleration when the A2L config keys are + // unset (i.e. every existing printer), so it is inert for them. + void mass_load_limited_machine_acceleration(const PrintStatistics &curr_print_statistics, const Print &print, + double &y_acceleration_limit_res, double &accumulated_mass_res); // Orca: pass the complete collection of region perimeters to the extrude loop to check whether the wipe before external loop // should be executed std::string extrude_entity(const ExtrusionEntity& entity, @@ -500,6 +518,18 @@ private: std::string extrude_infill(const Print& print, const std::vector& by_region, bool ironing); std::string extrude_support(const ExtrusionEntityCollection& support_fills, const ExtrusionRole support_extrusion_role); + // Farthest-point timelapse: find the extrusion point farthest from camera (0,0) + void compute_farthest_point(const std::vector &layers, int most_used_extruder, + const std::map, unsigned int> &support_filaments); + // Build the per-layer timelapse snapshot g-code (safe-position or, when skip_pos_pick, + // an inline photo at the current head position). Extracted from the former process_layer lambda so the + // per-extrusion farthest-point hook (_extrude) can call it too. Identical to the old lambda when the + // farthest-point subsystem is disabled (skip_pos_pick=false, m_farthest_point_timelapse.enabled=false). + std::string generate_timelapse_gcode(const Print &print, coordf_t print_z, int most_used_extruder, + const std::set *layer_object_label_ids, + const std::vector *printed_objects, + bool skip_pos_pick = false); + // BBS LiftType to_lift_type(ZHopType z_hop_types); @@ -556,6 +586,32 @@ private: AvoidCrossingPerimeters m_avoid_crossing_perimeters; RetractWhenCrossingPerimeters m_retract_when_crossing_perimeters; TimelapsePosPicker m_timelapse_pos_picker; + + // Farthest-point timelapse context. Corexy-only refinement layered on top of the existing + // timelapse_type. All fields default to the inert state; `enabled` is (re)computed each layer in + // process_layer and is false whenever the farthest_point_timelapse config toggle is off, the printer + // is i3 (psI3), or timelapse_type is not traditional — so every shipping printer that does not set the + // toggle is identical to the previous path. + struct FarthestPointTimelapseContext { + // Whether farthest-point timelapse is active for this layer + bool enabled{false}; + // The farthest extrusion point from camera (0,0) in global scaled coordinates (includes plate origin + inst.shift) + Point farthest_point; + // farthest_point converted to mm (gcode coordinate space, includes plate origin) + Vec2d farthest_gcode_pos{0, 0}; + // Extruder index (0-based) that prints the farthest point + int farthest_extruder_id{0}; + // Whether the farthest point is printed by the photo head (most_used_extruder) + bool farthest_is_photo_head{false}; + // Whether inline timelapse gcode has already been inserted on this layer + bool inserted_this_layer{false}; + // The extruder used most on this layer, chosen as the photo head + int most_used_extruder{0}; + // Object labels for the current layer, used when inline timelapse is inserted from extrusion code. + std::set layer_object_label_ids; + }; + FarthestPointTimelapseContext m_farthest_point_timelapse; + bool m_enable_loop_clipping; //resonance avoidance bool m_resonance_avoidance; @@ -595,6 +651,9 @@ private: float m_last_layer_z{ 0.0f }; float m_max_layer_z{ 0.0f }; float m_last_width{ 0.0f }; + // Bedslinger mass model: cumulative printed mass at the previous layer, used to derive + // the current layer mass for the per-layer Y acceleration limit (curr_y_acceleration_limit). + double m_last_layer_accumulated_mass{ 0.0 }; // Always check gcode placeholders when building in debug mode. #if !defined(NDEBUG) @@ -654,12 +713,18 @@ private: int m_start_gcode_filament = -1; std::string m_filament_instances_code; + // Object layer id of the layer being generated; keys the per-filament config-slot + // resolvers. Distinct from m_layer_index (an export progress counter starting at -1). + size_t m_cur_layer_idx{0}; + std::set m_initial_layer_extruders; std::vector> m_sorted_layer_filaments; // BBS int get_bed_temperature(const int extruder_id, const bool is_first_layer, const BedType bed_type) const; int get_highest_bed_temperature(const bool is_first_layer,const Print &print) const; + void update_layer_related_config(int layer_id); + double calc_max_volumetric_speed(const double layer_height, const double line_width, const std::string co_str); std::string _extrude(const ExtrusionPath &path, std::string description = "", double speed = -1); bool _needSAFC(const ExtrusionPath &path); diff --git a/src/libslic3r/GCode/ElegooGCodeProcessorHelper.cpp b/src/libslic3r/GCode/ElegooGCodeProcessorHelper.cpp new file mode 100644 index 0000000000..cac53637a5 --- /dev/null +++ b/src/libslic3r/GCode/ElegooGCodeProcessorHelper.cpp @@ -0,0 +1,190 @@ +#include "GCodeProcessor.hpp" + +#include "libslic3r/libslic3r.h" + +#include +#include +#include +#include + +namespace Slic3r { +namespace { + +bool equals_case_insensitive(std::string_view lhs, std::string_view rhs) +{ + return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin(), [](unsigned char l, unsigned char r) { + return std::tolower(l) == std::tolower(r); + }); +} + +float get_clamped_param(const GCodeReader::GCodeLine& line, char axis, float default_value, float min_value, float max_value) +{ + float value = default_value; + line.has_value(axis, value); + return std::clamp(value, min_value, max_value); +} + +float extrusion_time(float e_length, float feedrate) +{ + return feedrate > 0.0f && e_length > 0.0f ? e_length / feedrate * 60.0f : 0.0f; +} + +float retract_time(float e_length) +{ + static constexpr float retract_feedrate = 1800.0f; + return extrusion_time(std::max(e_length, 0.0f), retract_feedrate); +} + +float s819_time(float e_length, float feedrate) +{ + static constexpr float s819_tail_flush_length = 10.0f; + static constexpr float s819_tail_feedrate = 400.0f; + + const float tail_length = std::min(std::max(e_length, 0.0f), s819_tail_flush_length); + const float main_length = std::max(e_length - tail_length, 0.0f); + return extrusion_time(main_length, feedrate) + extrusion_time(tail_length, s819_tail_feedrate); +} + +float estimate_M6211_time_for_centauri_carbon(const GCodeReader::GCodeLine& line, float length, double current_x, + double current_y) +{ + static constexpr float max_segment_length = 73.0f; + static constexpr float wipe_after_flush_time = 2.8f; + static constexpr float main_feedrate = 500.0f; + static constexpr float tail_feedrate = 400.0f; + static constexpr float travel_feedrate = 5000.0f; + static constexpr double parking_x = 256.0; + static constexpr double parking_y = 0.0; + + const float flush_length = std::clamp(length, 10.0f, 1000.0f); + const float cool_time = get_clamped_param(line, 'P', 5000.0f, 0.0f, 20000.0f) * 0.001f; + const float travel_time = static_cast(std::abs(current_y - parking_y) + std::abs(current_x - parking_x)) / + travel_feedrate * 60.0f; + + // Initial time, including: material change, heating, etc. + float m6211_time = 18.2f + travel_time; + + float remaining_flush_length = std::max(flush_length, 0.0f); + while (remaining_flush_length > 0.0f) { + const float segment_length = std::min(remaining_flush_length, max_segment_length); + remaining_flush_length -= segment_length; + if (segment_length >= max_segment_length) { + // Full segment: 3-phase extrusion (30+35+10=75mm) + retract + m6211_time += extrusion_time(30.0f, main_feedrate) + extrusion_time(35.0f, main_feedrate) + + extrusion_time(10.0f, tail_feedrate) + extrusion_time(2.0f, tail_feedrate) + cool_time + + wipe_after_flush_time; + } else { + // Partial last segment: simple extrude at F500 + retract at F400 + m6211_time += extrusion_time(segment_length, main_feedrate) + extrusion_time(2.0f, tail_feedrate) + cool_time + + wipe_after_flush_time; + } + } + + return m6211_time; +} + +float estimate_M6211_time_for_centauri_carbon_2(const GCodeReader::GCodeLine& line, float length, float new_extruder_temp) +{ + const float flush_length = std::clamp(length, 10.0f, 1000.0f); + const float flush_length_single = get_clamped_param(line, 'K', 75.0f, 10.0f, 300.0f); + const float old_filament_e_feedrate = get_clamped_param(line, 'M', 300.0f, 10.0f, 600.0f); + const float new_filament_e_feedrate = get_clamped_param(line, 'N', 300.0f, 10.0f, 600.0f); + const float cool_time = get_clamped_param(line, 'P', 3000.0f, 0.0f, 20000.0f) * 0.001f; + + // The flush length of the old material, unit: mm + static constexpr float e_flush_dist = 15.0f; + // Wipe time after flush, in seconds + static constexpr float wipe_after_flush_time = 5.0f; + + const float flush_length_after_start = std::max(flush_length - e_flush_dist, 0.0f); + const int flush_times = std::max(1, static_cast(std::ceil(flush_length_after_start / flush_length_single))); + const float flush_length_actual = flush_length_single; + + // Initial time, including: material change, heating, moving, etc. + float m6211_time = 31.0f; + m6211_time += extrusion_time(std::min(e_flush_dist, flush_length), old_filament_e_feedrate); + + const int intermediate_flush_times = flush_times - 1; + const float intermediate_flush_time = s819_time(flush_length_actual, new_filament_e_feedrate) + retract_time(6.0f) + cool_time + + wipe_after_flush_time; + m6211_time += static_cast(intermediate_flush_times) * intermediate_flush_time; + m6211_time += s819_time(flush_length_actual, new_filament_e_feedrate * 0.8f) + retract_time(4.0f) + cool_time + wipe_after_flush_time; + + static constexpr float cooling_rate = 1.36f; + const float r_temp = get_clamped_param(line, 'R', new_extruder_temp + 20.0f, 185.0f, 350.0f); + const float s_temp = get_clamped_param(line, 'S', 250.0f, 185.0f, 350.0f); + + if (s_temp < r_temp) + m6211_time += (r_temp - s_temp) / cooling_rate; + + return m6211_time; +} + +float estimate_M6211_time(const GCodeReader::GCodeLine& line, std::string_view printer_model, float length, float new_extruder_temp, double current_x, double current_y) +{ + if (equals_case_insensitive(printer_model, "Elegoo Centauri Carbon") || equals_case_insensitive(printer_model, "Elegoo Centauri")) { + return estimate_M6211_time_for_centauri_carbon(line, length, current_x, current_y); + } else if (equals_case_insensitive(printer_model, "Elegoo Centauri Carbon 2") || + equals_case_insensitive(printer_model, "Elegoo Centauri 2")) { + return estimate_M6211_time_for_centauri_carbon_2(line, length, new_extruder_temp); + } + return 0.0f; +} + +} // namespace + +void GCodeProcessor::process_elegoo_M6211(const GCodeReader::GCodeLine& line) +{ + float length = 0.0f; + if (!line.has_value('L', length) || length <= 0.0f) + return; + + float t = -1.0f; + if (!line.has_value('T', t) || t < 0.0f) + return; + + const int filament_id = static_cast(std::round(t)); + if (filament_id < 0 || filament_id >= m_result.filaments_count) + return; + + const int extruder_id = m_filament_maps[filament_id]; + + float new_extruder_temp = 0.0f; + if (line.has_value('S', new_extruder_temp)) { + if (extruder_id >= 0 && static_cast(extruder_id) < m_extruder_temps.size()) + m_extruder_temps[static_cast(extruder_id)] = new_extruder_temp; + } + + const float m6211_time = estimate_M6211_time(line, m_printer_model, length, new_extruder_temp, + m_start_position[X], m_start_position[Y]); + const int curr_filament_id = get_filament_id(false); + const bool is_first_extrusion = (curr_filament_id == -1) || (filament_id == curr_filament_id); + + m_time_processor.filament_unload_times = 0; + m_time_processor.filament_load_times = m6211_time; + process_filament_change(filament_id); + + if (extruder_id >= 0 && static_cast(extruder_id) < m_remaining_volume.size()) { + const float remaining_volume = static_cast(extruder_id) < m_nozzle_volume.size() ? + m_nozzle_volume[extruder_id] : + 0.0f; + const float filament_diameter = static_cast(filament_id) < m_result.filament_diameters.size() ? + m_result.filament_diameters[filament_id] : + m_result.filament_diameters.back(); + const float area_filament_cross_section = static_cast(M_PI) * sqr(0.5f * filament_diameter); + const float volume_flushed_filament = area_filament_cross_section * length; + + if (volume_flushed_filament >= remaining_volume) { + if (!is_first_extrusion) + m_used_filaments.update_flush_per_filament(curr_filament_id, remaining_volume); + + m_used_filaments.update_flush_per_filament(filament_id, volume_flushed_filament - remaining_volume); + m_remaining_volume[extruder_id] = 0.0f; + } else { + m_used_filaments.update_flush_per_filament(filament_id, volume_flushed_filament); + m_remaining_volume[extruder_id] -= volume_flushed_filament; + } + } +} + +} // namespace Slic3r diff --git a/src/libslic3r/GCode/GCodeProcessor.cpp b/src/libslic3r/GCode/GCodeProcessor.cpp index 44cb185aec..4691af7e0e 100644 --- a/src/libslic3r/GCode/GCodeProcessor.cpp +++ b/src/libslic3r/GCode/GCodeProcessor.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -110,6 +111,21 @@ const std::string GCodeProcessor::VFlush_End_Tag = " VFLUSH_END"; //Orca: External device purge tag const std::string GCodeProcessor::External_Purge_Tag = " EXTERNAL_PURGE"; +// SKIPPABLE region tags. SKIPTYPE carries a trailing "" payload so it is matched with +// starts_with; START/END are whole-line tags. +const std::string GCodeProcessor::Skippable_Start_Tag = " SKIPPABLE_START"; +const std::string GCodeProcessor::Skippable_End_Tag = " SKIPPABLE_END"; +const std::string GCodeProcessor::Skippable_Type_Tag = " SKIPTYPE: "; + +// Usage-block builder markers. START/END machine-gcode markers are whole-line tags; the +// NOZZLE_CHANGE_* and CP_TOOLCHANGE_WIPE tags carry an OF/NF/ON/NN or CT/FL payload and are +// matched with starts_with. +const std::string GCodeProcessor::Machine_Start_GCode_End_Tag = " MACHINE_START_GCODE_END"; +const std::string GCodeProcessor::Machine_End_GCode_Start_Tag = " MACHINE_END_GCODE_START"; +const std::string GCodeProcessor::Nozzle_Change_Start_Tag = " NOZZLE_CHANGE_START"; +const std::string GCodeProcessor::Nozzle_Change_End_Tag = " NOZZLE_CHANGE_END"; +const std::string GCodeProcessor::Toolchange_Wipe_Tag = " CP_TOOLCHANGE_WIPE"; + const float GCodeProcessor::Wipe_Width = 0.05f; const float GCodeProcessor::Wipe_Height = 0.05f; @@ -469,6 +485,12 @@ void GCodeProcessor::TimeMachine::calculate_time(GCodeProcessorResult& result, P } time += double(block_time); + // Orca: accumulate per-SkipType time spent inside SKIPPABLE regions, folded into this single + // calculate_time write site. Fires fleet-wide (the shipping time_lapse_gcode template stamps + // blocks stTimelapse), but writes only skippable_part_time, which has no g-code-emitting + // reader until the pre-heat injector consumes it, so output is byte-identical. + if (block.skippable_type != SkipType::stNone) + result.skippable_part_time[block.skippable_type] += block.time(); result.moves[block.move_id].time[static_cast(mode)] = block_time; gcode_time.cache += block_time; //BBS @@ -960,6 +982,22 @@ public: } } + // Map a single first-pass (input) line id to its final output line id, using the same + // original->final table synchronize_moves() applies to the moves. The pre-heat injector's + // usage/skippable blocks are keyed on the pre-M73 input line id; this rebases them into the + // output-line-id space the moves and the second pass both use. Sentinel (unsigned)-1 and any + // id with no exact table entry are returned unchanged, matching synchronize_moves' exact-match rule. + unsigned int remap_gcode_id(unsigned int gcode_id) const + { + if (gcode_id == static_cast(-1)) + return gcode_id; + auto it = std::lower_bound(m_gcode_lines_map.begin(), m_gcode_lines_map.end(), static_cast(gcode_id), + [](const std::pair& e, size_t v) { return e.first < v; }); + if (it != m_gcode_lines_map.end() && it->first == static_cast(gcode_id)) + return static_cast(it->second); + return gcode_id; + } + size_t get_size() const { return m_size; } private: @@ -1392,6 +1430,11 @@ void GCodeProcessor::run_post_process() m_result.lines_ends.clear(); // m_result.lines_ends.emplace_back(std::vector()); + // Orca: freshly collect SKIPPABLE ranges each post-process pass. The ranges are stored on the + // member (rather than a local) so the injection pass can consume them, hence the clear here to + // avoid stale ranges on re-invocation. + m_skippable_blocks.clear(); + unsigned int line_id = 0; // Backtrace data for Tx gcode lines const ExportLines::Backtrace backtrace_T = { m_preheat_time, m_preheat_steps }; @@ -1399,6 +1442,161 @@ void GCodeProcessor::run_post_process() // to flush the backtrace cache accordingly float max_backtrace_time = 120.0f; + // First-pass usage-block builder. Reconstructs, from the emitted g-code, which filament/extruder + // is active over each output-line span so the pre-heat injector can locate idle-hotend windows. + // Gated behind m_enable_pre_heating: the byte-frozen fleet (X1/P1/A1/H2S, which never set the + // flag) runs none of this. It is pure data construction — it only fills m_filament_blocks / + // m_extruder_blocks / m_machine_*_gcode_*_line_id and never touches the exported g-code, so even + // the enable_pre_heating fleet stays byte-identical (nothing reads the blocks until the injection + // pass). In practice it also stays empty/degenerate today because no template/code yet emits the + // MACHINE_*_GCODE_* / NOZZLE_CHANGE_* / CP_TOOLCHANGE_WIPE markers it keys off. + m_filament_blocks.clear(); + m_extruder_blocks.clear(); + m_machine_start_gcode_end_line_id = (unsigned int) (-1); + m_machine_end_gcode_start_line_id = (unsigned int) (-1); + // the first use of an extruder emits no nozzle-change tag, so seed a dummy leading block + if (m_enable_pre_heating) + m_extruder_blocks.push_back(ExtruderPreHeating::ExtruderUsageBlcok()); + // Resolve the concrete layer-aware grouping: get_nozzle_id/get_extruder_id are not on the base + // interface. May be null on slicing paths that never populated it, in which case the builder + // degrades to empty blocks (every dereference below is nil-guarded). + auto layered_ngr = std::dynamic_pointer_cast(m_result.nozzle_group_result); + ExtruderPreHeating::ExtruderUsageBlcok temp_construct_block; // constructed, then pushed after init + + // Append a per-filament usage block at a filament change. + auto handle_filament_change = [&](int filament_id, int cur_line_id, int nozzle_id) { + // skip filament changes emitted inside the machine start / end gcode + if (m_machine_start_gcode_end_line_id == (unsigned int) (-1) && (unsigned int) (cur_line_id) < m_machine_start_gcode_end_line_id || + m_machine_end_gcode_start_line_id != (unsigned int) (-1) && (unsigned int) (cur_line_id) > m_machine_end_gcode_start_line_id) + return; + if (!m_filament_blocks.empty()) + m_filament_blocks.back().upper_gcode_id = cur_line_id; + if (nozzle_id == -1 && layered_ngr) + nozzle_id = layered_ngr->get_nozzle_id(filament_id, current_layer_id); + int extruder_id = 0; + if (layered_ngr) { + // Orca: nil-guard the optional nozzle lookup. + if (auto nozzle_info = layered_ngr->get_nozzle_from_id(nozzle_id)) + extruder_id = nozzle_info->extruder_id; + } + m_filament_blocks.emplace_back(filament_id, extruder_id, nozzle_id, cur_line_id, (unsigned int) (-1)); + }; + + // Parse a "; NOZZLE_CHANGE_* OF NF ON NN" line. The get_nozzle_from_id optional + // is nil-guarded here. + auto handle_nozzle_change_line = [&](const std::string& line, int& old_filament, int& next_filament, int& extruder_id, int gcode_id, int& old_nozzle_id, int& new_nozzle_id) -> bool { + std::regex re(R"(OF(\d+)\s+NF(\d+)\s+ON(\d+)\s+NN(\d+))"); + std::smatch match; + if (!std::regex_search(line, match, re)) + return false; + old_filament = std::stoi(match[1]); + next_filament = std::stoi(match[2]); + old_nozzle_id = std::stoi(match[3]); + new_nozzle_id = std::stoi(match[4]); + std::optional nozzle_info; + if (layered_ngr) + nozzle_info = layered_ngr->get_nozzle_from_id(new_nozzle_id); + extruder_id = nozzle_info ? nozzle_info->extruder_id : -1; + return true; + }; + + // Parse a "; CP_TOOLCHANGE_WIPE CT [FL]" line. + auto handle_toolchange_wipe_line = [](const std::string& line, bool& is_contact, bool& is_first_layer) -> bool { + std::regex re(R"(CT(\d)(?:\s+FL(\d))?)"); + std::smatch match; + if (!std::regex_search(line, match, re)) + return false; + is_contact = std::stoi(match[1]) != 0; + is_first_layer = match[2].matched ? std::stoi(match[2]) != 0 : false; + return true; + }; + + // Inspect one output line and update the usage-block state. Called only when m_enable_pre_heating; + // never modifies gcode_line. + auto build_usage_blocks = [&](const std::string& gcode_line, int line_id) { + using GLine = GCodeReader::GCodeLine; + // leading-whitespace count (GCodeReader::skip_whitespaces is private; is_whitespace == space|tab) + size_t skips = 0; + while (skips < gcode_line.size() && (gcode_line[skips] == ' ' || gcode_line[skips] == '\t')) + ++skips; + + // whole-line machine start / end gcode markers + if (gcode_line.size() > 1 && gcode_line.front() == ';') { + std::string_view tag(gcode_line); + while (!tag.empty() && (tag.back() == '\n' || tag.back() == '\r')) + tag.remove_suffix(1); + tag.remove_prefix(1); // strip leading ';' + if (tag == Machine_Start_GCode_End_Tag) { m_machine_start_gcode_end_line_id = line_id; return; } + if (tag == Machine_End_GCode_Start_Tag) { m_machine_end_gcode_start_line_id = line_id; return; } + } + + // filament-change commands: T, ;VT, M1020 S, each optionally " H" + if (GLine::cmd_starts_with(gcode_line, "T")) { + std::istringstream str(gcode_line.substr(skips + 1)); // skip whitespace and 'T' + int fid; + str >> fid; + if (!str.fail() && 0 <= fid && fid < 255) { + int nozzle_id = -1; char param; + while (str >> param) { if (param == 'H') { if (!(str >> nozzle_id)) BOOST_LOG_TRIVIAL(warning) << "Invalid nozzle id format in T command: " << gcode_line; break; } } + handle_filament_change(fid, line_id, nozzle_id); + } + return; + } + if (GLine::cmd_starts_with(gcode_line, ";VT")) { + std::istringstream str(gcode_line.substr(skips + 3)); // skip whitespace and ";VT" + int fid; + str >> fid; + if (!str.fail() && 0 <= fid && fid < 255) { + int nozzle_id = -1; char param; + while (str >> param) { if (param == 'H') { if (!(str >> nozzle_id)) BOOST_LOG_TRIVIAL(warning) << "Invalid nozzle id format in VT command: " << gcode_line; break; } } + handle_filament_change(fid, line_id, nozzle_id); + } + return; + } + if (GLine::cmd_starts_with(gcode_line, "M1020")) { + size_t s_pos = gcode_line.find('S'); + if (s_pos != std::string::npos) { + std::istringstream str(gcode_line.substr(s_pos + 1)); + int fid; + str >> fid; + if (!str.fail() && 0 <= fid && fid < 255) { + int nozzle_id = -1; char param; + while (str >> param) { if (param == 'H') { if (!(str >> nozzle_id)) BOOST_LOG_TRIVIAL(warning) << "Invalid nozzle id format in M1020 command: " << gcode_line; break; } } + handle_filament_change(fid, line_id, nozzle_id); + } + } + return; + } + + // extruder usage blocks are delimited by the NOZZLE_CHANGE_START/END markers + if (GLine::cmd_starts_with(gcode_line, (std::string(";") + Nozzle_Change_Start_Tag).c_str())) { + int prev_filament{-1}, next_filament{-1}, extruder_id{-1}, prev_nozzle_id{-1}, next_nozzle_id{-1}; + handle_nozzle_change_line(gcode_line, prev_filament, next_filament, extruder_id, line_id, prev_nozzle_id, next_nozzle_id); + if (!m_extruder_blocks.empty()) + m_extruder_blocks.back().initialize_step_2(line_id); + return; + } + if (GLine::cmd_starts_with(gcode_line, (std::string(";") + Nozzle_Change_End_Tag).c_str())) { + int prev_filament{-1}, next_filament{-1}, extruder_id{-1}, prev_nozzle_id{-1}, next_nozzle_id{-1}; + handle_nozzle_change_line(gcode_line, prev_filament, next_filament, extruder_id, line_id, prev_nozzle_id, next_nozzle_id); + if (!m_extruder_blocks.empty()) + m_extruder_blocks.back().initialize_step_3(line_id, prev_filament, line_id, prev_nozzle_id); + temp_construct_block.initialize_step_1(extruder_id, line_id, next_filament, next_nozzle_id); + m_extruder_blocks.emplace_back(temp_construct_block); + temp_construct_block.reset(); + return; + } + // CP_TOOLCHANGE_WIPE records whether the upcoming tower wipe contacts the model / is on the + // first layer, which later suppresses pre-cooling before the tower. + if (GLine::cmd_starts_with(gcode_line, (std::string(";") + Toolchange_Wipe_Tag).c_str())) { + bool is_contact = false, is_first_layer = false; + handle_toolchange_wipe_line(gcode_line, is_contact, is_first_layer); + if (!m_extruder_blocks.empty()) + m_extruder_blocks.back().ignore_cooling_before_tower = is_contact || is_first_layer; + return; + } + }; + { // Read the input stream 64kB at a time, extract lines and process them. std::vector buffer(65536 * 10, 0); @@ -1444,7 +1642,22 @@ void GCodeProcessor::run_post_process() tag_line.remove_prefix(1); if (tag_line == reserved_tag(ETags::Layer_Change)) ++current_layer_id; + // Collect [start,end] output-line-id ranges of each SKIPPABLE region for the + // pre-heat injector. The `!empty()` guard on END avoids dereferencing .back() + // on an empty vector. The shipping time_lapse_gcode template emits SKIPPABLE_* + // fleet-wide, so this records ~100 ranges per timelapse-on slice; output stays + // byte-identical because it only records line-ids (comment lines pass through + // unmodified) and nothing reads the ranges until the injection pass. + else if (tag_line == Skippable_Start_Tag) + m_skippable_blocks.emplace_back(line_id, 0); + else if (tag_line == Skippable_End_Tag && !m_skippable_blocks.empty()) + m_skippable_blocks.back().second = line_id; } + // Build the first-pass usage blocks off the raw line (before any placeholder + // replacement/clear below). Gated on m_enable_pre_heating so the byte-frozen fleet + // executes nothing; pure data construction, so the output is untouched regardless. + if (m_enable_pre_heating) + build_usage_blocks(gcode_line, line_id); // replace placeholder lines bool processed = process_placeholders(gcode_line); if (processed) @@ -1488,6 +1701,39 @@ void GCodeProcessor::run_post_process() } } + // Close out the usage blocks after the stream. The trailing filament block runs to the end-gcode + // start; the seeded first extruder block gets its start filled from the first filament, and the + // open last extruder block is completed with the trailing filament/nozzle. Gated + pure data — + // no effect on the exported g-code. + if (m_enable_pre_heating) { + if (!m_filament_blocks.empty()) + m_filament_blocks.back().upper_gcode_id = m_machine_end_gcode_start_line_id; + + if (!m_extruder_blocks.empty()) { + int first_filament = 0; + int last_filament = 0; + if (!m_filament_blocks.empty()) { + first_filament = m_filament_blocks.front().filament_id; + last_filament = m_filament_blocks.back().filament_id; + } + { + int extruder_id = -1; + std::optional nozzle_info; + if (layered_ngr) + nozzle_info = layered_ngr->get_first_nozzle_for_filament(first_filament); + if (nozzle_info) + extruder_id = nozzle_info->extruder_id; + int start_nozzle_id = nozzle_info ? nozzle_info->group_id : -1; + m_extruder_blocks.front().initialize_step_1(extruder_id, m_machine_start_gcode_end_line_id, first_filament, start_nozzle_id); + } + m_extruder_blocks.back().initialize_step_2(m_machine_end_gcode_start_line_id); + int last_nozzle_id = -1; + if (!m_filament_blocks.empty()) + last_nozzle_id = m_filament_blocks.back().nozzle_id; + m_extruder_blocks.back().initialize_step_3(m_machine_end_gcode_start_line_id, last_filament, m_machine_end_gcode_start_line_id, last_nozzle_id); + } + } + export_line.flush(out, m_result, out_path); out.close(); @@ -1496,11 +1742,628 @@ void GCodeProcessor::run_post_process() const std::string result_filename = m_result.filename; export_line.synchronize_moves(m_result); + // Rebase the first-pass usage/skippable blocks + the machine start/end gcode line ids from the + // pre-M73 input-line-id space into the final output-line-id space, so they share one coordinate + // system with the moves (whose gcode_ids synchronize_moves() just rebased) and with the + // second-pass line_id. This is the block-side counterpart to synchronize_moves, which does the + // same rebasing for the moves. Gated on m_enable_pre_heating so the byte-frozen fleet skips it + // entirely; on the flag-true fleet it writes only the (inert) block members, so the emitted + // g-code is unaffected either way. + if (m_enable_pre_heating) { + auto remap = [&export_line](unsigned int& id) { id = export_line.remap_gcode_id(id); }; + for (auto& b : m_filament_blocks) { + remap(b.lower_gcode_id); + remap(b.upper_gcode_id); + } + for (auto& b : m_extruder_blocks) { + remap(b.start_id); + remap(b.end_id); + remap(b.post_extrusion_start_id); + remap(b.post_extrusion_end_id); + } + for (auto& b : m_skippable_blocks) { + remap(b.first); + remap(b.second); + } + remap(m_machine_start_gcode_end_line_id); + remap(m_machine_end_gcode_start_line_id); + } + if (rename_file(out_path, result_filename)) throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + result_filename + '\n' + "Is " + out_path + " locked?" + '\n'); } +// Additive second file-rewrite pass for the pre-heat/pre-cool injector. The single-pass +// run_post_process (M73 / filament stats / ActualSpeedMove / Backtrace / machine_tool_change_time / +// is_final EOF hardening) is left untouched; this pass runs AFTER it, reads the finished g-code back, +// and splices the injector's InsertedLinesMap (keyed on the final output line id) after the matching +// lines, then re-shifts every move's gcode_id by the inserted-line count before it (see +// handle_offsets_of_second_process). It runs only when m_enable_pre_heating — the byte-frozen fleet +// (X1/P1/A1/H2S) never sets the flag, so it never enters this pass. The PreCoolingInjector (below) +// fills the map; when the injector produces no lines (no idle windows / no usage blocks) the map is +// empty and the pass is a byte-for-byte identity rewrite of the finished file. +void GCodeProcessor::run_second_pass_injection() +{ + // The ordered map of M632/M400/M104/M633 lines to splice into the finished g-code, keyed on the + // final output line id. Populated by the PreCoolingInjector below. If the injector produces + // nothing (no idle windows / no usage blocks), the map stays empty and the rewrite below is a + // byte-for-byte identity pass. + TimeProcessor::InsertedLinesMap inserted_operation_lines; + + // The enable_pre_heating orchestration block. Build the injector from the reconciled first-pass + // usage/skippable blocks (now in the final output-line-id space, sharing one coordinate with the + // moves' synchronized gcode_ids) and the per-move time substrate, then have it populate + // inserted_operation_lines. Runs under the same m_enable_pre_heating gate finalize() already + // applied, so the byte-frozen fleet (X1/P1/A1/H2S) never reaches here. + { + // Pick the active time mode (Normal/Stealth) whose move.time[] the injector reads. + int valid_machine_id = 0; + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + if (m_time_processor.machines[i].enabled) { + valid_machine_id = (int) i; + break; + } + } + // Reach the concrete layer-aware grouping (get_nozzle_from_id / is_support_dynamic_nozzle_map + // are not on the base interface). Orca: nil-guard it — on a slicing path that never populated + // the grouping, skip injection → empty map → identity rewrite. The shared_ptr local keeps the + // object alive for the injector's const ref. + auto layered_ngr = std::dynamic_pointer_cast(m_result.nozzle_group_result); + if (layered_ngr) { + constexpr float inject_time_threshold = 0.f; // threshold hardcoded to 0 + // Orca: nozzle temps are stored as float (ExtruderTemps) but the injector signature takes + // std::vector, so convert to int locals that outlive the injector (they are + // int-valued floats — see apply_config). + std::vector filament_nozzle_temps(m_filament_nozzle_temp.begin(), m_filament_nozzle_temp.end()); + std::vector filament_nozzle_temps_initial(m_filament_nozzle_temp_first_layer.begin(), m_filament_nozzle_temp_first_layer.end()); + // filament_max_temperature_drop_when_ec is inert (default {0}, never read by the injector); + // pass the same inert default (the config is registered but unwired). + const std::vector filament_max_temperature_drop_when_ec{ 0.f }; + + // Orca: MoveVertex.time[mode] stores the per-move DURATION (calculate_time: `= block_time`), + // but the injector's algorithm reads move.time[] as CUMULATIVE print time (idle-window gap = + // upper.time - prev(lower).time; heating_start back-solve = upper.time - delta/rate). Build a + // cumulative view of the active mode IN PLACE (prefix-sum in gcode-id/move order — moves are + // sorted by gcode_id), run the injector, then RESTORE the per-move durations so every + // downstream consumer (and the byte output) is unperturbed. Only the single active-mode + // column is touched. + std::vector saved_time; + saved_time.reserve(m_result.moves.size()); + { + float acc = 0.f; + for (auto& mv : m_result.moves) { + saved_time.push_back(mv.time[valid_machine_id]); + acc += mv.time[valid_machine_id]; + mv.time[valid_machine_id] = acc; + } + } + + PreCoolingInjector injector( + m_result.moves, + m_filament_types, + *layered_ngr, + filament_nozzle_temps, + filament_nozzle_temps_initial, + m_physical_extruder_map, + valid_machine_id, + inject_time_threshold, + m_handle_hotend_as_extruder, + m_has_filament_switcher, + m_filament_pre_cooling_temp, + m_hotend_cooling_rate, + m_hotend_heating_rate, + m_skippable_blocks, + m_extruder_max_nozzle_count, + m_filament_preheat_temperature_delta, + filament_max_temperature_drop_when_ec, + m_machine_start_gcode_end_line_id, + m_machine_end_gcode_start_line_id, + m_result.extruder_types, + m_nozzle_diameter); + injector.build_extruder_free_blocks(m_filament_blocks, m_extruder_blocks); + injector.process_pre_cooling_and_heating(inserted_operation_lines); + + // Restore the per-move durations (leave the moves exactly as run_post_process produced them). + for (size_t i = 0; i < m_result.moves.size(); ++i) + m_result.moves[i].time[valid_machine_id] = saved_time[i]; + } + } + + FilePtr in{ boost::nowide::fopen(m_result.filename.c_str(), "rb") }; + if (in.f == nullptr) + throw Slic3r::RuntimeError(std::string("GCode processor pre-heat injection pass failed.\nCannot open file for reading.\n")); + + const std::string out_path = m_result.filename + ".preheat"; + FilePtr out{ boost::nowide::fopen(out_path.c_str(), "wb") }; + if (out.f == nullptr) + throw Slic3r::RuntimeError(std::string("GCode processor pre-heat injection pass failed.\nCannot open file for writing.\n")); + + // The rewrite may shift byte positions (once the injector inserts lines), so rebuild lines_ends from scratch. + // With an empty map the scanned '\n' offsets reproduce the current lines_ends exactly. + m_result.lines_ends.clear(); + size_t out_file_pos = 0; + + auto write_out = [&out, &out_path, this, &out_file_pos](std::string& str) { + if (str.empty()) + return; + fwrite((const void*) str.c_str(), 1, str.length(), out.f); + if (ferror(out.f)) { + out.close(); + boost::nowide::remove(out_path.c_str()); + throw Slic3r::RuntimeError(std::string("GCode processor pre-heat injection pass failed.\nIs the disk full?\n")); + } + for (size_t i = 0; i < str.size(); ++i) { + if (str[i] == '\n') + m_result.lines_ends.emplace_back(out_file_pos + i + 1); + } + out_file_pos += str.size(); + str.clear(); + }; + + // Orca: read/split lines with EOL-preserving semantics (keep the original \r and \n bytes, and + // synthesize no trailing newline). This is required for the empty-map identity: normalizing every + // line ending to "\n" would not be byte-identical if the finished file used \r\n or lacked a + // final newline. + std::string gcode_line; + std::string export_buffer; + unsigned int line_id = 0; + auto op_it = inserted_operation_lines.begin(); + std::vector buffer(65536 * 10, 0); + for (;;) { + size_t cnt_read = ::fread(buffer.data(), 1, buffer.size(), in.f); + if (::ferror(in.f)) + throw Slic3r::RuntimeError(std::string("GCode processor pre-heat injection pass failed.\nError while reading from file.\n")); + bool eof = cnt_read == 0; + auto it = buffer.begin(); + auto it_bufend = buffer.begin() + cnt_read; + while (it != it_bufend || (eof && !gcode_line.empty())) { + bool eol = false; + auto it_end = it; + for (; it_end != it_bufend && !(eol = *it_end == '\r' || *it_end == '\n'); ++it_end); + eol |= eof && it_end == it_bufend; + gcode_line.insert(gcode_line.end(), it, it_end); + it = it_end; + if (it != it_bufend && *it == '\r') + gcode_line += *it++; + if (it != it_bufend && *it == '\n') + gcode_line += *it++; + if (eol) { + ++line_id; + // Splice any injector lines registered at this output line id. They are appended to the + // end of the current line's text (which already carries its EOL), so they land AFTER + // this line. PlaceholderReplace / TimePredict / ExtruderChangePredict are handled in the + // first pass and skipped here. + if (op_it != inserted_operation_lines.end() && line_id == op_it->first) { + for (const auto& elem : op_it->second) { + switch (elem.second) { + case TimeProcessor::InsertLineType::PreCooling: + case TimeProcessor::InsertLineType::PreHeating: + case TimeProcessor::InsertLineType::FilamentChangePredict: + gcode_line += elem.first; + break; + default: + break; + } + } + ++op_it; + } + export_buffer += gcode_line; + gcode_line.clear(); + if (export_buffer.length() >= 65536) + write_out(export_buffer); + } + } + if (eof) + break; + } + write_out(export_buffer); + + out.close(); + in.close(); + + // Re-shift the moves by the inserted-line counts (no-op with an empty map). + handle_offsets_of_second_process(inserted_operation_lines); + + if (rename_file(out_path, m_result.filename)) + throw Slic3r::RuntimeError(std::string("Failed to rename the output G-code file from ") + out_path + " to " + m_result.filename + '\n' + + "Is " + out_path + " locked?" + '\n'); +} + +// Every move whose gcode_id sits at or after an inserted line is pushed down by the running count of +// injector lines inserted before it. +void GCodeProcessor::handle_offsets_of_second_process(const TimeProcessor::InsertedLinesMap& inserted_operation_lines) +{ + int total_offset = 0; + auto iter = inserted_operation_lines.begin(); + for (GCodeProcessorResult::MoveVertex& move : m_result.moves) { + while (iter != inserted_operation_lines.end() && iter->first < move.gcode_id) { + total_offset += static_cast(iter->second.size()); + ++iter; + } + move.gcode_id += total_offset; + } +} + +// The pre-cool / pre-heat injection engine. See the class comment in the header. The methods populate +// a TimeProcessor::InsertedLinesMap (keyed on the final output line id) that run_second_pass_injection +// splices into the finished g-code. + +// Group the free-blocks per extruder; for each, always pre-cool, and pre-heat all-but-the-last; derive +// curr/target temps from the filament nozzle temps +/- filament_preheat_temperature_delta; apply the +// X2D mixed-extruder-type workaround. +void GCodeProcessor::PreCoolingInjector::process_pre_cooling_and_heating(TimeProcessor::InsertedLinesMap& inserted_operation_lines) +{ + bool is_multiple_nozzle = std::any_of(extruder_max_nozzle_count.begin(), extruder_max_nozzle_count.end(), [](auto& elem) { return elem > 1; }); + (void) is_multiple_nozzle; // computed but currently unused here + auto get_nozzle_temp = [this](int filament_id, bool is_first_layer, bool from_or_to, bool consider_preheat_temperature_delta) { + if (filament_id == -1) + return from_or_to ? 140 : 0; // default temp + double temp = (is_first_layer ? filament_nozzle_temps_initial_layer[filament_id] : filament_nozzle_temps[filament_id]); + if (consider_preheat_temperature_delta) + return (int) (temp - filament_preheat_temperature_delta[filament_id]); + else + return (int) (temp); + }; + + // Temporary workaround for X2D: when extruder types are mixed (e.g. DirectDrive + Bowden), + // limit pre-heating target to avoid overshooting on the slower-responding extruder. + bool has_mixed_extruder_types = extruder_types.size() > 1 && + std::adjacent_find(extruder_types.begin(), extruder_types.end(), std::not_equal_to<>()) != extruder_types.end(); + // Temporary workaround for X2D: Use the first nozzle diameter to determine the temp offset: 40 for large nozzles (0.6/0.8), 20 for others + float first_nozzle_dia = nozzle_diameter.empty() ? 0.4 : nozzle_diameter.front(); + float switcher_temp_offset = (first_nozzle_dia >= 0.6 - EPSILON) ? 40.f : 20.f; + + std::map> per_extruder_free_blocks; + + for (auto& block : m_extruder_free_blocks) + per_extruder_free_blocks[block.extruder_id].emplace_back(block); + + for (auto& elem : per_extruder_free_blocks) { + auto& extruder_free_blcoks = elem.second; + for (auto iter = extruder_free_blcoks.begin(); iter != extruder_free_blcoks.end(); ++iter) { + bool is_end = std::next(iter) == extruder_free_blcoks.end(); + bool apply_pre_cooling = true; + bool apply_pre_heating = is_end ? false : true; + float curr_temp = get_nozzle_temp(iter->last_filament_id, false, true, false); + float target_temp = get_nozzle_temp(iter->next_filament_id, false, false, !iter->ignore_cooling_before_tower); + // X2D temporary workaround: only apply temp offset when extruder types are mixed + if (has_filament_switcher && has_mixed_extruder_types && apply_pre_heating) { + float print_temp = get_nozzle_temp(iter->next_filament_id, false, false, false); + target_temp = std::min(target_temp, print_temp - switcher_temp_offset); + } + inject_cooling_heating_command(inserted_operation_lines, *iter, curr_temp, target_temp, apply_pre_cooling, apply_pre_heating); + } + } +} + +// A single extruder-usage block (or none) means the print stays on one extruder, so the idle windows +// are between per-filament usages; otherwise the print switches extruders and the idle windows are +// between per-extruder usages. +void GCodeProcessor::PreCoolingInjector::build_extruder_free_blocks(const std::vector& filament_usage_blocks, const std::vector& extruder_usage_blocks) +{ + if (extruder_usage_blocks.size() <= 1) + build_by_filament_blocks(filament_usage_blocks); + else + build_by_extruder_blocks(extruder_usage_blocks); +} + +// The core injector. Measures the idle-window duration from move.time[valid_machine_id], bails if it is +// below the threshold, and emits pre-cool M104 at the window start and pre-heat M104 (relocated out of +// SKIPPABLE blocks) at the back-solved heating-start move. +void GCodeProcessor::PreCoolingInjector::inject_cooling_heating_command(TimeProcessor::InsertedLinesMap& inserted_operation_lines, const ExtruderFreeBlock& block, float curr_temp, float target_temp, bool pre_cooling, bool pre_heating) +{ + auto get_valid_extruder_id = [&](int last_nozzle_id) { + auto nozzle_opt = nozzle_group_result.get_nozzle_from_id(last_nozzle_id); + return nozzle_opt ? nozzle_opt->extruder_id : 0; + }; + + auto is_pre_cooling_valid = [&nozzle_temps = this->filament_nozzle_temps, &pre_cooling_temps = this->filament_pre_cooling_temps](int idx) -> bool { + if (idx < 0) + return false; + return pre_cooling_temps[idx] > 0 && pre_cooling_temps[idx] < nozzle_temps[idx]; + }; + + auto get_partial_free_cooling_thres = [&](int idx) -> float { + if (idx < 0) + return 30.f; + float temp_in_tower = filament_nozzle_temps[idx]; + return temp_in_tower - (float) (filament_pre_cooling_temps[idx]); + }; + + auto gcode_move_comp = [](const GCodeProcessorResult::MoveVertex& a, unsigned int gcode_id) { + return a.gcode_id < gcode_id; + }; + + auto find_skip_block_end = [&skippable_blocks = this->skippable_blocks](unsigned int gcode_id) -> unsigned int { + auto it = std::upper_bound( + skippable_blocks.begin(), skippable_blocks.end(), gcode_id, + [](unsigned int id, const std::pair& block) { return id < block.first; }); + if (it != skippable_blocks.begin()) { + auto candidate = std::prev(it); + if (gcode_id >= candidate->first && gcode_id <= candidate->second) + return candidate->second; + } + return 0; + }; + + auto find_skip_block_start = [&skippable_blocks = this->skippable_blocks](unsigned int gcode_id) -> unsigned int { + auto it = std::upper_bound( + skippable_blocks.begin(), skippable_blocks.end(), gcode_id, + [](unsigned int id, const std::pair& block) { return id < block.first; }); + if (it != skippable_blocks.begin()) { + auto candidate = std::prev(it); + if (gcode_id >= candidate->first && gcode_id <= candidate->second) + return candidate->first; + } + return 0; + }; + + auto adjust_iter = [&](std::vector::const_iterator iter, + const std::vector::const_iterator& begin, + const std::vector::const_iterator& end, + bool forward) -> std::vector::const_iterator { + if (forward) { + while (iter != end) { + unsigned current_id = iter->gcode_id; + unsigned skip_block_end = find_skip_block_end(current_id); + if (skip_block_end == 0) + break; + iter = std::lower_bound(iter, end, skip_block_end + 1, gcode_move_comp); + } + } else { + while (iter != begin) { + unsigned current_id = iter->gcode_id; + unsigned skip_block_start = find_skip_block_start(current_id); + if (skip_block_start == 0) + break; + auto new_iter = std::lower_bound(begin, iter, skip_block_start, gcode_move_comp); + if (new_iter == begin) + break; + iter = std::prev(new_iter); + } + } + return iter; + }; + + if (!pre_cooling && !pre_heating && block.free_upper_gcode_id <= block.free_lower_gcode_id) + return; + + auto move_iter_lower = std::lower_bound(moves.begin(), moves.end(), block.free_lower_gcode_id, gcode_move_comp); + auto move_iter_upper = std::lower_bound(moves.begin(), moves.end(), block.free_upper_gcode_id, gcode_move_comp); // closed iter + + if (move_iter_lower == moves.end() || move_iter_upper == moves.begin()) + return; + --move_iter_upper; + float complete_free_time_gap = 0; // time of complete free + if (move_iter_lower == moves.begin()) + complete_free_time_gap = move_iter_upper->time[valid_machine_id]; + else + complete_free_time_gap = move_iter_upper->time[valid_machine_id] - std::prev(move_iter_lower)->time[valid_machine_id]; + + auto partial_free_move_lower = std::lower_bound(moves.begin(), moves.end(), block.partial_free_lower_id, gcode_move_comp); + auto partial_free_move_upper = std::lower_bound(moves.begin(), moves.end(), block.partial_free_upper_id, gcode_move_comp); // closed iter + if (partial_free_move_lower == moves.end() || partial_free_move_upper == moves.begin()) + return; + --partial_free_move_upper; + float partial_free_time_gap = 0; // time of partial free + if (partial_free_move_lower == moves.begin()) + partial_free_time_gap = partial_free_move_upper->time[valid_machine_id]; + else + partial_free_time_gap = partial_free_move_upper->time[valid_machine_id] - std::prev(partial_free_move_lower)->time[valid_machine_id]; + + if (move_iter_lower >= move_iter_upper) + return; + + bool apply_cooling_when_partial_free = is_pre_cooling_valid(block.last_filament_id) && pre_cooling; + + if (apply_cooling_when_partial_free && partial_free_time_gap + complete_free_time_gap < inject_time_threshold) + return; + + if (!apply_cooling_when_partial_free && complete_free_time_gap < inject_time_threshold) + return; + + int extruder_id = get_valid_extruder_id(block.last_nozzle_id); + float ext_heating_rate = heating_rate[extruder_id]; + float ext_cooling_rate = cooling_rate[extruder_id]; + + auto add_M104_lines = [&](int gcode_id, int target_extruder, int target_temp, int target_filament, bool skippable, int next_filament_idx, int next_nozzle_id, TimeProcessor::InsertLineType type, const std::string& comment = std::string()) { + auto format_line_M104 = [&](int target_extruder, int target_temp, int target_filament, bool skippable, int next_filament_idx, int next_nozzle_id, const std::string& comment = std::string()) -> std::vector { + std::vector buffer; + if (skippable) { + const bool support_dynamic_nozzle_map = this->nozzle_group_result.is_support_dynamic_nozzle_map(); + std::string m632_line = "M632 S" + std::to_string(next_filament_idx); + if (support_dynamic_nozzle_map) + m632_line += " H" + std::to_string(next_nozzle_id); + if (extruder_max_nozzle_count[target_extruder] > 1) + m632_line += " N R"; + m632_line += " W\n"; + buffer.emplace_back(std::move(m632_line)); + } + buffer.emplace_back("M400\n"); + std::string M104_line = "M104"; + if (handle_hotend_as_extruder) { + M104_line += (" I" + std::to_string(target_filament == -1 ? next_filament_idx : target_filament)); + } else if (target_extruder != -1) { + M104_line += (" T" + std::to_string(physical_extruder_map[target_extruder])); + } + + M104_line += " S" + std::to_string(target_temp); + M104_line += " N0"; // N0 means the gcode is generated by slicer + + if (!comment.empty()) + M104_line += " ;" + comment; + M104_line += '\n'; + + buffer.emplace_back(M104_line); + + if (skippable) + buffer.emplace_back("M633\n"); + + return buffer; + }; + + std::vector line_buf = format_line_M104(target_extruder, target_temp, target_filament, skippable, next_filament_idx, next_nozzle_id, comment); + for (auto& line : line_buf) + inserted_operation_lines[gcode_id].emplace_back(line, type); + }; + + constexpr float room_temperature = 25.f; + + if (apply_cooling_when_partial_free) { + float max_cooling_temp = std::min(curr_temp, std::min(get_partial_free_cooling_thres(block.last_filament_id), partial_free_time_gap * ext_cooling_rate)); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": partial cooling for %1% %2%") % max_cooling_temp % curr_temp; + curr_temp = std::max(room_temperature, curr_temp - max_cooling_temp); // set the temperature after doing cooling when post-extruding + add_M104_lines(block.partial_free_lower_id, extruder_id, curr_temp, block.last_filament_id, false, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreCooling, "Multi extruder pre cooling in post extrusion"); + } + + if (pre_cooling && !pre_heating) { + // only perform cooling + if (target_temp >= curr_temp) + return; + int clamped_target = std::max((int) room_temperature, (int) target_temp); + add_M104_lines(block.free_lower_gcode_id, extruder_id, clamped_target, block.last_filament_id, false, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreCooling, "Multi extruder pre cooling"); + return; + } + if (!pre_cooling && pre_heating) { + // only perform heating + if (target_temp <= curr_temp) + return; + float heating_start_time = move_iter_upper->time[valid_machine_id] - (target_temp - curr_temp) / ext_heating_rate; + auto heating_move_iter = std::upper_bound(move_iter_lower, move_iter_upper + 1, heating_start_time, [valid_machine_id = this->valid_machine_id](float time, const GCodeProcessorResult::MoveVertex& a) { return time < a.time[valid_machine_id]; }); + if (heating_move_iter == move_iter_lower) { + add_M104_lines(block.free_lower_gcode_id, extruder_id, target_temp, block.next_filament_id, true, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreHeating, "Multi extruder pre heating"); + } else { + --heating_move_iter; + heating_move_iter = adjust_iter(heating_move_iter, move_iter_lower, move_iter_upper, false); + add_M104_lines(heating_move_iter->gcode_id, extruder_id, target_temp, block.next_filament_id, true, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreHeating, "Multi extruder pre heating"); + } + return; + } + // perform cooling first and then perform heating + float mid_temp = std::max(room_temperature, (curr_temp * ext_heating_rate + target_temp * ext_cooling_rate - complete_free_time_gap * ext_cooling_rate * ext_heating_rate) / (ext_cooling_rate + ext_heating_rate)); + float heating_temp = target_temp - mid_temp; + float heating_start_time = move_iter_upper->time[valid_machine_id] - heating_temp / ext_heating_rate; + auto heating_move_iter = std::upper_bound(move_iter_lower, move_iter_upper + 1, heating_start_time, [valid_machine_id = this->valid_machine_id](float time, const GCodeProcessorResult::MoveVertex& a) { return time < a.time[valid_machine_id]; }); + if (heating_move_iter == move_iter_lower) + return; + --heating_move_iter; + heating_move_iter = adjust_iter(heating_move_iter, move_iter_lower, move_iter_upper, false); + + // get the insert pos of heat cmd and recalculate time gap and delta temp + float real_cooling_time = heating_move_iter->time[valid_machine_id] - move_iter_lower->time[valid_machine_id]; + int real_delta_temp = std::min((int) (real_cooling_time * ext_cooling_rate), (int) curr_temp); + if (real_delta_temp == 0) + return; + int cooling_temp = std::max((int) room_temperature, (int) curr_temp - real_delta_temp); + add_M104_lines(block.free_lower_gcode_id, extruder_id, cooling_temp, block.last_filament_id, false, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreCooling, "Multi extruder pre cooling"); + add_M104_lines(heating_move_iter->gcode_id, extruder_id, target_temp, block.next_filament_id, true, block.next_filament_id, block.next_nozzle_id, TimeProcessor::InsertLineType::PreHeating, "Multi extruder pre heating"); +} + +// Single-extruder / A2L path. Idle windows are the gaps between consecutive per-filament usages on the +// same extruder; ignore_cooling_before_tower is forced true (pre-cooling before the tower is handled by +// the wipe-tower template, not the injector). +void GCodeProcessor::PreCoolingInjector::build_by_filament_blocks(const std::vector& filament_usage_blocks_) +{ + m_extruder_free_blocks.clear(); + + std::map> per_extruder_usage_blocks; + for (auto& block : filament_usage_blocks_) { + per_extruder_usage_blocks[block.extruder_id].emplace_back(block); + } + ExtruderPreHeating::FilamentUsageBlock start_filament_block(-1, -1, -1, 0, machine_start_gcode_end_id); + ExtruderPreHeating::FilamentUsageBlock end_filament_block(-1, -1, -1, machine_end_gcode_start_id, std::numeric_limits::max()); + + for (auto& elem : per_extruder_usage_blocks) { + auto& blocks = elem.second; + blocks.insert(blocks.begin(), start_filament_block); + blocks.emplace_back(end_filament_block); + } + + for (auto& elem : per_extruder_usage_blocks) { + size_t extruder_id = elem.first; + const auto& filament_blocks = elem.second; + + for (auto iter = filament_blocks.begin(); iter < filament_blocks.end(); ++iter) { + auto niter = std::next(iter); + if (niter == filament_blocks.end()) + break; + ExtruderFreeBlock block; + block.free_lower_gcode_id = iter->upper_gcode_id; + block.last_filament_id = iter->filament_id; + block.last_nozzle_id = iter->nozzle_id; + block.free_upper_gcode_id = niter->lower_gcode_id; + block.next_filament_id = niter->filament_id; + block.next_nozzle_id = niter->nozzle_id; + if (block.last_nozzle_id == -1) + block.last_nozzle_id = block.next_nozzle_id; + block.extruder_id = extruder_id; + block.partial_free_lower_id = block.free_lower_gcode_id; + block.partial_free_upper_id = block.free_lower_gcode_id; + m_extruder_free_blocks.emplace_back(block); + } + } + std::for_each(m_extruder_free_blocks.begin(), m_extruder_free_blocks.end(), [](ExtruderFreeBlock& block) { block.ignore_cooling_before_tower = true; }); + sort(m_extruder_free_blocks.begin(), m_extruder_free_blocks.end(), [](const auto& a, const auto& b) { + return a.free_lower_gcode_id < b.free_lower_gcode_id || (a.free_lower_gcode_id == b.free_lower_gcode_id && a.free_upper_gcode_id < b.free_upper_gcode_id); + }); +} + +// Multi-extruder path. Idle windows are the gaps between consecutive per-extruder usages, with +// post-extrusion partial-free sub-ranges (the tower ramming region). +void GCodeProcessor::PreCoolingInjector::build_by_extruder_blocks(const std::vector& extruder_usage_blocks_) +{ + m_extruder_free_blocks.clear(); + std::map> per_extruder_usage_blocks; + for (auto& block : extruder_usage_blocks_) + per_extruder_usage_blocks[block.extruder_id].emplace_back(block); + + for (auto& elem : per_extruder_usage_blocks) { + size_t extruder_id = elem.first; + auto& blocks = elem.second; + ExtruderPreHeating::ExtruderUsageBlcok start_filament_block; + start_filament_block.initialize_step_1(extruder_id, 0, -1, -1); + start_filament_block.initialize_step_2(machine_start_gcode_end_id); + start_filament_block.initialize_step_3(machine_start_gcode_end_id, -1, machine_start_gcode_end_id, -1); + + ExtruderPreHeating::ExtruderUsageBlcok end_filament_block; + end_filament_block.initialize_step_1(extruder_id, machine_end_gcode_start_id, -1, -1); + end_filament_block.initialize_step_2(std::numeric_limits::max()); + end_filament_block.initialize_step_3(std::numeric_limits::max(), -1, std::numeric_limits::max(), -1); + + blocks.insert(blocks.begin(), start_filament_block); + blocks.emplace_back(end_filament_block); + } + + for (auto& elem : per_extruder_usage_blocks) { + size_t extruder_id = elem.first; + const auto& extruder_usage_blocks = elem.second; + for (auto iter = extruder_usage_blocks.begin(); iter != extruder_usage_blocks.end(); ++iter) { + auto niter = std::next(iter); + if (niter == extruder_usage_blocks.end()) + break; + ExtruderFreeBlock block; + block.free_lower_gcode_id = iter->end_id; + block.last_filament_id = iter->end_filament; + block.last_nozzle_id = iter->end_nozzle_id; + block.free_upper_gcode_id = niter->start_id; + block.next_filament_id = niter->start_filament; + block.next_nozzle_id = niter->start_nozzle_id; + if (block.last_nozzle_id == -1) + block.last_nozzle_id = block.next_nozzle_id; + block.extruder_id = extruder_id; + block.partial_free_lower_id = iter->post_extrusion_start_id; + block.partial_free_upper_id = iter->post_extrusion_end_id; + block.ignore_cooling_before_tower = niter->ignore_cooling_before_tower; + m_extruder_free_blocks.emplace_back(block); + } + } + + sort(m_extruder_free_blocks.begin(), m_extruder_free_blocks.end(), [](const auto& a, const auto& b) { + return a.free_lower_gcode_id < b.free_lower_gcode_id || (a.free_lower_gcode_id == b.free_lower_gcode_id && a.free_upper_gcode_id < b.free_upper_gcode_id); + }); +} + void GCodeProcessor::UsedFilaments::reset() { color_change_cache = 0.0f; @@ -1681,6 +2544,15 @@ void GCodeProcessorResult::reset() { optimal_assignment.clear(); filament_change_count_map.clear(); warnings.clear(); + // keep the grouping-result field default-empty across resets. + nozzle_group_result.reset(); + // per-extruder hotend types (pre-heat injector input); repopulated by apply_config. + extruder_types.clear(); + // machine-slot layout of the per-variant printer arrays; repopulated by apply_config. + printer_extruder_variant.clear(); + printer_extruder_id.clear(); + // SKIPPABLE per-type accumulated time. + skippable_part_time.clear(); //BBS: add mutex for protection of gcode result unlock(); @@ -1839,7 +2711,8 @@ void GCodeProcessor::register_commands() {"VM104", [this](const GCodeReader::GCodeLine& line) { process_VM104(line); }}, {"VM109", [this](const GCodeReader::GCodeLine& line) { process_VM109(line); }}, {"M622", [this](const GCodeReader::GCodeLine& line) { process_M622(line);}}, - {"M623", [this](const GCodeReader::GCodeLine& line) { process_M623(line);}} + {"M623", [this](const GCodeReader::GCodeLine& line) { process_M623(line);}}, + {"M6211", [this](const GCodeReader::GCodeLine& line) { process_M6211(line); }} }; std::unordered_setearly_quit_commands = { @@ -1863,6 +2736,12 @@ void GCodeProcessor::register_commands() } } +void GCodeProcessor::process_M6211(const GCodeReader::GCodeLine& line) +{ + if (boost::algorithm::istarts_with(m_printer_model, "elegoo")) + process_elegoo_M6211(line); +} + bool GCodeProcessor::check_multi_extruder_gcode_valid(const int extruder_size, const Pointfs plate_printable_area, const double plate_printable_height, @@ -2027,6 +2906,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_parser.apply_config(config); m_flavor = config.gcode_flavor; + m_printer_model = config.printer_model.value; m_single_extruder_multi_material = config.single_extruder_multi_material; @@ -2048,6 +2928,28 @@ void GCodeProcessor::apply_config(const PrintConfig& config) m_nozzle_volume[idx] = config.nozzle_volume.values[idx]; m_physical_extruder_map = config.physical_extruder_map.values; + // Multi-nozzle context state, consumed by the multi-nozzle time model and pre-heat injector. + m_extruder_max_nozzle_count = config.extruder_max_nozzle_count.values; + + // Pre-heat / pre-cool injector estimator inputs. Gated on enable_pre_heating; the injector + // side-pass that consumes them runs later in run_second_pass_injection. has_filament_switcher is + // read defensively because it is registered as a ConfigDef only, not a static PrintConfig member. + m_filament_types.resize(filament_count); + for (size_t idx = 0; idx < filament_count; ++idx) + m_filament_types[idx] = config.filament_type.get_at(idx); + m_nozzle_diameter = config.nozzle_diameter.values; + m_hotend_cooling_rate = config.hotend_cooling_rate.values; + m_hotend_heating_rate = config.hotend_heating_rate.values; + m_filament_pre_cooling_temp = config.filament_pre_cooling_temperature.values; + m_filament_preheat_temperature_delta = config.filament_preheat_temperature_delta.values; + m_enable_pre_heating = config.enable_pre_heating.value; + if (const ConfigOptionBool* has_switcher = config.option("has_filament_switcher")) + m_has_filament_switcher = has_switcher->value; + m_result.extruder_types.resize(config.extruder_type.values.size()); + for (size_t idx = 0; idx < config.extruder_type.values.size(); ++idx) + m_result.extruder_types[idx] = static_cast(config.extruder_type.values[idx]); + m_result.printer_extruder_variant = config.printer_extruder_variant.values; + m_result.printer_extruder_id = config.printer_extruder_id.values; m_extruder_offsets.resize(filament_count); m_extruder_colors.resize(filament_count); @@ -2072,6 +2974,8 @@ void GCodeProcessor::apply_config(const PrintConfig& config) for (size_t i = 0; i < filament_count; ++ i) { m_extruder_offsets[i] = to_3d(config.extruder_offset.get_at(filament_map[i] - 1).cast().eval(), 0.f); m_extruder_colors[i] = static_cast(i); + // Orca: pre-heat bookkeeping reads the filament's first per-variant column by design; + // it feeds estimation-side heat-up modelling only, never the emitted commands. m_filament_nozzle_temp_first_layer[i] = static_cast(config.nozzle_temperature_initial_layer.get_at(i)); m_filament_nozzle_temp[i] = static_cast(config.nozzle_temperature.get_at(i)); if (m_filament_nozzle_temp[i] == 0) { @@ -2176,6 +3080,66 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) m_physical_extruder_map = physical_extruder_map->values; } + // Multi-nozzle context state, consumed by the multi-nozzle time model and pre-heat injector. + const ConfigOptionIntsNullable* extruder_max_nozzle_count = config.option("extruder_max_nozzle_count"); + if (extruder_max_nozzle_count != nullptr) { + m_extruder_max_nozzle_count = extruder_max_nozzle_count->values; + } + + // Pre-heat / pre-cool injector estimator inputs. Gated on enable_pre_heating; consumed later by the + // injector side-pass. handle_hotend_as_extruder is read only in this overload; nozzle_diameter uses + // the non-nullable ConfigOptionFloats type. + const ConfigOptionFloatsNullable* hotend_cooling_rate = config.option("hotend_cooling_rate"); + if (hotend_cooling_rate != nullptr) + m_hotend_cooling_rate = hotend_cooling_rate->values; + + const ConfigOptionFloatsNullable* hotend_heating_rate = config.option("hotend_heating_rate"); + if (hotend_heating_rate != nullptr) + m_hotend_heating_rate = hotend_heating_rate->values; + + const ConfigOptionIntsNullable* filament_pre_cooling_temperature = config.option("filament_pre_cooling_temperature"); + if (filament_pre_cooling_temperature != nullptr) + m_filament_pre_cooling_temp = filament_pre_cooling_temperature->values; + + const ConfigOptionFloatsNullable* filament_preheat_temperature_delta = config.option("filament_preheat_temperature_delta"); + if (filament_preheat_temperature_delta != nullptr) + m_filament_preheat_temperature_delta = filament_preheat_temperature_delta->values; + + const ConfigOptionBool* enable_pre_heating = config.option("enable_pre_heating"); + if (enable_pre_heating != nullptr) + m_enable_pre_heating = enable_pre_heating->value; + + const ConfigOptionBool* handle_hotend_as_extruder = config.option("handle_hotend_as_extruder"); + if (handle_hotend_as_extruder != nullptr) + m_handle_hotend_as_extruder = handle_hotend_as_extruder->value; + + const ConfigOptionBool* has_filament_switcher = config.option("has_filament_switcher"); + if (has_filament_switcher != nullptr) + m_has_filament_switcher = has_filament_switcher->value; + + const ConfigOptionFloats* nozzle_diameter = config.option("nozzle_diameter"); + if (nozzle_diameter != nullptr) + m_nozzle_diameter = nozzle_diameter->values; + + const ConfigOptionStrings* filament_type = config.option("filament_type"); + if (filament_type != nullptr) { + m_filament_types.resize(filament_type->size()); + for (size_t idx = 0; idx < filament_type->size(); ++idx) + m_filament_types[idx] = filament_type->get_at(idx); + } + + const ConfigOptionEnumsGeneric* extruder_type = config.option("extruder_type"); + if (extruder_type != nullptr) { + m_result.extruder_types.resize(extruder_type->values.size()); + for (size_t idx = 0; idx < extruder_type->values.size(); ++idx) + m_result.extruder_types[idx] = static_cast(extruder_type->values[idx]); + } + + if (const ConfigOptionStrings* pe_variant = config.option("printer_extruder_variant")) + m_result.printer_extruder_variant = pe_variant->values; + if (const ConfigOptionInts* pe_id = config.option("printer_extruder_id")) + m_result.printer_extruder_id = pe_id->values; + const ConfigOptionEnumsGenericNullable* nozzle_type = config.option("nozzle_type"); if (nozzle_type != nullptr) { m_result.nozzle_type.resize(nozzle_type->size()); @@ -2213,6 +3177,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) if (printer_settings_id != nullptr) m_result.settings_ids.printer = printer_settings_id->value; + const ConfigOptionString* printer_model = config.option("printer_model"); + if (printer_model != nullptr) + m_printer_model = printer_model->value; + // BBS m_result.filaments_count = config.option("filament_diameter")->values.size(); @@ -2484,6 +3452,13 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config) const ConfigOptionFloat* z_offset = config.option("z_offset"); if (z_offset != nullptr) m_z_offset = z_offset->value; + + // Reprocessing an existing g-code (from-previous reload / imported g-code) reaches apply_config + // through this DynamicPrintConfig overload; rebuild the per-filament nozzle grouping onto the + // result so the multi-nozzle device GUI can map filaments to physical nozzles. The normal + // streaming export uses the PrintConfig overload and hands the live grouping over separately, so + // it is intentionally not touched here. + ensure_nozzle_group_result(static_cast(m_result.filaments_count)); } void GCodeProcessor::enable_stealth_time_estimator(bool enabled) @@ -2508,6 +3483,15 @@ void GCodeProcessor::reset() m_flushing = false; m_virtual_flushing = false; m_wipe_tower = false; + // reset SKIPPABLE tracking + the collected ranges (stored on the member; see run_post_process). + m_skippable = false; + m_skippable_type = SkipType::stNone; + m_skippable_blocks.clear(); + // reset the first-pass usage-block state (rebuilt each run_post_process). + m_filament_blocks.clear(); + m_extruder_blocks.clear(); + m_machine_start_gcode_end_line_id = (unsigned int) (-1); + m_machine_end_gcode_start_line_id = (unsigned int) (-1); m_remaining_volume = std::vector(MAXIMUM_EXTRUDER_NUMBER, 0.f); m_line_id = 0; @@ -2527,6 +3511,12 @@ void GCodeProcessor::reset() m_filament_id = std::vector(MAXIMUM_EXTRUDER_NUMBER, static_cast(-1)); m_last_filament_id = std::vector(MAXIMUM_EXTRUDER_NUMBER, static_cast(-1)); m_extruder_id = static_cast(-1); + // clear the multi-nozzle occupancy tracker between slices (the richer hotend-change model's only + // mutable state). Inert for the single-nozzle fleet (never populated). + m_nozzle_status_recorder = MultiNozzleUtils::NozzleStatusRecorder{}; + // drop the slot-resolution context and its cached slot; re-seeded per export. + m_nozzle_group_result.reset(); + m_machine_config_idx = 0; m_extruder_colors.resize(MIN_EXTRUDERS_COUNT); for (size_t i = 0; i < MIN_EXTRUDERS_COUNT; ++i) { m_extruder_colors[i] = static_cast(i); @@ -2537,6 +3527,18 @@ void GCodeProcessor::reset() } m_physical_extruder_map.clear(); + m_extruder_max_nozzle_count = { 1 }; + + // reset pre-heat / pre-cool injector estimator inputs to defaults. Repopulated by apply_config + // each slice. + m_filament_types.clear(); + m_nozzle_diameter.clear(); + m_hotend_cooling_rate = m_hotend_heating_rate = { 2.f }; + m_filament_pre_cooling_temp = { 0 }; + m_filament_preheat_temperature_delta.clear(); + m_enable_pre_heating = false; + m_handle_hotend_as_extruder = false; + m_has_filament_switcher = false; m_highest_bed_temp = 0; @@ -2714,6 +3716,12 @@ void GCodeProcessor::finalize(bool post_process) if (post_process){ run_post_process(); + // Additive pre-heat/pre-cool injection second pass. Gated on m_enable_pre_heating so the + // byte-frozen fleet (X1/P1/A1/H2S) never enters it. When the injector produces no lines the + // InsertedLinesMap is empty, so this is a byte-for-byte identity rewrite; it exercises the + // merge/offset machinery on the multi-nozzle fleet (H2D/X2D/H2D-Pro/H2C). + if (m_enable_pre_heating) + run_second_pass_injection(); } //BBS: update slice warning update_slice_warnings(); @@ -3166,6 +4174,29 @@ void GCodeProcessor::process_tags(const std::string_view comment, bool producers return; } + // SKIPPABLE region tags. Mark the current section so its time blocks are stamped with the skip + // type. The shipping time_lapse_gcode template emits these tags fleet-wide, so this parse fires on + // essentially every slice (m_skippable → true, m_skippable_type → stTimelapse); it only sets + // internal state and early-returns, so the output is byte-identical until the injector reads the + // stamps. + if (boost::starts_with(comment, GCodeProcessor::Skippable_Start_Tag)) { + m_skippable = true; + return; + } + + if (boost::starts_with(comment, GCodeProcessor::Skippable_End_Tag)) { + m_skippable = false; + m_skippable_type = SkipType::stNone; + return; + } + + // skippable type + if (boost::starts_with(comment, GCodeProcessor::Skippable_Type_Tag)) { + std::string_view type = comment.substr(GCodeProcessor::Skippable_Type_Tag.length()); + set_skippable_type(type); + return; + } + //BBS: flush start tag if (boost::starts_with(comment, GCodeProcessor::Flush_Start_Tag)) { m_flushing = true; @@ -3997,6 +5028,10 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes TimeBlock block; block.move_type = type; + // stamp the current SKIPPABLE type onto the block. Stamped stTimelapse inside the fleet-wide + // time_lapse_gcode regions; byte-inert because nothing reads the stamp until the injector + // consumes it. + block.skippable_type = m_skippable_type; //BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode. block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone; block.distance = distance; @@ -4041,7 +5076,7 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); if (curr.abs_axis_feedrate[a] != 0.0f) { - float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a)); + float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a), m_machine_config_idx); if (axis_max_feedrate != 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); } } @@ -4065,7 +5100,7 @@ void GCodeProcessor::process_G1(const std::array, 4>& axes //BBS for (unsigned char a = X; a <= E; ++a) { - float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); + float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a), m_machine_config_idx); if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration) acceleration = axis_max_acceleration / (std::abs(delta_pos[a]) * inv_distance); } @@ -4357,6 +5392,10 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line) TimeBlock block; block.move_type = type; + // stamp the current SKIPPABLE type onto the block. Stamped stTimelapse inside the fleet-wide + // time_lapse_gcode regions; byte-inert because nothing reads the stamp until the injector + // consumes it. + block.skippable_type = m_skippable_type; //BBS: don't calculate travel time into extrusion path, except travel inside start and end gcode. block.role = (type != EMoveType::Travel || m_extrusion_role == erCustom) ? m_extrusion_role : erNone; block.distance = distance; @@ -4399,7 +5438,7 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line) curr.abs_axis_feedrate[a] = std::abs(curr.axis_feedrate[a]); if (curr.abs_axis_feedrate[a] != 0.0f) { - float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a)); + float axis_max_feedrate = get_axis_max_feedrate(static_cast(i), static_cast(a), m_machine_config_idx); if (axis_max_feedrate != 0.0f) min_feedrate_factor = std::min(min_feedrate_factor, axis_max_feedrate / curr.abs_axis_feedrate[a]); } } @@ -4423,7 +5462,7 @@ void GCodeProcessor::process_VG1(const GCodeReader::GCodeLine& line) //BBS for (unsigned char a = X; a <= E; ++a) { - float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a)); + float axis_max_acceleration = get_axis_max_acceleration(static_cast(i), static_cast(a), m_machine_config_idx); if (acceleration * std::abs(delta_pos[a]) * inv_distance > axis_max_acceleration) acceleration = axis_max_acceleration / (std::abs(delta_pos[a]) * inv_distance); } @@ -5162,16 +6201,23 @@ void GCodeProcessor::process_M201(const GCodeReader::GCodeLine& line) // see http://reprap.org/wiki/G-code#M201:_Set_max_printing_acceleration float factor = ((m_flavor != gcfRepRapSprinter && m_flavor != gcfRepRapFirmware) && m_units == EUnits::Inches) ? INCHES_TO_MM : 1.0f; - // Write to index i (0=Normal, 1=Stealth) — matches get_axis_max_acceleration's read pattern. + // The arrays are slot-major ([slot*2 + mode]); a firmware M201 changes the machine's live + // limits globally, so write the value into EVERY slot's mode entry. Orca: covering every slot + // (not a partial range) keeps the per-slot reads in lockstep with the mode-only reads they + // replaced. Per-mode gating unchanged: Stealth entries only once envelope processing is on. + auto set_all_slots = [](ConfigOptionFloats &option, size_t mode, float value) { + for (size_t slot_base = 0; slot_base < option.size(); slot_base += 2) + set_option_value(option, slot_base + mode, value); + }; for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal || m_time_processor.machine_envelope_processing_enabled) { - if (line.has_x()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor); + if (line.has_x()) set_all_slots(m_time_processor.machine_limits.machine_max_acceleration_x, i, line.x() * factor); - if (line.has_y()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, i, line.y() * factor); + if (line.has_y()) set_all_slots(m_time_processor.machine_limits.machine_max_acceleration_y, i, line.y() * factor); - if (line.has_z()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, i, line.z() * factor); + if (line.has_z()) set_all_slots(m_time_processor.machine_limits.machine_max_acceleration_z, i, line.z() * factor); - if (line.has_e()) set_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, i, line.e() * factor); + if (line.has_e()) set_all_slots(m_time_processor.machine_limits.machine_max_acceleration_e, i, line.e() * factor); } } } @@ -5186,20 +6232,25 @@ void GCodeProcessor::process_M203(const GCodeReader::GCodeLine& line) // http://smoothieware.org/supported-g-codes float factor = (m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware || m_flavor == gcfSmoothie || m_flavor == gcfKlipper) ? 1.0f : MMMIN_TO_MMSEC; - // Write to index i (0=Normal, 1=Stealth) — matches get_axis_max_feedrate's read pattern. + // Slot-major arrays; a firmware M203 changes the live limits globally — write every slot's + // mode entry (see process_M201). Per-mode gating unchanged. + auto set_all_slots = [](ConfigOptionFloats &option, size_t mode, float value) { + for (size_t slot_base = 0; slot_base < option.size(); slot_base += 2) + set_option_value(option, slot_base + mode, value); + }; for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { if (static_cast(i) == PrintEstimatedStatistics::ETimeMode::Normal || m_time_processor.machine_envelope_processing_enabled) { if (line.has_x()) - set_option_value(m_time_processor.machine_limits.machine_max_speed_x, i, line.x() * factor); + set_all_slots(m_time_processor.machine_limits.machine_max_speed_x, i, line.x() * factor); if (line.has_y()) - set_option_value(m_time_processor.machine_limits.machine_max_speed_y, i, line.y() * factor); + set_all_slots(m_time_processor.machine_limits.machine_max_speed_y, i, line.y() * factor); if (line.has_z()) - set_option_value(m_time_processor.machine_limits.machine_max_speed_z, i, line.z() * factor); + set_all_slots(m_time_processor.machine_limits.machine_max_speed_z, i, line.z() * factor); if (line.has_e()) - set_option_value(m_time_processor.machine_limits.machine_max_speed_e, i, line.e() * factor); + set_all_slots(m_time_processor.machine_limits.machine_max_speed_e, i, line.e() * factor); } } } @@ -5438,7 +6489,14 @@ void GCodeProcessor::process_SYNC(const GCodeReader::GCodeLine& line) void GCodeProcessor::process_T(const GCodeReader::GCodeLine& line) { - process_T(line.cmd()); + // parse the H logical-nozzle id off the T line. H2C's change_filament template emits + // `T H`; the single-nozzle fleet emits a bare `T` (H absent → -1 → byte-inert + // via the self-gate). + int nozzle_id = -1; + float nozzle_val = 0.f; + if (line.has_value('H', nozzle_val)) + nozzle_id = static_cast(nozzle_val); + process_T(line.cmd(), nozzle_id); } void GCodeProcessor::process_M1020(const GCodeReader::GCodeLine &line) @@ -5462,12 +6520,25 @@ void GCodeProcessor::process_M1020(const GCodeReader::GCodeLine &line) BOOST_LOG_TRIVIAL(error) << "Invalid M1020 command (" << line.raw() << ")."; return; } - process_filament_change(eid); + // carry the H logical-nozzle id. process_filament_change(int,int) self-gates back + // to the single-arg model for the single-nozzle fleet, so this is byte-inert for them. + int nozzle_id = -1; + float nozzle_val = 0.f; + if (line.has_value('H', nozzle_val)) + nozzle_id = static_cast(nozzle_val); + process_filament_change(eid, nozzle_id); } } } void GCodeProcessor::process_T(const std::string_view command) +{ + // the no-nozzle-context callers (custom-gcode tool-change strings, color-print T parsing) route + // through the H-less variant; -1 keeps the richer model on its filament-first nozzle fallback. + process_T(command, -1); +} + +void GCodeProcessor::process_T(const std::string_view command, int nozzle_id) { unsigned int eid = 0; auto ret = std::from_chars(command.data() + 1, command.data()+command.size(), eid); @@ -5480,8 +6551,11 @@ void GCodeProcessor::process_T(const std::string_view command) if (command.length() > 1) { if (eid < 0 || eid > 254) { //BBS: T255, T1000 and T1100 is used as special command for BBL machine and does not cost time. return directly + // Orca: T1001 (hotend-type detection) and T65535/T65279 (AMS unload virtual-tool selects, paired with + // M620/M621 S65535/S65279) are firmware opcodes emitted verbatim by BBL machine start/end g-code, not + // real tool changes - whitelist them so the time estimator stops flagging these valid lines. if ((m_flavor == gcfMarlinLegacy || m_flavor == gcfMarlinFirmware) && (command == "Tx" || command == "Tc" || command == "T?" || - eid == 1000 || eid == 1100 || eid == 255)) + eid == 1000 || eid == 1100 || eid == 255 || eid == 1001 || eid == 65279 || eid == 65535)) return; // T-1 is a valid gcode line for RepRap Firmwares (used to deselects all tools) @@ -5493,7 +6567,9 @@ void GCodeProcessor::process_T(const std::string_view command) BOOST_LOG_TRIVIAL(error) << "Invalid T command (" << command << ")."; return; } - process_filament_change(eid); + // process_filament_change(int,int) self-gates back to the single-arg model for the + // single-nozzle fleet, so this call is byte-inert for X1/P1/A1/H2S/A2L. + process_filament_change(eid, nozzle_id); } } } @@ -5509,6 +6585,233 @@ void GCodeProcessor::init_filament_maps_and_nozzle_type_when_import_only_gcode() } } +// Surface a per-filament nozzle grouping onto m_result when reprocessing an already-generated g-code +// (from-previous reload / imported g-code) — process_file does not otherwise rebuild it, so the +// multi-nozzle device GUI would find nozzle_group_result == NULL and the rack print-dispatch mapping +// request fails with code -1. Only invoked from the DynamicPrintConfig apply_config (the reprocess / +// import path); the normal streaming export keeps handing the live grouping over separately. +void GCodeProcessor::ensure_nozzle_group_result(int min_filament_count) +{ + if (m_nozzle_group_result) { + // A grouping was already seeded from the reloaded result (initialize_from_context). Publish it + // onto m_result so extract_result() carries it. (The reference relies on the streaming-export + // handover for this and returns early here; the reprocess path has no such handover.) + m_result.nozzle_group_result = m_nozzle_group_result; + return; + } + + int filament_count = std::max(1, min_filament_count); + filament_count = std::max(filament_count, static_cast(m_filament_maps.size())); + + std::vector filament_map = m_filament_maps; + if (filament_map.empty()) { + filament_map.assign(filament_count, 0); + } else if (static_cast(filament_map.size()) < filament_count) { + filament_map.resize(filament_count, filament_map.front()); + } + + int min_value = *std::min_element(filament_map.begin(), filament_map.end()); + if (min_value >= 1) { + for (int &value : filament_map) { + value -= 1; + } + } + + for (int &value : filament_map) { + value = std::max(0, value); + } + + int max_extruder_id = *std::max_element(filament_map.begin(), filament_map.end()); + max_extruder_id = std::max(0, max_extruder_id); + + std::string nozzle_diameter = format_diameter_to_str(DEFAULT_TOOLPATH_WIDTH); + std::vector nozzle_list; + nozzle_list.reserve(static_cast(max_extruder_id + 1)); + for (int extruder_id = 0; extruder_id <= max_extruder_id; ++extruder_id) { + MultiNozzleUtils::NozzleInfo info; + info.diameter = nozzle_diameter; + info.volume_type = NozzleVolumeType::nvtStandard; + info.extruder_id = extruder_id; + info.group_id = extruder_id; + nozzle_list.emplace_back(std::move(info)); + } + + std::vector filament_nozzle_map(filament_count, 0); + for (int i = 0; i < filament_count; ++i) { + filament_nozzle_map[i] = filament_map[i]; + } + + std::vector used_filaments; + used_filaments.reserve(filament_count); + for (int i = 0; i < filament_count; ++i) { + used_filaments.push_back(static_cast(i)); + } + + auto result = MultiNozzleUtils::LayeredNozzleGroupResult::create(filament_nozzle_map, nozzle_list, used_filaments); + if (result) { + m_nozzle_group_result = std::make_shared(*result); + m_result.nozzle_group_result = m_nozzle_group_result; + } +} + +bool GCodeProcessor::use_multi_nozzle_change_time_model() const +{ + // Multi-nozzle context = a printer that can incur nozzle-change events the single-arg model + // cannot distinguish: either a multi-extruder machine (nozzle_diameter has >1 physical extruder, + // e.g. H2D/X2D/H2D-Pro) or an extruder that carries a nozzle cluster (extruder_max_nozzle_count>1, + // e.g. H2C's {1,6}). Every single-extruder single-nozzle printer (X1/P1/A1/H2S/A2L) fails both + // tests → false → they keep the byte-frozen single-arg time model. Both members are populated by + // apply_config (each overload) and cleared in reset(), so this is stream-time safe. + if (m_nozzle_diameter.size() > 1) + return true; + for (int count : m_extruder_max_nozzle_count) + if (count > 1) + return true; + return false; +} + +// The richer hotend-change time model. It resolves the target nozzle from the nozzle-grouping result +// (by the H id when present, else the filament's first nozzle) and splits the change into three +// independent costs — physical-extruder switch, nozzle-in-extruder change, and filament-in-nozzle +// change — so a multi-nozzle print's ETA reflects only the transitions that actually occur. +// Estimator-gated: for the single-nozzle fleet it delegates to the single-arg model, so their time +// estimate — hence exported g-code — is unchanged. +// +// Orca: +// - The nozzle-grouping result is stored on m_result. Both resolver methods are virtual on +// NozzleGroupResultBase, so no down-cast is needed. +// - The flush delay is attributed via a Tool_change move-type block with no extrusion role (mirroring +// the single-arg convention) rather than an erFlush-stamped block, to keep the delay out of the +// per-role feature-time distribution, so the multi-nozzle delta stays a pure ETA/time shift. +// - Beyond total_(flush_)filament_changes, the richer counters (total_extruder_changes / load / +// unload / tool_change time) are maintained in the matching branches so the multi-nozzle +// GCodeViewer stats do not regress to zero. These are UI-only (not written to g-code). +std::optional GCodeProcessor::resolve_target_nozzle( + const MultiNozzleUtils::NozzleGroupResultBase &group, int id, int nozzle_id) const +{ + std::optional info; + if (nozzle_id != -1) + info = group.get_nozzle_from_id(nozzle_id); + if (!info) { + auto used_nozzles = group.get_nozzles_for_filament(id); + if (!used_nozzles.empty()) + info = used_nozzles.front(); + } + return info; +} + +void GCodeProcessor::process_filament_change(int id, int nozzle_id) +{ + // Gate: outside the multi-nozzle context, or when the nozzle-grouping result is not available + // (e.g. re-importing a bare g-code file), run the existing single-arg model byte-for-byte. + if (!use_multi_nozzle_change_time_model() || !m_result.nozzle_group_result) { + // Orca: occupancy bookkeeping is deliberately decoupled from the gated change-time model: + // the per-slot machine-limit resolution needs the recorder during the streaming pass, + // where the richer time model stays byte-frozen behind the result-field gate above. + // Recorder writes have no time effect. + if (m_nozzle_group_result) { + if (auto info = resolve_target_nozzle(*m_nozzle_group_result, id, nozzle_id)) + m_nozzle_status_recorder.set_nozzle_status(info->group_id, id, info->extruder_id); + } + process_filament_change(id); + return; + } + + assert(id < m_result.filaments_count); + const int prev_extruder_id = get_extruder_id(false); + const int prev_filament_id = get_filament_id(false); + float extra_time = 0.0f; + + // A same-filament re-select with no explicit nozzle target costs nothing. + if (prev_filament_id == id && nozzle_id == -1) + return; + + if (prev_extruder_id != -1) + m_last_filament_id[prev_extruder_id] = static_cast(prev_filament_id); + + // Resolve the destination nozzle: by explicit H id first, else the filament's first nozzle. + std::optional target_nozzle_info = resolve_target_nozzle(*m_result.nozzle_group_result, id, nozzle_id); + if (!target_nozzle_info) + return; + + const int new_extruder_id = target_nozzle_info->extruder_id; + const int old_extruder_id = prev_extruder_id; + const int new_nozzle_id_in_extruder = target_nozzle_info->group_id; + const int old_nozzle_id_in_extruder = m_nozzle_status_recorder.get_nozzle_in_extruder(new_extruder_id); + const int new_filament_id = id; + const int old_filament_in_nozzle = m_nozzle_status_recorder.get_filament_in_nozzle(new_nozzle_id_in_extruder); + const int old_filament_in_extruder = m_nozzle_status_recorder.get_filament_in_nozzle(old_nozzle_id_in_extruder); + + const bool extruder_change = new_extruder_id != old_extruder_id; + const bool nozzle_in_extruder_change = new_nozzle_id_in_extruder != old_nozzle_id_in_extruder; + const bool filament_in_nozzle_change = new_filament_id != old_filament_in_nozzle; + + // Orca: attribute the accumulated volume usage to the OLD extruder before switching state. Unlike + // an unconditional call, the single-arg model (and every other Orca estimator path) skips this on + // the very first tool-select (prev_extruder_id == -1) where there is no prior filament segment to + // close out. Matching that keeps H2C's initial `T H` byte-identical to its single-arg + // baseline; every subsequent change closes out identically. + if (prev_extruder_id != -1) + process_filaments(CustomGCode::ToolChange); + + m_result.lock(); + if (extruder_change && old_extruder_id != -1) { + const float t = get_extruder_change_time(new_extruder_id); + extra_time += t; + m_result.print_statistics.total_tool_change_time += t; // Orca-only stat + m_result.print_statistics.total_extruder_changes += 1; // Orca-only stat + } + if (nozzle_in_extruder_change || filament_in_nozzle_change) { + if (old_filament_in_extruder >= 0) { + const float t = get_filament_unload_time(static_cast(old_filament_in_extruder)); + extra_time += t; + m_result.print_statistics.total_filament_unload_time += t; // Orca-only stat + } + m_time_processor.extruder_unloaded = false; + const float t = get_filament_load_time(static_cast(new_filament_id)); + extra_time += t; + m_result.print_statistics.total_filament_load_time += t; // Orca-only stat + if (filament_in_nozzle_change && old_filament_in_nozzle != -1) + m_result.print_statistics.total_flush_filament_changes += 1; + } + if (prev_filament_id != -1) + m_result.print_statistics.total_filament_changes += 1; + m_result.unlock(); + + if (new_extruder_id != -1) + m_filament_id[new_extruder_id] = static_cast(new_filament_id); + m_extruder_id = static_cast(new_extruder_id); + + // Record the resulting nozzle/extruder occupancy so the next change can classify itself. + m_nozzle_status_recorder.set_nozzle_status(new_nozzle_id_in_extruder, new_filament_id, new_extruder_id); + + m_cp_color.current = m_extruder_colors[new_filament_id]; + + // Same tool-change move + zero-distance time block plumbing as the single-arg model, so the flush + // delay lands on a Tool_change block (kept out of the per-role feature-time distribution). + store_move_vertex(EMoveType::Tool_change); + + for (size_t i = 0; i < static_cast(PrintEstimatedStatistics::ETimeMode::Count); ++i) { + TimeMachine& machine = m_time_processor.machines[i]; + if (!machine.enabled) + continue; + TimeBlock block; + block.move_id = static_cast(m_result.moves.size()) - 1; + block.move_type = EMoveType::Tool_change; + block.skippable_type = m_skippable_type; + block.layer_id = std::max(1, m_layer_id); + block.g1_line_id = m_g1_line_id; + block.flags.prepare_stage = m_processing_start_custom_gcode; + block.distance = 0.0f; + block.calculate_trapezoid(); + machine.blocks.push_back(block); + } + + simulate_st_synchronize(extra_time, EMoveType::Tool_change); + + m_machine_config_idx = get_machine_config_idx(); +} + void GCodeProcessor::process_filament_change(int id) { assert(id < m_result.filaments_count); @@ -5616,6 +6919,10 @@ void GCodeProcessor::process_filament_change(int id) TimeBlock block; block.move_id = static_cast(m_result.moves.size()) - 1; block.move_type = EMoveType::Tool_change; + // stamp the current SKIPPABLE type onto the tool-change block (the fleet-wide time_lapse_gcode + // regions stamp stTimelapse); byte-inert because nothing reads the stamp until the injector + // consumes it. + block.skippable_type = m_skippable_type; block.layer_id = std::max(1, m_layer_id); block.g1_line_id = m_g1_line_id; block.flags.prepare_stage = m_processing_start_custom_gcode; @@ -5625,6 +6932,8 @@ void GCodeProcessor::process_filament_change(int id) } simulate_st_synchronize(extra_time, EMoveType::Tool_change); + + m_machine_config_idx = get_machine_config_idx(); } void GCodeProcessor::store_move_vertex(EMoveType type, EMovePathType path_type, bool internal_only) @@ -5723,6 +7032,21 @@ void GCodeProcessor::set_extrusion_role(ExtrusionRole role) m_extrusion_role = role; } +// Resolve a SKIPPABLE_TYPE payload to a SkipType. Only meaningful inside a SKIPPABLE region. +void GCodeProcessor::set_skippable_type(const std::string_view type) +{ + if (!m_skippable) { + m_skippable_type = SkipType::stNone; + return; + } + auto iter = skip_type_map.find(type); + if (iter != skip_type_map.end()) { + m_skippable_type = iter->second; + } else { + m_skippable_type = SkipType::stOther; + } +} + float GCodeProcessor::minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const { if (m_time_processor.machine_limits.machine_min_extruding_rate.empty()) @@ -5739,31 +7063,59 @@ float GCodeProcessor::minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMod return std::max(feedrate, get_option_value(m_time_processor.machine_limits.machine_min_travel_rate, static_cast(mode))); } -// Machine limit arrays hold 2 values: [0]=Normal, [1]=Stealth. Index by mode only. -// BambuStudio used extruder_id*2+mode to support per-nozzle limits, but OrcaSlicer -// never ported that system (filament_map_2 / get_config_idx_for_filament), so the -// extruder_id offset was always wrong: uninitialized extruder (255) or extruder > 0 -// would overshoot the array and fall back to values.back() (stealth limits). +// Machine slot of the nozzle currently mounted in the active extruder. Slot 0 (the historical +// single-slot read) whenever there is no grouping context (bare g-code import), no active +// extruder yet, or the nozzle/extruder is unknown to the recorder. +int GCodeProcessor::get_machine_config_idx() const +{ + const int extruder_id = get_extruder_id(false); + if (!m_nozzle_group_result || extruder_id < 0) + return 0; + const int nozzle_id = m_nozzle_status_recorder.get_nozzle_in_extruder(extruder_id); + auto nozzle_info = m_nozzle_group_result->get_nozzle_from_id(nozzle_id); + // Orca: bounds guard — a stale grouping context after a printer swap must not index OOB. + if (!nozzle_info || extruder_id >= (int) m_result.extruder_types.size()) + return 0; + return std::max(0, get_config_index_base(nozzle_info->volume_type, m_result.extruder_types[extruder_id], + extruder_id + 1, m_result.printer_extruder_variant, + m_result.printer_extruder_id)); +} + +// Speed/acceleration limit arrays are slot-major with two mode entries per machine slot: +// [slot*2 + mode]. Single-variant printers have one slot, so the 2-arg forms (slot 0) read +// exactly the historical [mode] entry. float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const { + return get_axis_max_feedrate(mode, axis, 0); +} + +float GCodeProcessor::get_axis_max_feedrate(PrintEstimatedStatistics::ETimeMode mode, Axis axis, int machine_idx) const +{ + const size_t pos = static_cast(machine_idx) * 2 + static_cast(mode); switch (axis) { - case X: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_x, static_cast(mode)); } - case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_y, static_cast(mode)); } - case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_z, static_cast(mode)); } - case E: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_e, static_cast(mode)); } + case X: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_x, pos); } + case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_y, pos); } + case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_z, pos); } + case E: { return get_option_value(m_time_processor.machine_limits.machine_max_speed_e, pos); } default: { return 0.0f; } } } float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const { + return get_axis_max_acceleration(mode, axis, 0); +} + +float GCodeProcessor::get_axis_max_acceleration(PrintEstimatedStatistics::ETimeMode mode, Axis axis, int machine_idx) const +{ + const size_t pos = static_cast(machine_idx) * 2 + static_cast(mode); switch (axis) { - case X: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, static_cast(mode)); } - case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, static_cast(mode)); } - case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, static_cast(mode)); } - case E: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, static_cast(mode)); } + case X: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_x, pos); } + case Y: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_y, pos); } + case Z: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_z, pos); } + case E: { return get_option_value(m_time_processor.machine_limits.machine_max_acceleration_e, pos); } default: { return 0.0f; } } } diff --git a/src/libslic3r/GCode/GCodeProcessor.hpp b/src/libslic3r/GCode/GCodeProcessor.hpp index 1d2e0890da..8a66cdc9e4 100644 --- a/src/libslic3r/GCode/GCodeProcessor.hpp +++ b/src/libslic3r/GCode/GCodeProcessor.hpp @@ -6,6 +6,7 @@ #include "libslic3r/ExtrusionEntity.hpp" #include "libslic3r/PrintConfig.hpp" #include "libslic3r/CustomGCode.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" #include #include @@ -43,6 +44,23 @@ class Print; Count }; + // Classifies why a wipe-tower / change_filament / time-lapse region is safe to relocate a + // pre-heat M104 into, for the pre-heat/pre-cool injector. The shipping time_lapse_gcode + // template (timelapse-on by default) emits SKIPPABLE_* on essentially every slice, so the + // "timelapse" payload -> stTimelapse classification is exercised widely. + enum SkipType + { + stTimelapse, + stHeadWrapDetect, + stOther, + stNone + }; + + const std::unordered_map skip_type_map{ + {"timelapse", SkipType::stTimelapse}, + {"head_wrap_detect", SkipType::stHeadWrapDetect} + }; + struct PrintEstimatedStatistics { enum class ETimeMode : unsigned char @@ -77,6 +95,10 @@ class Print; std::array(ETimeMode::Count)> modes; unsigned int total_filament_changes; + // Number of filament changes that actually re-flush a nozzle (a filament-in-nozzle change + // onto a non-empty nozzle), tracked only by the richer multi-nozzle hotend-change time model. + // Stays 0 for single-nozzle printers (X1/P1/A1/H2S/A2L), which never enter the two-arg model. + unsigned int total_flush_filament_changes; unsigned int total_extruder_changes; float total_filament_load_time; float total_filament_unload_time; @@ -101,6 +123,7 @@ class Print; flush_per_filament.clear(); used_filaments_per_role.clear(); total_filament_changes = 0; + total_flush_filament_changes = 0; total_extruder_changes = 0; total_filament_load_time = 0.0f; total_filament_unload_time = 0.0f; @@ -166,6 +189,14 @@ class Print; ConflictResultOpt conflict_result; GCodeCheckResult gcode_check_result; FilamentPrintableResult filament_printable_reuslt; + // The per-filament -> logical-nozzle grouping the slicer computed for this + // result, surfaced onto the object the device GUI reads + // (plater->background_process().get_current_gcode_result()). Populated only from + // Print::get_layered_nozzle_group_result() (ToolOrdering's static L/R + rack subset); + // default-empty (null) and read by no g-code emitter, so it is invisible in the emitted + // g-code. Consumed by the print-dispatch nozzle mapping (DevNozzleMappingCtrl) via + // DevUtilBackend::GetNozzleGroupResult. + std::shared_ptr nozzle_group_result; float initial_layer_time; struct SettingsIds @@ -263,6 +294,14 @@ class Print; std::vector warnings; int nozzle_hrc; std::vector nozzle_type; + // Per-extruder physical hotend type. Fed to the pre-heat injector's TimeProcessContext + // (mixed-type X2D workaround). Populated in apply_config; unused until the injector side-pass + // consumes it. + std::vector extruder_types; + // Machine-slot layout of the per-variant printer arrays (one entry per (extruder x + // volume-type) slot). Populated in apply_config; keys the per-slot machine-limit lookup. + std::vector printer_extruder_variant; + std::vector printer_extruder_id; // first key stores filaments, second keys stores the layer ranges(enclosed) that use the filaments std::unordered_map, std::vector>,FilamentSequenceHash> layer_filaments; std::vector nozzle_change_sequence; @@ -271,6 +310,11 @@ class Print; // first key stores `from` filament, second keys stores the `to` filament std::map, int > filament_change_count_map; + // Accumulated print time spent inside SKIPPABLE regions, per skip type. Populated by the time + // estimator; consumed only downstream. The shipping time_lapse_gcode template emits SKIPPABLE_* + // widely, so this is typically populated (stTimelapse) on most slices. + std::unordered_map skippable_part_time; + BedType bed_type = BedType::btCount; void reset(); @@ -304,11 +348,20 @@ class Print; gcode_check_result = other.gcode_check_result; limit_filament_maps = other.limit_filament_maps; filament_printable_reuslt = other.filament_printable_reuslt; + // Orca: copy the shared grouping result so a copied result keeps it (shared_ptr => + // memory-safe), rather than leaving a stale pointer on the target. No g-code effect either way. + nozzle_group_result = other.nozzle_group_result; + // Keep the per-extruder hotend types on a copied result (injector input). + extruder_types = other.extruder_types; + printer_extruder_variant = other.printer_extruder_variant; + printer_extruder_id = other.printer_extruder_id; layer_filaments = other.layer_filaments; filament_change_sequence = other.filament_change_sequence; nozzle_change_sequence = other.nozzle_change_sequence; optimal_assignment = other.optimal_assignment; filament_change_count_map = other.filament_change_count_map; + // Keep the SKIPPABLE per-type time on a copied result. + skippable_part_time = other.skippable_part_time; initial_layer_time = other.initial_layer_time; #if ENABLE_GCODE_VIEWER_STATISTICS time = other.time; @@ -319,6 +372,75 @@ class Print; void unlock() const { result_mutex.unlock(); } }; + // First-pass usage-block descriptors for the pre-heat/pre-cool injector. FilamentUsageBlock + // records the [lower,upper) output-line-id span a single filament occupies; ExtruderUsageBlcok + // (the "Blcok" typo is intentional) records the span an extruder is active in, with the start/end + // filament + logical-nozzle ids and the post-extrusion (pre-switch) partial-free sub-range. Built + // during run_post_process, consumed only by the injector side-pass under the enable_pre_heating gate. + namespace ExtruderPreHeating + { + struct FilamentUsageBlock + { + int filament_id; + int extruder_id; + int nozzle_id; + unsigned int lower_gcode_id; + unsigned int upper_gcode_id; // [lower_gcode_id,upper_gcode_id) uses current filament , upper gcode id will be set after finding next block + FilamentUsageBlock(int filament_id_, int extruder_id_, int nozzle_id_, unsigned int lower_gcode_id_, unsigned int upper_gcode_id_) :filament_id(filament_id_), extruder_id(extruder_id_), nozzle_id(nozzle_id_), lower_gcode_id(lower_gcode_id_), upper_gcode_id(upper_gcode_id_) {} + }; + + /** + * @brief Describle the usage of a exturder in a section + * + * The strucutre stores the start and end lines of the sections as well as + * the filament used at the beginning and end of the section. + * Post extrusion means the final extrusion before switching to the next extruder. + * + * Simplified GCode Flow: + * 1.Extruder Change Block (ext0 switch to ext1) + * 2.Extruder Usage Block (use ext1 to print) + * 3.Extruder Change Block (ext1 switch to ext0) + * 4.Extruder Usage Block (use ext0 to print) + * 5.Extruder Change Block (ext0 switch to ex1) + * ... + * + * So the construct of extruder usage block relys on two extruder change block + */ + struct ExtruderUsageBlcok + { + int extruder_id = -1; + unsigned int start_id = -1; + unsigned int end_id = -1; + int start_filament = -1; + int end_filament = -1; + int start_nozzle_id = -1; + int end_nozzle_id = -1; + unsigned int post_extrusion_start_id = -1; + unsigned int post_extrusion_end_id = -1; + bool ignore_cooling_before_tower = false; + + void initialize_step_1(int extruder_id_, int start_id_, int start_filament_, int start_nozzle_id_) { + extruder_id = extruder_id_; + start_id = start_id_; + start_filament = start_filament_; + start_nozzle_id = start_nozzle_id_; + }; + void initialize_step_2(int post_extrusion_start_id_) { + post_extrusion_start_id = post_extrusion_start_id_; + } + void initialize_step_3(int end_id_, int end_filament_, int post_extrusion_end_id_, int end_nozzle_id_) { + end_id = end_id_; + end_filament = end_filament_; + post_extrusion_end_id = post_extrusion_end_id_; + end_nozzle_id = end_nozzle_id_; + } + void reset() { + *this = ExtruderUsageBlcok(); + } + ExtruderUsageBlcok() = default; + }; + } + class CommandProcessor { public: @@ -347,6 +469,24 @@ class Print; static const std::string VFlush_Start_Tag; static const std::string VFlush_End_Tag; static const std::string External_Purge_Tag; + public: + // Orca: SKIPPABLE region tags, stored as static strings (the FLUSH idiom above) rather than + // a CustomETags/CustomTags array. Public so the emission sites (WipeTower / change_filament + // path) can reference them single-sourced. + static const std::string Skippable_Start_Tag; + static const std::string Skippable_End_Tag; + static const std::string Skippable_Type_Tag; + // Orca: usage-block builder markers (MACHINE_START_GCODE_END / MACHINE_END_GCODE_START / + // NOZZLE_CHANGE_START / NOZZLE_CHANGE_END / CP_TOOLCHANGE_WIPE), stored as static strings (the + // FLUSH/SKIPPABLE idiom above) rather than extending the Reserved_Tags arrays — these are + // multi-nozzle markers only ever emitted by BBL-printer paths. Public so the emission sites can + // reference them single-sourced. The MACHINE_*_GCODE_* emission (GCode.cpp, gated + // enable_pre_heating) activates the usage-block builder. + static const std::string Machine_Start_GCode_End_Tag; + static const std::string Machine_End_GCode_Start_Tag; + static const std::string Nozzle_Change_Start_Tag; + static const std::string Nozzle_Change_End_Tag; + static const std::string Toolchange_Wipe_Tag; public: enum class ETags : unsigned char { @@ -455,6 +595,9 @@ class Print; EMoveType move_type{ EMoveType::Noop }; ExtrusionRole role{ erNone }; + // SKIPPABLE tag classification stamped onto each time block. Feeds skippable_part_time + // and the injector's SKIPPABLE relocation. stNone unless inside a SKIPPABLE_* region. + SkipType skippable_type{ SkipType::stNone }; unsigned int move_id{ 0 }; unsigned int g1_line_id{ 0 }; unsigned int remaining_internal_g1_lines{ 0 }; @@ -624,6 +767,25 @@ class Print; struct TimeProcessor { + // Orca: the insert-line taxonomy + the ordered map of lines the pre-heat/pre-cool injector + // splices into the finished g-code, keyed by output-line id. Orca keeps its single-pass + // run_post_process (M73 / filament stats / ActualSpeedMove / Backtrace / + // machine_tool_change_time) intact and applies this map in a separate, gated ADDITIVE + // second file-rewrite pass (run_second_pass_injection); with an empty map that pass is a + // byte-for-byte identity rewrite. The map is populated by the PreCoolingInjector. + enum InsertLineType + { + PlaceholderReplace, + TimePredict, + FilamentChangePredict, + ExtruderChangePredict, + PreCooling, + PreHeating, + }; + + // first key is line id, second key is content + using InsertedLinesMap = std::map>>; + struct Planner { // Size of the firmware planner queue. The old 8-bit Marlins usually just managed 16 trapezoidal blocks. @@ -651,6 +813,117 @@ class Print; void reset(); }; + + // The pre-cool / pre-heat injection engine. It consumes the already-computed per-move time + // substrate (moves[i].time[valid_machine_id] / .gcode_id) and the first-pass usage blocks to + // locate idle-hotend windows, then emits M632/M400/M104/M633 lines into a + // TimeProcessor::InsertedLinesMap that the additive second file-rewrite pass + // (run_second_pass_injection) splices into the finished g-code. It is constructed and run ONLY + // when m_enable_pre_heating — single-nozzle printers (X1/P1/A1/H2S, flag false) never reach it. + // Every input is a const reference bundled from GCodeProcessor members; the injector never + // mutates GCodeProcessor state. + class PreCoolingInjector { + public: + struct ExtruderFreeBlock { + unsigned int free_lower_gcode_id; + unsigned int free_upper_gcode_id; + unsigned int partial_free_lower_id; // range of extrusion in wipe tower; without a wipe tower + unsigned int partial_free_upper_id; // partial_free lower/upper equal free_lower_gcode_id + int last_filament_id; + int next_filament_id; + int last_nozzle_id; + int next_nozzle_id; + int extruder_id; // partition key for the pre-heat/pre-cool region (extruder or hotend), not + // necessarily a real extruder id + bool ignore_cooling_before_tower = false; + }; + + void process_pre_cooling_and_heating(TimeProcessor::InsertedLinesMap& inserted_operation_lines); + void build_extruder_free_blocks(const std::vector& filament_usage_blocks, const std::vector& extruder_usage_blocks); + + PreCoolingInjector( + const std::vector& moves_, + const std::vector& filament_types_, + const MultiNozzleUtils::LayeredNozzleGroupResult& nozzle_group_result_, + const std::vector& filament_nozzle_temps_, + const std::vector& filament_nozzle_temps_initial_layer_, + const std::vector& physical_extruder_map_, + int valid_machine_id_, + float inject_time_threshold_, + bool handle_hotend_as_extruder_, + bool has_filament_switcher_, + const std::vector& pre_cooling_temp_, + const std::vector& cooling_rate_, + const std::vector& heating_rate_, + const std::vector>& skippable_blocks_, + const std::vector& extruder_max_nozzle_count_, + const std::vector& filament_preheat_temperature_delta_, + const std::vector& filament_max_temperature_drop_when_ec_, + unsigned int machine_start_gcode_end_id_, + unsigned int machine_end_gcode_start_id_, + const std::vector& extruder_types_, + const std::vector& nozzle_diameter_ + ) : + moves(moves_), + filament_types(filament_types_), + nozzle_group_result(nozzle_group_result_), + filament_nozzle_temps(filament_nozzle_temps_), + filament_nozzle_temps_initial_layer(filament_nozzle_temps_initial_layer_), + physical_extruder_map(physical_extruder_map_), + valid_machine_id(valid_machine_id_), + inject_time_threshold(inject_time_threshold_), + handle_hotend_as_extruder(handle_hotend_as_extruder_), + has_filament_switcher(has_filament_switcher_), + filament_pre_cooling_temps(pre_cooling_temp_), + cooling_rate(cooling_rate_), + heating_rate(heating_rate_), + skippable_blocks(skippable_blocks_), + extruder_max_nozzle_count(extruder_max_nozzle_count_), + filament_preheat_temperature_delta(filament_preheat_temperature_delta_), + filament_max_temperature_drop_when_ec(filament_max_temperature_drop_when_ec_), + machine_start_gcode_end_id(machine_start_gcode_end_id_), + machine_end_gcode_start_id(machine_end_gcode_start_id_), + extruder_types(extruder_types_), + nozzle_diameter(nozzle_diameter_) + { + } + + private: + std::vector m_extruder_free_blocks; + const std::vector& moves; + const std::vector& filament_types; + const MultiNozzleUtils::LayeredNozzleGroupResult& nozzle_group_result; + const std::vector& filament_nozzle_temps; + const std::vector& filament_nozzle_temps_initial_layer; + const std::vector& physical_extruder_map; + const int valid_machine_id; + const float inject_time_threshold; + const bool handle_hotend_as_extruder; + const bool has_filament_switcher; + const std::vector& cooling_rate; + const std::vector& heating_rate; + const std::vector& filament_pre_cooling_temps; // target cooling temp during post extrusion + const std::vector>& skippable_blocks; + const std::vector& extruder_max_nozzle_count; + const std::vector& filament_preheat_temperature_delta; + const std::vector& filament_max_temperature_drop_when_ec; + const unsigned int machine_start_gcode_end_id; + const unsigned int machine_end_gcode_start_id; + const std::vector& extruder_types; + const std::vector& nozzle_diameter; + + void inject_cooling_heating_command( + TimeProcessor::InsertedLinesMap& inserted_operation_lines, + const ExtruderFreeBlock& free_block, + float curr_temp, + float target_temp, + bool pre_cooling, + bool pre_heating + ); + + void build_by_filament_blocks(const std::vector& filament_usage_blocks); + void build_by_extruder_blocks(const std::vector& extruder_usage_blocks); + }; public: class SeamsDetector { @@ -795,12 +1068,57 @@ class Print; bool m_flushing; // mark a section with real flush bool m_virtual_flushing; // mark a section with virtual flush, only for statistics bool m_wipe_tower; + // Current-section SKIPPABLE state. Set by process_tags when inside a SKIPPABLE_* region; + // stamped onto each TimeBlock. The shipping time_lapse_gcode template emits SKIPPABLE_* + // widely, so these commonly go active (true / stTimelapse) and stamp blocks on most slices. + bool m_skippable{false}; + SkipType m_skippable_type{SkipType::stNone}; int m_object_label_id{-1}; float m_print_z{0.0f}; std::vector m_remaining_volume; ExtruderTemps m_filament_nozzle_temp; ExtruderTemps m_filament_nozzle_temp_first_layer; std::vector m_physical_extruder_map; + // Multi-nozzle context state. Per-extruder max (sub-)nozzle count; >1 marks a multi-nozzle + // extruder. Input for the pre-heat/filament-change-time injection model; not yet consumed by + // Orca's time estimator, so it is inert for existing printers. + std::vector m_extruder_max_nozzle_count{1}; + // Pre-heat / pre-cool injector estimator inputs. Populated from the config in apply_config + // (both overloads) and cleared in reset(), so the PreCoolingInjector has its inputs in place. + // Consumed only by the injector two-pass side-pass, gated on m_enable_pre_heating. + std::vector m_filament_types; + std::vector m_nozzle_diameter; + std::vector m_hotend_cooling_rate{ 2.f }; + std::vector m_hotend_heating_rate{ 2.f }; + std::vector m_filament_pre_cooling_temp{ 0 }; + std::vector m_filament_preheat_temperature_delta; + bool m_enable_pre_heating{ false }; + bool m_handle_hotend_as_extruder{ false }; + bool m_has_filament_switcher{ false }; + // [start,end] output-line-id ranges of each SKIPPABLE region, collected during + // run_post_process. The injector relocates pre-heat M104s out of these ranges. The shipping + // time_lapse_gcode template emits SKIPPABLE_* widely, so on a timelapse-on slice this is + // populated with many timelapse ranges (not empty) — the consumer must expect the common + // timelapse case, not only H2C/A2L wipe-tower ranges. + std::vector> m_skippable_blocks; + // First-pass usage blocks, built in run_post_process and stored on the member so the + // injector side-pass can consume them. Filled only when m_enable_pre_heating — single-nozzle + // printers (X1/P1/A1/H2S) never build them. They depend on the MACHINE_*_GCODE_* / + // NOZZLE_CHANGE_* emission the builder keys off. + std::vector m_filament_blocks; + std::vector m_extruder_blocks; + unsigned int m_machine_start_gcode_end_line_id{ (unsigned int) (-1) }; + unsigned int m_machine_end_gcode_start_line_id{ (unsigned int) (-1) }; + // Tracks, during the stream, which filament sits in each physical nozzle and which nozzle each + // extruder currently carries. Written by both branches of the two-arg process_filament_change + // (the fallback branch does occupancy bookkeeping only); read by the richer change-time model + // and by the per-slot machine-limit resolution. Single-nozzle printers never populate it. + MultiNozzleUtils::NozzleStatusRecorder m_nozzle_status_recorder; + // Nozzle grouping context for slot resolution during the streaming pass. Set before the + // replay begins (see initialize_from_context); deliberately separate from + // m_result.nozzle_group_result, which is handed over only after the stream for the + // pre-heat injector's second pass and gates the richer change-time model. + std::shared_ptr m_nozzle_group_result; bool m_manual_filament_change; //BBS: x, y offset for gcode generated @@ -825,6 +1143,9 @@ class Print; std::vector m_last_filament_id; std::vector m_filament_id; unsigned char m_extruder_id; + // Cached get_machine_config_idx() value; its inputs (active extruder + recorder occupancy) + // change only on filament-change events, where it is recomputed. + int m_machine_config_idx{0}; ExtruderColors m_extruder_colors; ExtruderTemps m_extruder_temps; bool m_is_XL_printer = false; @@ -846,6 +1167,7 @@ class Print; float m_preheat_time; int m_preheat_steps; bool m_disable_m73; + std::string m_printer_model; enum class EProducer { @@ -875,6 +1197,11 @@ class Print; public: GCodeProcessor(); void init_filament_maps_and_nozzle_type_when_import_only_gcode(); + // Reprocessing an already-generated g-code (from-previous / imported g-code) does not rebuild + // the per-filament nozzle grouping the multi-nozzle device GUI needs. Surface it onto the + // result: keep an already-seeded grouping (from initialize_from_context), otherwise synthesize + // a default one from the filament map so the result is never left without it. + void ensure_nozzle_group_result(int min_filament_count); // check whether the gcode path meets the filament_map grouping requirements bool check_multi_extruder_gcode_valid(const int extruder_size, const Pointfs plate_printable_area, @@ -886,6 +1213,11 @@ class Print; const std::vector>& unprintable_filament_types ); void apply_config(const PrintConfig& config); void set_print(Print* print) { m_print = print; } + // Hand the nozzle grouping context to the estimator BEFORE the streaming replay, so the + // per-slot machine-limit resolution can follow the active nozzle. Null is fine (slot 0). + void initialize_from_context(const std::shared_ptr& nozzle_group_result) { + m_nozzle_group_result = nozzle_group_result; + } DynamicConfig export_config_for_render() const; @@ -1084,35 +1416,72 @@ class Print; // Unload the current filament into the MK3 MMU2 unit at the end of print. void process_M702(const GCodeReader::GCodeLine& line); + //Used for Elegoo printer to change tool head + void process_M6211(const GCodeReader::GCodeLine& line); + void process_elegoo_M6211(const GCodeReader::GCodeLine& line); + void process_SYNC(const GCodeReader::GCodeLine& line); // Processes T line (Select Tool) void process_T(const GCodeReader::GCodeLine& line); void process_T(const std::string_view command); + // T variant carrying the H logical-nozzle id parsed off the command line. -1 = absent. + void process_T(const std::string_view command, int nozzle_id); void process_M1020(const GCodeReader::GCodeLine &line); void process_M622(const GCodeReader::GCodeLine &line); void process_M623(const GCodeReader::GCodeLine &line); void process_filament_change(int id); + // Richer hotend-change time model distinguishing extruder-switch / nozzle-in-extruder change / + // filament-in-nozzle change. Self-gated: for single-nozzle printers it delegates to + // process_filament_change(int) so their time estimate — hence exported g-code — is unchanged. + void process_filament_change(int id, int nozzle_id); + // Destination nozzle of a filament change: the explicit H id when given, else the + // filament's first nozzle in the grouping. Shared by the change-time model and the + // fallback-path occupancy bookkeeping. + std::optional resolve_target_nozzle( + const MultiNozzleUtils::NozzleGroupResultBase &group, int id, int nozzle_id) const; + // Machine slot of the nozzle currently mounted in the active extruder (0 when no grouping + // context / unknown extruder — the single-slot layout). Cached in m_machine_config_idx, + // recomputed on filament-change events. + int get_machine_config_idx() const; + // True only for multi-nozzle-capable printers (H2C cluster, or a dual/multi-extruder machine + // like H2D/X2D): the gate that admits the richer two-arg hotend-change time model. False for + // every single-extruder single-nozzle printer (X1/P1/A1/H2S/A2L). + bool use_multi_nozzle_change_time_model() const; // post process the file with the given filename to: // 1) add remaining time lines M73 and update moves' gcode ids accordingly // 2) update used filament data void run_post_process(); + // Additive second file-rewrite pass. Splices the pre-heat/pre-cool injector's InsertedLinesMap + // into the finished g-code and re-shifts every move's gcode_id by the number of inserted lines + // before it. Runs only when m_enable_pre_heating, AFTER run_post_process, so single-nozzle + // printers (X1/P1/A1/H2S) never enter it; with an empty map it is a byte-for-byte identity rewrite. + void run_second_pass_injection(); + // Shift each move's gcode_id by the count of injector lines inserted before it. No-op when the + // map is empty. + void handle_offsets_of_second_process(const TimeProcessor::InsertedLinesMap& inserted_operation_lines); + //BBS: different path_type is only used for arc move void store_move_vertex(EMoveType type, EMovePathType path_type = EMovePathType::Noop_move, bool internal_only = false); void set_extrusion_role(ExtrusionRole role); + // Resolve the SKIPPABLE_TYPE payload to a SkipType. + void set_skippable_type(const std::string_view type); float minimum_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const; float minimum_travel_feedrate(PrintEstimatedStatistics::ETimeMode mode, float feedrate) const; - // Machine limit arrays are indexed by time mode only: [0]=Normal, [1]=Stealth. - // Do NOT add an extruder_id parameter — OrcaSlicer does not use BambuStudio's - // per-nozzle machine limits (filament_map_2 / get_config_idx_for_filament). + // Speed/acceleration limit arrays are slot-major with two mode entries per machine slot: + // [slot*2 + mode], slot from get_machine_config_idx() (0 = the only slot on single-variant + // printers, whose arrays hold just [Normal, Stealth]). The 2-arg forms read slot 0 and stay + // exactly the historical mode-only lookup; jerk and the accelerations below are mode-only. float get_axis_max_feedrate(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const; + float get_axis_max_feedrate(PrintEstimatedStatistics::ETimeMode mode, Axis axis, int machine_idx) const; float get_axis_max_acceleration(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const; + float get_axis_max_acceleration(PrintEstimatedStatistics::ETimeMode mode, Axis axis, int machine_idx) const; float get_axis_max_jerk_with_jd(PrintEstimatedStatistics::ETimeMode mode, Axis axis, float acceleration) const; float get_axis_max_jerk_with_jd(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const; float get_axis_max_jerk(PrintEstimatedStatistics::ETimeMode mode, Axis axis) const; diff --git a/src/libslic3r/GCode/TimelapsePosPicker.cpp b/src/libslic3r/GCode/TimelapsePosPicker.cpp index 0301d01122..364624a88c 100644 --- a/src/libslic3r/GCode/TimelapsePosPicker.cpp +++ b/src/libslic3r/GCode/TimelapsePosPicker.cpp @@ -361,7 +361,8 @@ namespace Slic3r { * @param safe_areas A collection of extended polygons defining the safe areas. * @return Point The nearest point within the safe areas or the default timelapse position if no safe areas exist. */ - Point pick_pos_internal(const Point& curr_pos, const ExPolygons& safe_areas, const ExPolygons& path_collision_area, bool detect_path_collision) + Point pick_pos_internal(const Point& curr_pos, const ExPolygons& safe_areas, const ExPolygons& path_collision_area, bool detect_path_collision, + const std::optional& farthest_point = std::nullopt) { struct CandidatePoint { @@ -381,7 +382,11 @@ namespace Slic3r { std::priority_queue max_heap; const double candidate_point_segment = scale_(5), weight_of_camera=1./3.; - auto penaltyFunc = [&weight_of_camera](const Point &curr_post, const Point &CameraPos, const Point &candidatet) -> double { + auto penaltyFunc = [&weight_of_camera, &farthest_point](const Point &curr_post, const Point &CameraPos, const Point &candidatet) -> double { + if (farthest_point.has_value()) { + // Farthest-point timelapse: prefer candidate closest to the farthest point (L1 norm) + return (farthest_point.value() - candidatet).cwiseAbs().sum(); + } // move distance + Camera occlusion penalty function double ret_pen = (curr_post - candidatet).cwiseAbs().sum() - weight_of_camera * (CameraPos - candidatet).cwiseAbs().sum(); return ret_pen; @@ -523,7 +528,7 @@ namespace Slic3r { path_collision_area = union_ex(layer_slices_without_curr, rod_limit_areas); } - return pick_pos_internal(center_p, safe_area,path_collision_area, by_object); + return pick_pos_internal(center_p, safe_area,path_collision_area, by_object, ctx.farthest_point); } /** @@ -610,4 +615,50 @@ namespace Slic3r { return *m_all_layer_pos; } + // Whether the head can travel to X0 without crossing any other instance that is + // taller than the current print position. + bool TimelapsePosPicker::get_is_clear_to_x0(const PosPickCtx &ctx) + { + bool by_object = m_print_seq == PrintSequence::ByObject; + std::vector object_list = get_object_list(ctx.printed_objects); + + auto range_intersect = [](int left1, int right1, int left2, int right2) { + if (left1 <= left2 && left2 <= right1) return true; + if (left2 <= left1 && left1 <= right2) return true; + return false; + }; + + ExPolygons unclear_area; + const Layer *layer = ctx.curr_layer; + float z_target = layer->print_z; + float z_low = layer->print_z - 0.5; + float z_high = layer->print_z + 0.5; + + for (auto &obj : object_list) { + for (auto &instance : obj->instances()) { + auto instance_bbox = get_real_instance_bbox(instance); + bool is_curr_obj = ( obj == object_list.back() ) || ( !by_object ), + higher_than_curr_pos = instance_bbox.max.z() > z_target; + if (!is_curr_obj && range_intersect(instance_bbox.min.z(), instance_bbox.max.z(), z_low, z_high)) { + ExPolygon expoly; + expoly.contour = {{scale_(instance_bbox.min.x()), scale_(instance_bbox.min.y())}, + {scale_(instance_bbox.max.x()), scale_(instance_bbox.min.y())}, + {scale_(instance_bbox.max.x()), scale_(instance_bbox.max.y())}, + {scale_(instance_bbox.min.x()), scale_(instance_bbox.max.y())}}; + expoly.contour = expand_object_projection(expoly.contour, by_object, higher_than_curr_pos); + unclear_area.emplace_back(std::move(expoly)); + } + } + } + + Point curr_pos_in_plate = {ctx.curr_pos.x() - scale_(m_plate_offset.x()), ctx.curr_pos.y() - scale_(m_plate_offset.y())}; + for (const ExPolygon &expoly : unclear_area) { + BoundingBox bbox = expoly.contour.bounding_box(); + if (curr_pos_in_plate.y() < bbox.min.y() || curr_pos_in_plate.y() > bbox.max.y()) continue; + if (bbox.min.x() <= curr_pos_in_plate.x()) return false; + } + + return true; + } + } \ No newline at end of file diff --git a/src/libslic3r/GCode/TimelapsePosPicker.hpp b/src/libslic3r/GCode/TimelapsePosPicker.hpp index c4930b3022..9ed6b14fc7 100644 --- a/src/libslic3r/GCode/TimelapsePosPicker.hpp +++ b/src/libslic3r/GCode/TimelapsePosPicker.hpp @@ -22,6 +22,9 @@ namespace Slic3r { int picture_extruder_id; // the extruder id to take picture int curr_extruder_id; std::optional> printed_objects; // printed objects, only have value in by object mode + // Farthest-point timelapse: plate-relative scaled point; when set, pick_pos_internal + // biases the picked snapshot position toward this point (nullopt → legacy camera-occlusion loss). + std::optional farthest_point; }; // data are stored without plate offset @@ -32,6 +35,9 @@ namespace Slic3r { ~TimelapsePosPicker() = default; Point pick_pos(const PosPickCtx& ctx); + // Is the path to X0 clear of other (taller) instances? Drives the + // `clear_to_x0` timelapse-gcode variable (g39 clamping detection). + bool get_is_clear_to_x0(const PosPickCtx& ctx); void init(const Print* print, const Point& plate_offset); void reset(); private: diff --git a/src/libslic3r/GCode/ToolOrderUtils.cpp b/src/libslic3r/GCode/ToolOrderUtils.cpp index 5a6e9059f2..c8b8ac3fdc 100644 --- a/src/libslic3r/GCode/ToolOrderUtils.cpp +++ b/src/libslic3r/GCode/ToolOrderUtils.cpp @@ -7,13 +7,100 @@ namespace Slic3r { +// ==================== MaxFlowWithLowerBounds ==================== + struct MaxFlowWithLowerBounds { + public: + + void add_edge(int from, int to, int capacity); + + bool bfs(); + int dfs(int u, int f); + int solve(std::vector& matching); + + public: + std::vector l_nodes; + std::vector r_nodes; + std::vector edges; + std::vector> adj; + std::vector level; + std::vector it; + + int total_nodes{ -1 }; + int source_id{ -1 }; + int sink_id{ -1 }; + }; + + void MaxFlowWithLowerBounds::add_edge(int from, int to, int capacity) + { + adj[from].emplace_back(edges.size()); + edges.emplace_back(from, to, capacity, 0); + // also add the reverse residual edge with zero capacity + adj[to].emplace_back(edges.size()); + edges.emplace_back(to, from, 0, 0); + } + + bool MaxFlowWithLowerBounds::bfs() { + level.assign(total_nodes, -1); + std::queue q; + q.push(source_id); + level[source_id] = 0; + + while (!q.empty()) { + int u = q.front(); q.pop(); + for (int eid : adj[u]) { + Edge &e = edges[eid]; + if (e.flow < e.capacity && level[e.to] == -1) { + level[e.to] = level[u] + 1; + q.push(e.to); + } + } + } + return level[sink_id] != -1; + } + + int MaxFlowWithLowerBounds::dfs(int u, int f) { + if (u == sink_id) return f; + for (int &i = it[u]; i < (int)adj[u].size(); ++i) { + int eid = adj[u][i]; + Edge &e = edges[eid]; + if (e.flow < e.capacity && level[e.to] == level[u] + 1) { + int pushed = dfs(e.to, std::min(f, e.capacity - e.flow)); + if (pushed > 0) { + e.flow += pushed; + edges[eid ^ 1].flow -= pushed; + return pushed; + } + } + } + return 0; + } + + int MaxFlowWithLowerBounds::solve(std::vector& matching) { + int flow = 0; + while (bfs()) { + it.assign(total_nodes, 0); + while (int pushed = dfs(source_id, MaxFlowGraph::INF)) + flow += pushed; + } + + int L = l_nodes.size(); + int R = r_nodes.size(); + // collect l-r matches + matching.resize(l_nodes.size(), MaxFlowGraph::INVALID_ID); + for (int u = 0; u < L; ++u) { + for (int eid : adj[u]) { + Edge &e = edges[eid]; + if (e.flow > 0 && e.to >= L && e.to < L + R) { + matching[e.from] = e.to - L; + } + } + } + return flow; + } + +// ==================== MinCostMaxFlow ==================== struct MinCostMaxFlow { public: - struct Edge { - int from, to, capacity, cost, flow; - Edge(int u, int v, int cap, int cst) : from(u), to(v), capacity(cap), cost(cst), flow(0) {} - }; - std::vector solve(); void add_edge(int from, int to, int capacity, int cost); bool spfa(int source, int sink); @@ -107,15 +194,10 @@ namespace Slic3r { if (l_nodes[idx_in_left] == -1) { return 0; - //TODO: test more here - int sum = 0; - for (int i = 0; i < matrix.size(); ++i) - sum += matrix[i][idx_in_right]; - sum /= matrix.size(); - return -sum; } - return matrix[l_nodes[idx_in_left]][r_nodes[idx_in_right]]; + float val = matrix[l_nodes[idx_in_left]][r_nodes[idx_in_right]]; + return std::min(static_cast(val), MaxFlowGraph::MCMF_MAX_EDGE_COST); } @@ -123,27 +205,40 @@ namespace Slic3r const std::unordered_map>& uv_link_limits, const std::unordered_map>& uv_unlink_limits, const std::vector& u_capacity, - const std::vector& v_capacity) + const std::vector& v_capacity, + const std::vector,int>>& v_group_capacity) { assert(u_capacity.empty() || u_capacity.size() == u_nodes.size()); assert(v_capacity.empty() || v_capacity.size() == v_nodes.size()); l_nodes = u_nodes; r_nodes = v_nodes; - total_nodes = u_nodes.size() + v_nodes.size() + 2; + total_nodes = u_nodes.size() + v_nodes.size() + v_group_capacity.size() + 2; source_id = total_nodes - 2; sink_id = total_nodes - 1; adj.resize(total_nodes); + std::vectorv_node_to(v_nodes.size(), sink_id); + for (size_t gid = 0; gid < v_group_capacity.size(); ++gid) { + for (auto vid : v_group_capacity[gid].first) + v_node_to[vid] = l_nodes.size() + r_nodes.size() + gid; + } + // add edge from source to left nodes for (int idx = 0; idx < l_nodes.size(); ++idx) { int capacity = u_capacity.empty() ? 1 : u_capacity[idx]; add_edge(source_id, idx, capacity); } - // add edge from right nodes to sink node + // add edge from right nodes to v_node_to(sink node or temp group node) for (int idx = 0; idx < r_nodes.size(); ++idx) { int capacity = v_capacity.empty() ? 1 : v_capacity[idx]; - add_edge(l_nodes.size() + idx, sink_id, capacity); + add_edge(l_nodes.size() + idx, v_node_to[idx], capacity); + } + + // add edge from temp group node to sink node + for (int idx = 0; idx < v_group_capacity.size(); ++idx) { + int capacity = v_group_capacity[idx].second; + add_edge(l_nodes.size() + r_nodes.size() + idx, sink_id, capacity); } // add edge from left nodes to right nodes @@ -269,6 +364,301 @@ namespace Slic3r return m_solver->solve(); } +// ==================== GeneralMinCostLowerBoundsSolver ==================== + GeneralMinCostLowerBoundsSolver::~GeneralMinCostLowerBoundsSolver() = default; + + GeneralMinCostLowerBoundsSolver::GeneralMinCostLowerBoundsSolver(const std::vector &matrix_, + const std::vector &u_nodes, + const std::vector &v_nodes, + const std::vector &v_nodes_group, + const std::unordered_map> &uv_link_limits, + const std::unordered_map> &uv_unlink_limits) + { + flush_matrix = matrix_; + l_nodes = u_nodes; + r_nodes = v_nodes; + r_nodes_group = v_nodes_group; + m_uv_link_limits = uv_link_limits; + m_uv_unlink_limits = uv_unlink_limits; + num_groups = *std::max_element(r_nodes_group.begin(), r_nodes_group.end()) + 1; + + m_solver_lower_bounds = std::make_unique(); + m_solver_min_cost = std::make_unique(); + } + + std::vector GeneralMinCostLowerBoundsSolver::solve() + { + // group nodes that do not need a lower-bound constraint + std::unordered_set no_lower_group; + for (int i = 0; i < r_nodes.size(); i++) { + if (r_nodes[i] >= 0) + no_lower_group.insert(r_nodes_group[i]); + } + + // 1. build the lower-bound network graph + build_feasible_graph(no_lower_group); + + // 2. compute the max flow + int need = 0; + for (int d : demand) + if (d > 0) need += d; + std::vector feasible_matching; + int pushed_flow = m_solver_lower_bounds->solve(feasible_matching); + assert(need == pushed_flow); + + // 3. convert the lower-bound max-flow network into a min-cost-max-flow network + build_graph_with_feasible_result(); + // 4. compute the min-cost max-flow + auto min_cost_matching = m_solver_min_cost->solve(); + + return min_cost_matching; + } + + void GeneralMinCostLowerBoundsSolver::build_feasible_graph(const std::unordered_set &no_lower_groups) + { + m_solver_lower_bounds->l_nodes = l_nodes; + m_solver_lower_bounds->r_nodes = r_nodes; + m_solver_lower_bounds->total_nodes = l_nodes.size() + r_nodes.size() + num_groups + 2; + + m_solver_lower_bounds->source_id = m_solver_lower_bounds->total_nodes - 2; + m_solver_lower_bounds->sink_id = m_solver_lower_bounds->total_nodes - 1; + m_solver_lower_bounds->adj.resize(m_solver_lower_bounds->total_nodes); + demand.resize(m_solver_lower_bounds->total_nodes, 0); + + const int L = m_solver_lower_bounds->l_nodes.size(); + const int R = m_solver_lower_bounds->r_nodes.size(); + + // source -> l + for (int i = 0; i < L; ++i) + m_solver_lower_bounds->add_edge(m_solver_lower_bounds->source_id, i, 1); + + // u -> v (with link/unlink limits) + for (int i = 0; i < L; ++i) { + if (auto it = m_uv_link_limits.find(i); it != m_uv_link_limits.end()) { + for (int j : it->second) + m_solver_lower_bounds->add_edge(i, L + j, 1); + continue; + } + + std::optional> unlink_limits; + if (auto it = m_uv_unlink_limits.find(i); it != m_uv_unlink_limits.end()) + unlink_limits = it->second; + + for (int j = 0; j < R; ++j) { + if (unlink_limits.has_value() && std::find(unlink_limits->begin(), unlink_limits->end(), j) != unlink_limits->end()) + continue; + m_solver_lower_bounds->add_edge(i, L + j, 1); + } + } + + // r -> group + for (int j = 0; j < R; ++j) { + int g = r_nodes_group[j]; + m_solver_lower_bounds->add_edge(L + j, L + R + g, 1); + } + + // group -> sink (lower bound = 1) + for (int g = 0; g < num_groups; ++g) { + if (no_lower_groups.count(g)) + m_solver_lower_bounds->add_edge(L + R + g, m_solver_lower_bounds->sink_id, R); + else + add_edge_with_lower_bound(L + R + g, m_solver_lower_bounds->sink_id, 1, R, 0); + } + + max_flow_edges = m_solver_lower_bounds->edges.size(); + + // support lower bounds, add super source super sink + super_source = m_solver_lower_bounds->total_nodes++; + super_sink = m_solver_lower_bounds->total_nodes++; + + m_solver_lower_bounds->adj.resize(m_solver_lower_bounds->total_nodes); + demand.resize(m_solver_lower_bounds->total_nodes, 0); + + for (int i = 0; i < super_source; ++i) { + if (demand[i] > 0) { + m_solver_lower_bounds->add_edge(super_source, i, demand[i]); + } else if (demand[i] < 0) { + m_solver_lower_bounds->add_edge(i, super_sink, -demand[i]); + } + } + m_solver_lower_bounds->add_edge(m_solver_lower_bounds->sink_id, m_solver_lower_bounds->source_id, MaxFlowGraph::INF); + source_id = m_solver_lower_bounds->source_id; + sink_id = m_solver_lower_bounds->sink_id; + m_solver_lower_bounds->source_id = super_source; + m_solver_lower_bounds->sink_id = super_sink; + } + + void GeneralMinCostLowerBoundsSolver::build_graph_with_feasible_result() + { + for (auto&lb:lower_bound_edges){ + m_solver_lower_bounds->edges[lb.edge_id].flow += lb.lower; + m_solver_lower_bounds->edges[lb.edge_id ^ 1].flow -= lb.lower; + } + + m_solver_min_cost->l_nodes = m_solver_lower_bounds->l_nodes; + m_solver_min_cost->r_nodes = m_solver_lower_bounds->r_nodes; + + m_solver_min_cost->source_id = source_id; + m_solver_min_cost->sink_id = sink_id; + m_solver_min_cost->total_nodes = sink_id + 1; + + m_solver_min_cost->edges = m_solver_lower_bounds->edges; + m_solver_min_cost->edges.erase(m_solver_min_cost->edges.begin() + max_flow_edges, m_solver_min_cost->edges.end()); + + m_solver_min_cost->adj = m_solver_lower_bounds->adj; + m_solver_min_cost->adj.resize(m_solver_min_cost->total_nodes); + for (auto &node_edges : m_solver_min_cost->adj) { + node_edges.erase(std::remove_if(node_edges.begin(), node_edges.end(), [this](int val) {return val >= this->max_flow_edges;}), node_edges.end()); + } + + + for (auto& e : m_solver_min_cost->edges) { + int L = m_solver_min_cost->l_nodes.size(); + int R = m_solver_min_cost->r_nodes.size(); + + if (e.from < L && e.to >= L && e.to < L + R) { + int idx_in_left = e.from; + int idx_in_right = e.to - L; + int group_id = r_nodes_group[idx_in_right]; + + if (r_nodes[idx_in_right] == -1) continue; + e.cost = flush_matrix[group_id][l_nodes[idx_in_left]][r_nodes[idx_in_right]]; + } + } + } + void GeneralMinCostLowerBoundsSolver::add_edge_with_lower_bound(int from, int to, int lower, int upper, int cost) + { + int eid = m_solver_lower_bounds->edges.size(); + m_solver_lower_bounds->add_edge(from, to, upper - lower); + + lower_bound_edges.push_back({eid, lower}); + demand[from] -= lower; + demand[to] += lower; + } + +// ==================== GroupMinCostFlowSolver ==================== + GroupMinCostFlowSolver::~GroupMinCostFlowSolver() = default; + + GroupMinCostFlowSolver::GroupMinCostFlowSolver(const std::vector &matrix_, + const std::vector &u_nodes, + const std::vector &v_nodes, + const std::vector &v_nodes_group, + const std::unordered_map> &uv_link_limits, + const std::unordered_map> &uv_unlink_limits) + { + flush_matrix = matrix_; + l_nodes = u_nodes; + r_nodes = v_nodes; + r_nodes_group = v_nodes_group; + m_uv_link_limits = uv_link_limits; + m_uv_unlink_limits = uv_unlink_limits; + num_groups = *std::max_element(r_nodes_group.begin(), r_nodes_group.end()) + 1; + + m_solver = std::make_unique(); + build_graph(); + } + + int GroupMinCostFlowSolver::get_flush_cost(int l_idx, int r_idx) + { + if (r_nodes[r_idx] == -1) + return 0; + int group_id = r_nodes_group[r_idx]; + return (int)flush_matrix[group_id][l_nodes[l_idx]][r_nodes[r_idx]]; + } + + void GroupMinCostFlowSolver::build_graph() + { + const int L = (int)l_nodes.size(); + const int R = (int)r_nodes.size(); + const int G = num_groups; + + m_solver->l_nodes = l_nodes; + m_solver->r_nodes = r_nodes; + m_solver->total_nodes = L + R + G + 2; + m_solver->source_id = L + R + G; + m_solver->sink_id = L + R + G + 1; + m_solver->adj.resize(m_solver->total_nodes); + + int max_flush = 0; + for (const auto &mat : flush_matrix) + for (const auto &row : mat) + for (float v : row) + max_flush = std::max(max_flush, (int)v); + int bonus = max_flush * L + 1; + + // source -> l_i + for (int i = 0; i < L; ++i) + m_solver->add_edge(m_solver->source_id, i, 1, 0); + + // l_i -> r_j (with link/unlink limits) + for (int i = 0; i < L; ++i) { + if (auto it = m_uv_link_limits.find(i); it != m_uv_link_limits.end()) { + for (int j : it->second) + m_solver->add_edge(i, L + j, 1, get_flush_cost(i, j)); + continue; + } + + std::optional> unlink_limits; + if (auto it = m_uv_unlink_limits.find(i); it != m_uv_unlink_limits.end()) + unlink_limits = it->second; + + for (int j = 0; j < R; ++j) { + if (unlink_limits.has_value() && std::find(unlink_limits->begin(), unlink_limits->end(), j) != unlink_limits->end()) + continue; + m_solver->add_edge(i, L + j, 1, get_flush_cost(i, j)); + } + } + + // r_j -> group_g + // Compute per-nozzle incoming edge count as capacity upper bound. + // When unlink_limits restrict multiple filaments to the same nozzle, + // capacity=1 would block valid assignments. Using the actual in-degree + // allows the necessary flow while still preserving nozzle-level balance + // (a nozzle with fewer forced filaments keeps a tighter cap). + // The first unit carries a small nozzle-bonus to encourage spreading + // filaments across distinct nozzles within the same group. + int nozzle_bonus = max_flush + 1; + std::vector r_in_degree(R, 0); + for (int i = 0; i < L; ++i) { + if (auto it = m_uv_link_limits.find(i); it != m_uv_link_limits.end()) { + for (int j : it->second) + r_in_degree[j]++; + continue; + } + std::optional> unlink_limits; + if (auto it = m_uv_unlink_limits.find(i); it != m_uv_unlink_limits.end()) + unlink_limits = it->second; + for (int j = 0; j < R; ++j) { + if (unlink_limits.has_value() && std::find(unlink_limits->begin(), unlink_limits->end(), j) != unlink_limits->end()) + continue; + r_in_degree[j]++; + } + } + + for (int j = 0; j < R; ++j) { + int g = r_nodes_group[j]; + int cap = std::max(r_in_degree[j], 1); + // First unit gets -nozzle_bonus to prefer using distinct nozzles + m_solver->add_edge(L + j, L + R + g, 1, -nozzle_bonus); + if (cap > 1) + m_solver->add_edge(L + j, L + R + g, cap - 1, 0); + } + + // group_g -> sink (split: first unit gets -bonus, rest gets 0) + // bonus >> nozzle_bonus, so group coverage always takes priority + for (int g = 0; g < G; ++g) { + m_solver->add_edge(L + R + g, m_solver->sink_id, 1, -bonus); + if (L > 1) + m_solver->add_edge(L + R + g, m_solver->sink_id, L - 1, 0); + } + } + + std::vector GroupMinCostFlowSolver::solve() + { + return m_solver->solve(); + } + +// ==================== MinFlushFlowSolver ==================== MinFlushFlowSolver::~MinFlushFlowSolver() { } @@ -277,7 +667,8 @@ namespace Slic3r const std::unordered_map>& uv_link_limits, const std::unordered_map>& uv_unlink_limits, const std::vector& u_capacity, - const std::vector& v_capacity) + const std::vector& v_capacity, + const std::vector,int>>&v_group_capacity) { assert(u_capacity.empty() || u_capacity.size() == u_nodes.size()); assert(v_capacity.empty() || v_capacity.size() == v_nodes.size()); @@ -286,13 +677,19 @@ namespace Slic3r m_solver->l_nodes = u_nodes; m_solver->r_nodes = v_nodes; - m_solver->total_nodes = u_nodes.size() + v_nodes.size() + 2; + m_solver->total_nodes = u_nodes.size() + v_nodes.size() + v_group_capacity.size() + 2; m_solver->source_id =m_solver->total_nodes - 2; m_solver->sink_id = m_solver->total_nodes - 1; m_solver->adj.resize(m_solver->total_nodes); + std::vector v_node_to(v_nodes.size(), m_solver->sink_id); + for (size_t gid = 0; gid < v_group_capacity.size(); ++gid) { + for (auto vid : v_group_capacity[gid].first) + v_node_to[vid] = m_solver->l_nodes.size() + m_solver->r_nodes.size() + gid; + } + // add edge from source to left nodes,cost to 0 for (int i = 0; i < m_solver->l_nodes.size(); ++i) { int capacity = u_capacity.empty() ? 1 : u_capacity[i]; @@ -301,7 +698,12 @@ namespace Slic3r // add edge from right nodes to sink,cost to 0 for (int i = 0; i < m_solver->r_nodes.size(); ++i) { int capacity = v_capacity.empty() ? 1 : v_capacity[i]; - m_solver->add_edge(m_solver->l_nodes.size() + i, m_solver->sink_id, capacity, 0); + m_solver->add_edge(m_solver->l_nodes.size() + i, v_node_to[i], capacity, 0); + } + // add edge from temp group node to sink node + for(int i=0;iadd_edge(m_solver->l_nodes.size() + m_solver->r_nodes.size() + i, m_solver->sink_id, capacity, 0); } // add edge from left node to right nodes for (int i = 0; i < m_solver->l_nodes.size(); ++i) { @@ -602,12 +1004,125 @@ namespace Slic3r } + // Single-nozzle flush-minimizing reorder over one filament set / one flush matrix, with an + // optional seed filament. Extracted from the group loop so the multi-nozzle reorder can call it + // per physical nozzle. + // TODO: add custom sequence + static int reorder_filaments_for_minimum_flush_volume_base(const std::vector& filament_lists, + const std::vector>& layer_filaments, + const FlushMatrix& flush_matrix, + const std::function&)> get_custom_seq, + std::vector>* filament_sequences, + std::optional initial_filament_id = std::nullopt) + { + constexpr int max_n_with_forcast = 5; + using uint128_t = boost::multiprecision::uint128_t; + + if (filament_sequences) { + filament_sequences->clear(); + filament_sequences->reserve(layer_filaments.size()); + } + auto filament_list_to_hash_key = [](const std::vector& curr_layer_filaments, const std::vector& next_layer_filaments, + const std::optional& prev_filament, bool use_forcast) -> uint128_t { + uint128_t hash_key = 0; + // 31-0 bit define current layer extruder,63-32 bit define next layer extruder,95~64 define prev extruder + if (prev_filament) hash_key |= (uint128_t(1) << (64 + *prev_filament)); + + if (use_forcast) { + for (auto item : next_layer_filaments) { hash_key |= (uint128_t(1) << (32 + item)); } + } + + for (auto item : curr_layer_filaments) { hash_key |= (uint128_t(1) << item); } + return hash_key; + }; + + int cost = 0; + std::map> custom_layer_sequence_map; + std::unordered_map>> caches; + std::unordered_set filament_sets(filament_lists.begin(), filament_lists.end()); + std::optional curr_filament_id; + // use the provided initial filament id as the starting state when it is valid + if (initial_filament_id.has_value() && *initial_filament_id < flush_matrix.size()) { + curr_filament_id = initial_filament_id; + } + + for (size_t layer = 0; layer < layer_filaments.size(); ++layer){ + const auto& curr_lf = layer_filaments[layer]; + std::vector custom_filament_seq; + if (get_custom_seq && get_custom_seq(layer, custom_filament_seq) && !custom_filament_seq.empty()) { + std::vector unsign_custom_extruder_seq; + for (int extruder : custom_filament_seq) { + unsigned int unsign_extruder = static_cast(extruder) - 1; + auto it = std::find(layer_filaments[layer].begin(), layer_filaments[layer].end(), unsign_extruder); + if (it != layer_filaments[layer].end()) + unsign_custom_extruder_seq.emplace_back(unsign_extruder); + } + assert(layer_filaments[layer].size() == unsign_custom_extruder_seq.size()); + + custom_layer_sequence_map[layer] = unsign_custom_extruder_seq; + } + } + + for (size_t layer = 0; layer < layer_filaments.size(); ++layer) { + const auto& curr_lf = layer_filaments[layer]; + + if(auto iter = custom_layer_sequence_map.find(layer); iter != custom_layer_sequence_map.end()){ + auto sequence_in_group = collect_filaments_in_groups(std::unordered_set(filament_lists.begin(),filament_lists.end()), iter->second); + + std::optional prev = curr_filament_id; + for (auto& f: sequence_in_group){ + if(prev) + cost += flush_matrix[*prev][f]; + prev = f; + } + + if(!sequence_in_group.empty()){ + curr_filament_id = sequence_in_group.back(); + } + + if(filament_sequences) + filament_sequences->emplace_back(sequence_in_group); + + continue; + } + + std::vector filament_used = collect_filaments_in_groups(filament_sets, curr_lf); + std::vector next_lf; + if (layer + 1 < layer_filaments.size()) next_lf = layer_filaments[layer + 1]; + std::vector filament_used_next_layer = collect_filaments_in_groups(filament_sets, next_lf); + + bool use_forcast = false; + float tmp_cost = 0; + std::vector sequence; + uint128_t hash_key = filament_list_to_hash_key(filament_used, filament_used_next_layer, curr_filament_id, use_forcast); + if (auto iter = caches.find(hash_key); iter != caches.end()) { + tmp_cost = iter->second.first; + sequence = iter->second.second; + } + else { + sequence = get_extruders_order(flush_matrix, filament_used, filament_used_next_layer, curr_filament_id, use_forcast, &tmp_cost); + caches[hash_key] = { tmp_cost,sequence }; + } + + if (filament_sequences) + filament_sequences->emplace_back(sequence); + + if (!sequence.empty()) + curr_filament_id = sequence.back(); + + cost += tmp_cost; + } + + return cost; + } + int reorder_filaments_for_minimum_flush_volume(const std::vector& filament_lists, const std::vector& filament_maps, const std::vector>& layer_filaments, const std::vector& flush_matrix, std::optional&)>> get_custom_seq, - std::vector>* filament_sequences) + std::vector>* filament_sequences, + const std::unordered_map& nozzle_status) { //only when layer filament num <= 5,we do forcast constexpr int max_n_with_forcast = 5; @@ -670,6 +1185,12 @@ namespace Slic3r if (groups[idx].empty()) continue; std::optionalcurrent_extruder_id; + // seed the group (nozzle) with the filament already loaded, if nozzle_status supplies one + if (auto it = nozzle_status.find(static_cast(idx)); it != nozzle_status.end() && it->second >= 0) { + unsigned int initial_fil = static_cast(it->second); + if (initial_fil < flush_matrix[idx].size()) + current_extruder_id = initial_fil; + } std::unordered_map>> caches; @@ -775,4 +1296,174 @@ namespace Slic3r return cost; } + + int reorder_filaments_for_multi_nozzle_extruder(const std::vector& filament_lists, + const MultiNozzleUtils::LayeredNozzleGroupResult& nozzle_group_result, + const std::vector>& layer_filaments, + const std::vector& flush_matrix, + const std::function&)> get_custom_seq, + std::vector>* filament_sequences, + const MultiNozzleUtils::NozzleStatusRecorder& initial_status) + { + std::map> nozzle_filament_groups; + std::map> extruder_to_nozzle; + + for(auto filament_idx : filament_lists){ + auto nozzle_info = nozzle_group_result.get_nozzle_for_filament(filament_idx, -1); + if (!nozzle_info) + continue; + nozzle_filament_groups[nozzle_info->group_id].insert(filament_idx); + extruder_to_nozzle[nozzle_info->extruder_id].insert(nozzle_info->group_id); + } + + std::map>custom_layer_sequence_map;// save the filament sequences of custom layer + for (size_t layer = 0; layer < layer_filaments.size(); ++layer){ + const auto& curr_lf = layer_filaments[layer]; + std::vector custom_filament_seq; + if (get_custom_seq && get_custom_seq(layer, custom_filament_seq) && !custom_filament_seq.empty()) { + std::vector unsign_custom_extruder_seq; + for (int extruder : custom_filament_seq) { + unsigned int unsign_extruder = static_cast(extruder) - 1; + auto it = std::find(layer_filaments[layer].begin(), layer_filaments[layer].end(), unsign_extruder); + if (it != layer_filaments[layer].end()) + unsign_custom_extruder_seq.emplace_back(unsign_extruder); + } + assert(layer_filaments[layer].size() == unsign_custom_extruder_seq.size()); + + custom_layer_sequence_map[layer] = unsign_custom_extruder_seq; + } + } + + + std::map>> nozzle_filament_sequences; + bool store_sequence = filament_sequences != nullptr; + + int cost = 0; + for(auto& group : nozzle_filament_groups){ + int nozzle_id = group.first; + auto& filament_in_nozzle = group.second; + + int extruder_id = 0; + for(auto& [ext, nozzle_set] : extruder_to_nozzle){ + if(nozzle_set.count(nozzle_id)){ + extruder_id = ext; + break; + } + } + + if(filament_in_nozzle.empty()) + continue; + + std::vector filament_vec_in_nozzle(filament_in_nozzle.begin(), filament_in_nozzle.end()); + + int initial_fil = initial_status.get_filament_in_nozzle(nozzle_id); + std::optional initial_fil_id = (initial_fil >= 0 && initial_fil < flush_matrix[extruder_id].size())? std::optional(initial_fil) : std::nullopt; + + std::vector> filament_seq; + cost += reorder_filaments_for_minimum_flush_volume_base(filament_vec_in_nozzle, layer_filaments, flush_matrix[extruder_id], get_custom_seq, + store_sequence ? &filament_seq : nullptr, initial_fil_id); + if(store_sequence) + nozzle_filament_sequences.emplace(nozzle_id, std::move(filament_seq)); + + } + + if(!store_sequence) + return cost; + + std::vector extruders; + std::map> nozzles_per_extruder; + for (auto& [extruder_id, nozzle_set] : extruder_to_nozzle) { + extruders.push_back(extruder_id); + nozzles_per_extruder[extruder_id] = std::vector( + nozzle_set.begin(), nozzle_set.end() + ); + } + + filament_sequences->clear(); + filament_sequences->resize(layer_filaments.size()); + + // No filament in filament_lists resolved to a nozzle in nozzle_group_result + // (e.g. a degenerate input where a layer references a filament index outside the range's + // grouping map). Emit each layer's filaments in their given order so the caller still gets a + // valid per-layer sequence, and skip the cross-nozzle reorder. Guards the unchecked + // max_element(extruders) below, which would dereference end() on an empty range. + if (extruders.empty()) { + for (size_t layer = 0; layer < layer_filaments.size(); ++layer) + (*filament_sequences)[layer] = layer_filaments[layer]; + return cost; + } + + auto get_extruder_for_filament = [nozzle_group_result](unsigned int filament_idx) { + auto nozzle = nozzle_group_result.get_nozzle_for_filament(filament_idx, -1); + if (!nozzle) + return -1; + return nozzle->extruder_id; + }; + + auto get_nozzle_idx_for_filament = [nozzles_per_extruder, nozzle_group_result](unsigned int filament_idx)->int { + auto nozzle = nozzle_group_result.get_nozzle_for_filament(filament_idx, -1); + if (!nozzle) + return -1; + return std::find(nozzles_per_extruder.at(nozzle->extruder_id).begin(), nozzles_per_extruder.at(nozzle->extruder_id).end(), nozzle->group_id) - nozzles_per_extruder.at(nozzle->extruder_id).begin(); + }; + + int initial_extruder = initial_status.get_current_extruder_id(); + int last_extruder_idx = (initial_extruder >= 0 && initial_extruder < extruders.size())? initial_extruder : 0; + // set size to max extruder_id in case extruder_id is not continuous + std::vector last_nozzle_idx(*std::max_element(extruders.begin(),extruders.end()) + 1,0); + for (int ext_id = 0; ext_id < static_cast(last_nozzle_idx.size()); ext_id++) { + int initial_nozzle = initial_status.get_nozzle_in_extruder(ext_id); + auto ext_nozzles = nozzles_per_extruder[ext_id]; + auto it = std::find(ext_nozzles.begin(), ext_nozzles.end(), initial_nozzle); + if (it != ext_nozzles.end()) + last_nozzle_idx[ext_id] = static_cast(std::distance(ext_nozzles.begin(), it)); + } + + for (size_t layer = 0; layer < layer_filaments.size(); ++layer) { + auto& out_seq = (*filament_sequences)[layer]; + + if (custom_layer_sequence_map.find(layer) != custom_layer_sequence_map.end()) { + out_seq = custom_layer_sequence_map[layer]; + if (!out_seq.empty()) { + last_extruder_idx = get_extruder_for_filament(out_seq.back()); + for (auto filament : out_seq) { + int cur_ext_id = get_extruder_for_filament(filament); + last_nozzle_idx[cur_ext_id] = get_nozzle_idx_for_filament(filament); + } + } + continue; + } + + if (last_extruder_idx == -1) + last_extruder_idx = 0; + + int curr_last_extruder_idx = last_extruder_idx; + auto curr_last_nozzle_idx = last_nozzle_idx; + for (int i = 0; i < extruders.size(); ++i) { + int extruder_id = extruders[(last_extruder_idx + i) % extruders.size()]; + auto& base_nozzles = nozzles_per_extruder[extruder_id]; + + bool has_seq = false; + if (last_nozzle_idx[extruder_id] == -1) + last_nozzle_idx[extruder_id] = 0; + + for (int j = 0; j < base_nozzles.size(); ++j) { + int nozzle_idx = (last_nozzle_idx[extruder_id] + j) % base_nozzles.size(); + int nozzle_id = base_nozzles[nozzle_idx]; + const auto& frag = nozzle_filament_sequences[nozzle_id][layer]; + if (frag.empty()) + continue; + has_seq = true; + curr_last_nozzle_idx[extruder_id] = nozzle_idx; + out_seq.insert(out_seq.end(), frag.begin(), frag.end()); + } + + if (has_seq) + curr_last_extruder_idx = extruder_id; + } + last_extruder_idx = curr_last_extruder_idx; + last_nozzle_idx = curr_last_nozzle_idx; + } + return cost; + } } diff --git a/src/libslic3r/GCode/ToolOrderUtils.hpp b/src/libslic3r/GCode/ToolOrderUtils.hpp index 26c9a01186..7b103531b1 100644 --- a/src/libslic3r/GCode/ToolOrderUtils.hpp +++ b/src/libslic3r/GCode/ToolOrderUtils.hpp @@ -6,7 +6,10 @@ #include #include #include +#include #include +#include +#include "../MultiNozzleUtils.hpp" namespace Slic3r { @@ -15,21 +18,27 @@ using FlushMatrix = std::vector>; namespace MaxFlowGraph { const int INF = std::numeric_limits::max(); const int INVALID_ID = -1; + // Upper bound for MCMF edge cost to prevent int overflow in SPFA causing infinite loops + constexpr int MCMF_MAX_EDGE_COST = 10000000; } +// Namespace-scope edge shared by the max-flow / min-cost-max-flow solvers below. +// The default cost keeps the plain max-flow solvers (which never read cost) source-compatible. +struct Edge +{ + int from, to, capacity, cost, flow; + Edge(int u, int v, int cap, int cst = 0) : from(u), to(v), capacity(cap), cost(cst), flow(0) {} +}; + class MaxFlowSolver { -private: - struct Edge { - int from, to, capacity, flow; - Edge(int u, int v, int cap) :from(u), to(v), capacity(cap), flow(0) {} - }; public: MaxFlowSolver(const std::vector& u_nodes, const std::vector& v_nodes, const std::unordered_map>& uv_link_limits = {}, const std::unordered_map>& uv_unlink_limits = {}, const std::vector& u_capacity = {}, - const std::vector& v_capacity = {} + const std::vector& v_capacity = {}, + const std::vector, int>>& v_group_capacity = {} ); std::vector solve(); @@ -47,6 +56,7 @@ private: struct MinCostMaxFlow; +struct MaxFlowWithLowerBounds; class GeneralMinCostSolver { @@ -61,6 +71,84 @@ private: std::unique_ptr m_solver; }; +class GeneralMinCostLowerBoundsSolver +{ +public: + GeneralMinCostLowerBoundsSolver( + const std::vector &matrix_, + const std::vector& u_nodes, + const std::vector& v_nodes, + const std::vector& v_nodes_group, + const std::unordered_map>& uv_link_limits = {}, + const std::unordered_map>& uv_unlink_limits = {}); + + std::vector solve(); + ~GeneralMinCostLowerBoundsSolver(); + +private: + void build_feasible_graph(const std::unordered_set& no_lower_groups); + + void build_graph_with_feasible_result(); + + void add_edge_with_lower_bound(int from, int to, int lower, int upper, int cost); + + int get_distance(const int idx_in_left,const int idx_in_right); + +private: + std::unique_ptr m_solver_lower_bounds; + std::unique_ptr m_solver_min_cost; + + std::vector flush_matrix; + std::vector l_nodes; + std::vector r_nodes; + std::vector r_nodes_group; + std::unordered_map> m_uv_link_limits; + std::unordered_map> m_uv_unlink_limits; + int num_groups = 0; + + // support lower bounds + struct LowerBoundEdge{ + int edge_id; + int lower; + }; + + std::vector demand; + std::vector lower_bound_edges; + + int super_source = -1; + int super_sink = -1; + int source_id = -1; + int sink_id = -1; + int max_flow_edges = 0; +}; + +class GroupMinCostFlowSolver +{ +public: + GroupMinCostFlowSolver( + const std::vector &matrix_, + const std::vector &u_nodes, + const std::vector &v_nodes, + const std::vector &v_nodes_group, + const std::unordered_map> &uv_link_limits = {}, + const std::unordered_map> &uv_unlink_limits = {}); + + std::vector solve(); + ~GroupMinCostFlowSolver(); + +private: + void build_graph(); + int get_flush_cost(int l_idx, int r_idx); + + std::unique_ptr m_solver; + std::vector flush_matrix; + std::vector l_nodes; + std::vector r_nodes; + std::vector r_nodes_group; + std::unordered_map> m_uv_link_limits; + std::unordered_map> m_uv_unlink_limits; + int num_groups = 0; +}; class MinFlushFlowSolver { @@ -71,7 +159,8 @@ public: const std::unordered_map>& uv_link_limits = {}, const std::unordered_map>& uv_unlink_limits = {}, const std::vector& u_capacity = {}, - const std::vector& v_capacity = {} + const std::vector& v_capacity = {}, + const std::vector, int>>& v_group_capacity = {} ); std::vector solve(); ~MinFlushFlowSolver(); @@ -108,7 +197,19 @@ int reorder_filaments_for_minimum_flush_volume(const std::vector & const std::vector> &layer_filaments, const std::vector &flush_matrix, std::optional &)>> get_custom_seq, - std::vector> *filament_sequences); + std::vector> *filament_sequences, + const std::unordered_map& nozzle_status = {}); + +// Order filaments within a per-nozzle grouping result (multi-nozzle extruders). Threads a +// NozzleStatusRecorder describing the initial physical nozzle occupancy so the reorder can reward +// keeping an already-loaded filament in place. +int reorder_filaments_for_multi_nozzle_extruder(const std::vector& filament_lists, + const MultiNozzleUtils::LayeredNozzleGroupResult& nozzle_group_result, + const std::vector>& layer_filaments, + const std::vector& flush_matrix, + const std::function&)> get_custom_seq, + std::vector> * filament_sequences, + const MultiNozzleUtils::NozzleStatusRecorder& initial_status = {}); } #endif // !TOOL_ORDER_UTILS_HPP diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 5cb66ba5e5..f37025d4e7 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -6,8 +6,12 @@ #include "ParameterUtils.hpp" #include "GCode/ToolOrderUtils.hpp" #include "FilamentGroupUtils.hpp" +#include "MultiNozzleUtils.hpp" +#include "Utils.hpp" #include "I18N.hpp" +#include + // #define SLIC3R_DEBUG // Make assert active if SLIC3R_DEBUG @@ -138,7 +142,8 @@ static double calc_max_layer_height(const PrintConfig &config, double max_object { double max_layer_height = std::numeric_limits::max(); for (size_t i = 0; i < config.nozzle_diameter.values.size(); ++ i) { - double mlh = config.max_layer_height.values[i]; + // max_layer_height may be shorter than the extruder count; get_at() clamps. + double mlh = config.max_layer_height.get_at(i); if (mlh == 0.) mlh = 0.75 * config.nozzle_diameter.values[i]; max_layer_height = std::min(max_layer_height, mlh); @@ -149,26 +154,47 @@ static double calc_max_layer_height(const PrintConfig &config, double max_object } //calculate the flush weight (first value) and filament change count(second value) -static FilamentChangeStats calc_filament_change_info_by_toolorder(const PrintConfig* config, const std::vector& filament_map, const std::vector& flush_matrix, const std::vector>& layer_sequences) +// Nozzle-aware flush-stat calculator. Resolves each +// filament in the print sequence to its physical nozzle via the grouping result and tracks a +// per-nozzle NozzleStatusRecorder, so flush weight and flush_filament_change_count are charged +// per physical nozzle. For single-nozzle-per-extruder printers (H2D/X1/...) nozzle_id == extruder_id, +// so every returned value is identical to the extruder-level calculation. Out-of-range +// filament ids resolve to no nozzle and are skipped. +static FilamentChangeStats calc_filament_change_info_by_toolorder(const PrintConfig* config, const MultiNozzleUtils::LayeredNozzleGroupResult& group_result, const std::vector& flush_matrix, const std::vector>& layer_sequences) { FilamentChangeStats ret; std::unordered_map flush_volume_per_filament; - int max_extruder_id = *std::max_element(filament_map.begin(), filament_map.end()); - assert(max_extruder_id >= 0); - std::vectorlast_filament_per_extruder(max_extruder_id + 1, -1); + MultiNozzleUtils::NozzleStatusRecorder recorder; int total_filament_change_count = 0; + int total_flush_filament_change_count = 0; float total_filament_flush_weight = 0; - for (const auto& ls : layer_sequences) { - for (const auto& item : ls) { - int extruder_id = filament_map[item]; - int last_filament = last_filament_per_extruder[extruder_id]; - if (last_filament != -1 && last_filament != item) { - int flush_volume = flush_matrix[extruder_id][last_filament][item]; - flush_volume_per_filament[item] += flush_volume; - total_filament_change_count += 1; + + int old_filament_id = -1; + for (size_t layer_idx = 0; layer_idx < layer_sequences.size(); ++layer_idx) { + const auto& ls = layer_sequences[layer_idx]; + for (const auto& filament : ls) { + auto nozzle = group_result.get_nozzle_for_filament(filament, layer_idx); + if (!nozzle) + continue; + + int new_extruder_id = nozzle->extruder_id; + int new_nozzle_id_in_extruder = nozzle->group_id; + int new_filament_id_in_nozzle = filament; + int old_filament_id_in_nozzle = recorder.get_filament_in_nozzle(new_nozzle_id_in_extruder); + + bool filament_in_nozzle_change = old_filament_id_in_nozzle != -1 && new_filament_id_in_nozzle != old_filament_id_in_nozzle; + bool filament_change = old_filament_id != -1 && old_filament_id != new_filament_id_in_nozzle; + + if (filament_in_nozzle_change) { + total_flush_filament_change_count++; + int flush_volume = flush_matrix[new_extruder_id][old_filament_id_in_nozzle][new_filament_id_in_nozzle]; + flush_volume_per_filament[filament] += flush_volume; } - last_filament_per_extruder[extruder_id] = item; + if (filament_change) + total_filament_change_count++; + old_filament_id = new_filament_id_in_nozzle; + recorder.set_nozzle_status(new_nozzle_id_in_extruder, new_filament_id_in_nozzle, new_extruder_id); } } @@ -177,8 +203,9 @@ static FilamentChangeStats calc_filament_change_info_by_toolorder(const PrintCon total_filament_flush_weight += weight; } - ret.filament_change_count = total_filament_change_count; - ret.filament_flush_weight = (int)total_filament_flush_weight; + ret.filament_change_count = total_filament_change_count; + ret.flush_filament_change_count = total_flush_filament_change_count; + ret.filament_flush_weight = (int)total_filament_flush_weight; return ret; } @@ -187,6 +214,10 @@ static void apply_first_layer_order(const DynamicPrintConfig* config, std::vecto void ToolOrdering::handle_dontcare_extruder(const std::vector& tool_order_layer0) { + const PrintConfig* print_config = m_print_config_ptr; + if (!print_config && m_print_object_ptr) + print_config = &m_print_object_ptr->print()->config(); + if(m_layer_tools.empty() || tool_order_layer0.empty()) return; @@ -221,6 +252,8 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector& too for (int i = 1; i < m_layer_tools.size(); i++) { LayerTools& lt = m_layer_tools[i]; + // Extruders in lt.extruders are already sorted. + if (lt.extruders.empty()) continue; if (lt.extruders.size() == 1 && lt.extruders.front() == 0) @@ -229,14 +262,23 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector& too if (lt.extruders.front() == 0) // Pop the "don't care" extruder, the "don't care" region will be merged with the next one. lt.extruders.erase(lt.extruders.begin()); - // Reorder the extruders to start with the last one. - for (size_t i = 1; i < lt.extruders.size(); ++i) - if (lt.extruders[i] == last_extruder_id) { - // Move the last extruder to the front. - memmove(lt.extruders.data() + 1, lt.extruders.data(), i * sizeof(unsigned int)); - lt.extruders.front() = last_extruder_id; - break; + + if (print_config == nullptr + || print_config->toolchange_ordering == ToolChangeOrderingType::Default) + { + // Reorder the extruders to start with the last one. + for (size_t i = 1; i < lt.extruders.size(); ++i) { + if (lt.extruders[i] == last_extruder_id) { + // Move the last extruder to the front. + std::rotate( + lt.extruders.begin(), + lt.extruders.begin() + i, + lt.extruders.begin() + i + 1 + ); + break; + } } + } } last_extruder_id = lt.extruders.back(); } @@ -252,6 +294,10 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector& too void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id) { + const PrintConfig* print_config = m_print_config_ptr; + if (!print_config && m_print_object_ptr) + print_config = &m_print_object_ptr->print()->config(); + if(m_layer_tools.empty()) return; if(last_extruder_id == (unsigned int)-1){ @@ -275,6 +321,8 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id) } for (LayerTools < : m_layer_tools) { + // Extruders in lt.extruders are already sorted. + if (lt.extruders.empty()) continue; if (lt.extruders.size() == 1 && lt.extruders.front() == 0) @@ -283,21 +331,30 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id) if (lt.extruders.front() == 0) // Pop the "don't care" extruder, the "don't care" region will be merged with the next one. lt.extruders.erase(lt.extruders.begin()); - // Reorder the extruders to start with the last one. - for (size_t i = 1; i < lt.extruders.size(); ++ i) - if (lt.extruders[i] == last_extruder_id) { - // Move the last extruder to the front. - memmove(lt.extruders.data() + 1, lt.extruders.data(), i * sizeof(unsigned int)); - lt.extruders.front() = last_extruder_id; - break; + + if (print_config == nullptr + || print_config->toolchange_ordering == ToolChangeOrderingType::Default) + { + // Reorder the extruders to start with the last one. + for (size_t i = 1; i < lt.extruders.size(); ++i) { + if (lt.extruders[i] == last_extruder_id) { + // Move the last extruder to the front. + std::rotate( + lt.extruders.begin(), + lt.extruders.begin() + i, + lt.extruders.begin() + i + 1 + ); + break; + } } + } if (lt == m_layer_tools[0]) { // On first layer with wipe tower, prefer a soluble extruder // at the beginning, so it is not wiped on the first layer. - if (m_print_config_ptr && m_print_config_ptr->enable_prime_tower) { + if (print_config && print_config->enable_prime_tower) { for (size_t i = 0; ifilament_soluble.get_at(lt.extruders[i]-1)) { // 1-based... + if (print_config->filament_soluble.get_at(lt.extruders[i]-1)) { // 1-based... std::swap(lt.extruders[i], lt.extruders.front()); break; } @@ -396,6 +453,7 @@ void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material) { m_print_full_config = &object.print()->full_print_config(); + m_print_config_ptr = &object.print()->config(); m_print_object_ptr = &object; m_print = const_cast(object.print()); if (object.layers().empty()) @@ -1005,12 +1063,24 @@ bool ToolOrdering::cal_non_support_filaments(const PrintConfig &config, int find_count = 0; int find_first_filaments_count = 0; bool has_non_support = has_non_support_filament(config); - for (const LayerTools &layer_tool : m_layer_tools) { - for (const unsigned int &filament : layer_tool.extruders) { + // The selector can move a filament between extruders per layer; resolve the extruder from + // the published result then, so the first filament attributed to an extruder is one it + // actually prints there. Static results keep the cross-layer filament_map arithmetic. + const bool use_dynamic_map = m_nozzle_group_result.is_support_dynamic_nozzle_map() && m_nozzle_group_result.get_layer_count() > 0; + auto extruder_for_filament = [&](unsigned int filament, size_t layer_idx) -> int { + if (use_dynamic_map) + return m_nozzle_group_result.get_extruder_id(static_cast(filament), static_cast(layer_idx)); + return config.filament_map.values[filament] - 1; + }; + for (size_t layer_idx = 0; layer_idx < m_layer_tools.size(); ++layer_idx) { + for (const unsigned int &filament : m_layer_tools[layer_idx].extruders) { //check first filament - if (!config.filament_map.values.empty() && initial_filaments[config.filament_map.values[filament] - 1] == -1) { - initial_filaments[config.filament_map.values[filament] - 1] = filament; - find_first_filaments_count++; + if (!config.filament_map.values.empty()) { + const int extruder_id = extruder_for_filament(filament, layer_idx); + if (extruder_id >= 0 && extruder_id < static_cast(initial_filaments.size()) && initial_filaments[extruder_id] == -1) { + initial_filaments[extruder_id] = filament; + find_first_filaments_count++; + } } if (has_non_support) { @@ -1025,8 +1095,9 @@ bool ToolOrdering::cal_non_support_filaments(const PrintConfig &config, if (config.filament_map.values.empty()) return true; - if (initial_non_support_filaments[config.filament_map.values[filament] - 1] == -1) { - initial_non_support_filaments[config.filament_map.values[filament] - 1] = filament; + const int extruder_id = extruder_for_filament(filament, layer_idx); + if (extruder_id >= 0 && extruder_id < static_cast(initial_non_support_filaments.size()) && initial_non_support_filaments[extruder_id] == -1) { + initial_non_support_filaments[extruder_id] = filament; find_count++; } @@ -1104,27 +1175,42 @@ float get_flush_volume(const std::vector &filament_maps, const std::vector< return flush_volume; } -std::vector ToolOrdering::get_recommended_filament_maps(const std::vector>& layer_filaments, const Print* print, const FilamentMapMode mode,const std::vector>&physical_unprintables,const std::vector>&geometric_unprintables) +// Forward declaration — the single-nozzle-per-extruder nozzle list (defined below). +static std::vector build_default_nozzle_list(const PrintConfig &print_config, size_t extruder_nums); + +// Best-effort readers for the multi-nozzle dev config keys. These are registered in the ConfigDef +// but not (yet) static PrintConfig members, so the slicing PrintConfig reads them as inert defaults, +// which keeps the auto grouping path bit-exact (all these degrade to the flush-only, non-switcher +// case). +static bool cfg_bool(const ConfigBase& c, const char* key, bool def) { - using namespace FilamentGroupUtils; - if (!print || layer_filaments.empty()) - return std::vector(); + if (auto* o = c.option(key)) return o->value; + return def; +} +static double cfg_float(const ConfigBase& c, const char* key, double def) +{ + if (auto* o = c.option(key)) return o->value; + return def; +} - const auto& print_config = print->config(); - const unsigned int filament_nums = (unsigned int)(print_config.filament_colour.values.size() + EPSILON); - - // get flush matrix - std::vector nozzle_flush_mtx; +// Prepare per-extruder flush matrices. The prime_volume_mode==pvmFast branch: Default reads +// flush_multiplier, Fast reads flush_multiplier_fast. +static std::vector prepare_flush_matrices(const PrintConfig& print_config) +{ size_t extruder_nums = print_config.nozzle_diameter.values.size(); + size_t filament_nums = print_config.filament_colour.values.size(); + std::vector nozzle_flush_mtx; for (size_t nozzle_id = 0; nozzle_id < extruder_nums; ++nozzle_id) { - std::vector flush_matrix(cast(get_flush_volumes_matrix(print_config.flush_volumes_matrix.values, nozzle_id, extruder_nums))); + std::vector flush_matrix(cast(get_flush_volumes_matrix(print_config.flush_volumes_matrix.values, nozzle_id, extruder_nums))); std::vector> wipe_volumes; for (unsigned int i = 0; i < filament_nums; ++i) wipe_volumes.push_back(std::vector(flush_matrix.begin() + i * filament_nums, flush_matrix.begin() + (i + 1) * filament_nums)); - nozzle_flush_mtx.emplace_back(wipe_volumes); } - auto flush_multiplies = print_config.flush_multiplier.values; + + // Fast purge mode uses flush_multiplier_fast; Default is inert. + auto flush_multiplies = (print_config.prime_volume_mode == PrimeVolumeMode::pvmFast) ? print_config.flush_multiplier_fast.values + : print_config.flush_multiplier.values; flush_multiplies.resize(extruder_nums, 1); for (size_t nozzle_id = 0; nozzle_id < extruder_nums; ++nozzle_id) { for (auto& vec : nozzle_flush_mtx[nozzle_id]) { @@ -1132,88 +1218,377 @@ std::vector ToolOrdering::get_recommended_filament_maps(const std::vector other_layers_seqs = get_other_layers_print_sequence(print_config.other_layers_print_sequence_nums.value, print_config.other_layers_print_sequence.values); - - // other_layers_seq: the layer_idx and extruder_idx are base on 1 - auto get_custom_seq = [&other_layers_seqs](int layer_idx, std::vector& out_seq) -> bool { - for (size_t idx = other_layers_seqs.size() - 1; idx != size_t(-1); --idx) { - const auto& other_layers_seq = other_layers_seqs[idx]; - if (layer_idx + 1 >= other_layers_seq.first.first && layer_idx + 1 <= other_layers_seq.first.second) { - out_seq = other_layers_seq.second; - return true; +// Per-extruder physical nozzle groups. +// Orca: bounds-guards the nozzle_volume_type / extruder_max_nozzle_count arrays, which may be +// shorter than the extruder count on some profiles. +static std::vector build_nozzle_groups(const PrintConfig& print_config, size_t extruder_nums) +{ + std::vector nozzle_groups; + auto extruder_nozzle_counts = get_extruder_nozzle_stats(print_config.extruder_nozzle_stats.values); + const auto& nozzle_volume_types = print_config.nozzle_volume_type.values; + for (size_t idx = 0; idx < extruder_nums; ++idx) { + std::string diameter = format_diameter_to_str(print_config.nozzle_diameter.values[idx]); + NozzleVolumeType vt = idx < nozzle_volume_types.size() ? NozzleVolumeType(nozzle_volume_types[idx]) : nvtStandard; + int max_count = idx < print_config.extruder_max_nozzle_count.values.size() ? print_config.extruder_max_nozzle_count.values[idx] : 1; + if (idx >= extruder_nozzle_counts.size() || extruder_nozzle_counts[idx].empty()) { + nozzle_groups.emplace_back(diameter, vt, (int)idx, max_count); + } else { + if (vt == nvtHybrid) { + for (auto& [volume_type, count] : extruder_nozzle_counts[idx]) + nozzle_groups.emplace_back(diameter, volume_type, (int)idx, count); + } else { + nozzle_groups.emplace_back(diameter, vt, (int)idx, extruder_nozzle_counts[idx][vt]); } } + } + return nozzle_groups; +} + +// Build the nozzle-centric FilamentGroupContext. +// Orca deviations, all inert for the shipping fleet: +// * no print->get_filament_usage_type() → FilamentInfo::usage_type stays ModelOnly (the default); +// * no print->get_filament_print_time() → speed_info.filament_print_time empty (TimeEvaluator → 0); +// * the fmmAutoForQuality and Bowden-PA-calibration limit blocks are omitted (Orca has no +// fmmAutoForQuality mode and no Calib_Params::has_bowden_extruder). +// prefer_non_model_filament (Bowden extruders) is all-false for the Direct-Drive BBL fleet, so the +// support-preference reward path stays dormant. +static FilamentGroupContext build_filament_group_context( + const Print* print, + const std::vector>& layer_filaments, + const std::vector>& physical_unprintables, + const std::vector>& geometric_unprintables, + const std::map>& unprintable_volumes, + FilamentMapMode mode, + const std::unordered_map& nozzle_status) +{ + using namespace MultiNozzleUtils; + using namespace FilamentGroupUtils; + + FilamentGroupContext context; + + const auto& print_config = print->config(); + const size_t filament_nums = print_config.filament_colour.values.size(); + const size_t extruder_nums = print_config.nozzle_diameter.values.size(); + bool has_multiple_nozzle = std::any_of(print_config.extruder_max_nozzle_count.values.begin(), print_config.extruder_max_nozzle_count.values.end(), + [](int v) { return v > 1; }); + + auto nozzle_flush_mtx = prepare_flush_matrices(print_config); + auto nozzle_groups = build_nozzle_groups(print_config, extruder_nums); + + std::vector> ext_unprintable_filaments; + collect_unprintable_limits(physical_unprintables, geometric_unprintables, ext_unprintable_filaments); + + bool ignore_ext_filament = false; + auto extruder_ams_counts = get_extruder_ams_count(print_config.extruder_ams_count.values); + std::vector group_size = calc_max_group_size(extruder_ams_counts, ignore_ext_filament); + + // When a filament switcher is connected, disable the AMS capacity limit for grouping. + const bool has_filament_switcher = cfg_bool(print_config, "has_filament_switcher", false); + if (has_filament_switcher) { + int total_filaments = (int)filament_nums; + for (auto& s : group_size) + s = std::max(s, total_filaments); + } + + std::vector prefer_non_model_filament(extruder_nums, false); + for (size_t idx = 0; idx < extruder_nums; ++idx) + if (idx < print_config.extruder_type.values.size()) + prefer_non_model_filament[idx] = (print_config.extruder_type.values[idx] == ExtruderType::etBowden); + + auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament); + + std::vector filament_types = print_config.filament_type.values; + std::vector filament_colours = print_config.filament_colour.values; + std::vector filament_is_support = print_config.filament_is_support.values; + std::vector filament_ids = print_config.filament_ids.values; + + FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode : FGMode::FlushMode; + context.model_info.flush_matrix = std::move(nozzle_flush_mtx); + context.model_info.unprintable_filaments = ext_unprintable_filaments; + context.model_info.layer_filaments = layer_filaments; + context.model_info.filament_ids = filament_ids; + context.model_info.unprintable_volumes = unprintable_volumes; + + for (size_t idx = 0; idx < filament_types.size(); ++idx) { + FilamentGroupUtils::FilamentInfo info; + info.color = filament_colours[idx]; + info.type = filament_types[idx]; + info.is_support = filament_is_support[idx]; + context.model_info.filament_info.emplace_back(std::move(info)); + } + + context.speed_info.group_with_time = cfg_bool(print_config, "group_algo_with_time", false); + context.speed_info.filament_change_time = print_config.machine_load_filament_time + print_config.machine_unload_filament_time; + context.speed_info.extruder_change_time = cfg_float(print_config, "machine_switch_extruder_time", 0.0); + { + double load_time = print_config.machine_load_filament_time; + double unload_time = print_config.machine_unload_filament_time; + context.speed_info.change_time_params.standard_load_time = static_cast(load_time); + context.speed_info.change_time_params.standard_unload_time = static_cast(unload_time); + context.speed_info.change_time_params.selector_load_time = static_cast(load_time / 2); + context.speed_info.change_time_params.selector_unload_time = static_cast(unload_time / 2); + } + + context.machine_info.machine_filament_info = machine_filament_info; + context.machine_info.max_group_size = std::move(group_size); + context.machine_info.master_extruder_id = print_config.master_extruder_id.value - 1; + context.machine_info.prefer_non_model_filament = prefer_non_model_filament; + + context.group_info.total_filament_num = (int)(filament_nums); + context.group_info.max_gap_threshold = 0.01; + context.group_info.strategy = FGStrategy::BestCost; + context.group_info.mode = fg_mode; + context.group_info.ignore_ext_filament = ignore_ext_filament; + context.group_info.has_filament_switcher = has_filament_switcher; + + // hybrid flow means no special per-filament nozzle-volume request. + // Orca: honour the config's per-filament volume map only when it is sized to the filament + // count. The full-config producers (PresetBundle injection, engine write-back) always size + // it; a mis-sized map (stale project value, CLI runs until the per-filament synthesis lands + // there) must not displace the hybrid fallback rebuild_nozzle_unprintables relies on, nor be + // indexed out of bounds. + if (mode == FilamentMapMode::fmmManual && + print_config.filament_volume_map.values.size() == filament_nums) + context.group_info.filament_volume_map = print_config.filament_volume_map.values; + else + context.group_info.filament_volume_map = std::vector(filament_nums, (int)(NozzleVolumeType::nvtHybrid)); + + context.nozzle_info.nozzle_list = build_nozzle_list(nozzle_groups); + context.nozzle_info.extruder_nozzle_list = build_extruder_nozzle_list(context.nozzle_info.nozzle_list); + + if (context.nozzle_info.nozzle_list.empty()) + throw Slic3r::RuntimeError("No valid nozzle found. Please check nozzle count."); + + if (!nozzle_status.empty()) + context.nozzle_info.nozzle_status = nozzle_status; + + auto used_filaments = collect_sorted_used_filaments(layer_filaments); + + // add_volume_type_limits: only for single-nozzle-per-extruder machines (H2D and the like). A + // filament whose forbidden nozzle-volume-type matches an extruder's (only) nozzle becomes + // unprintable on that extruder; conflicts printable nowhere are dropped. + if (!has_multiple_nozzle) { + std::vector> ext_unprintable_filaments_with_volume = ext_unprintable_filaments; + for (auto& nozzle : context.nozzle_info.nozzle_list) { + for (auto fil_id : used_filaments) { + auto unprintable_vols = context.model_info.unprintable_volumes[fil_id]; + if (unprintable_vols.count(nozzle.volume_type) && nozzle.extruder_id >= 0 && nozzle.extruder_id < (int)ext_unprintable_filaments_with_volume.size()) + ext_unprintable_filaments_with_volume[nozzle.extruder_id].insert(fil_id); + } + } + for (auto fil_id : used_filaments) { + if (ext_unprintable_filaments_with_volume[0].count(fil_id) && ext_unprintable_filaments_with_volume[1].count(fil_id)) { + ext_unprintable_filaments_with_volume[0].erase(fil_id); + ext_unprintable_filaments_with_volume[1].erase(fil_id); + } + } + context.model_info.unprintable_filaments = ext_unprintable_filaments_with_volume; + } + + return context; +} + +// Orca: restore the master-extruder preference. Orca historically ran +// optimize_group_for_master_extruder / can_swap_groups after grouping so a light-filament print stays +// on the primary/master extruder. A weak in-enum penalty alone cannot overcome a pre-existing +// non-zero right-extruder self-flush term in the flush matrix (which otherwise pulls a lone filament +// onto the non-master extruder and changes H2D/H2C g-code). We re-apply the preference ONLY in this +// slicing wrapper — never in the FilamentGroup engine or the test harness — so existing prints keep +// their extruder assignment while the new engine's genuine multi-filament grouping deltas still land. +static bool can_swap_extruder_groups(int extruder_id_0, const std::set& group_0, int extruder_id_1, const std::set& group_1, const FilamentGroupContext& ctx) +{ + using namespace FilamentGroupUtils; + std::vector> extruder_unprintables(2); + { + std::vector> unprintable_filaments = ctx.model_info.unprintable_filaments; + if (unprintable_filaments.size() > 1) + remove_intersection(unprintable_filaments[0], unprintable_filaments[1]); + std::map> unplaceable_limits; + for (int group_id : {extruder_id_0, extruder_id_1}) + if (group_id >= 0 && group_id < (int)unprintable_filaments.size()) + for (auto f : unprintable_filaments[group_id]) + unplaceable_limits[f].emplace_back(group_id); + for (auto& elem : unplaceable_limits) sort_remove_duplicates(elem.second); + for (auto& elem : unplaceable_limits) + for (auto& eid : elem.second) { + if (eid == extruder_id_0) extruder_unprintables[0].insert(elem.first); + if (eid == extruder_id_1) extruder_unprintables[1].insert(elem.first); + } + } + for (auto fid : group_0) if (extruder_unprintables[1].count(fid) > 0) return false; + for (auto fid : group_1) if (extruder_unprintables[0].count(fid) > 0) return false; + const auto& mgs = ctx.machine_info.max_group_size; + if (extruder_id_0 < (int)mgs.size() && extruder_id_1 < (int)mgs.size() && + mgs[extruder_id_0] >= (int)group_0.size() && mgs[extruder_id_1] >= (int)group_1.size() && + (mgs[extruder_id_0] < (int)group_1.size() || mgs[extruder_id_1] < (int)group_0.size())) return false; + return true; +} + +// Balance a filament->nozzle map toward the master extruder (2-extruder machines only). If the +// non-master extruder holds strictly more used filaments than the master and the swap is valid, move +// each group's filaments onto nozzles of the opposite extruder. The exact nozzle within an extruder +// does not affect static g-code (which emits H-1), so re-nozzling round-robin is byte-safe. +static std::vector apply_master_extruder_preference(const FilamentGroupContext& ctx, const std::vector& used_filaments, std::vector nozzle_ret) +{ + const auto& extruder_nozzle_list = ctx.nozzle_info.extruder_nozzle_list; + int master = ctx.machine_info.master_extruder_id; + if (extruder_nozzle_list.size() != 2 || master < 0 || master > 1) return nozzle_ret; + int other = 1 - master; + if (extruder_nozzle_list.count(master) == 0 || extruder_nozzle_list.count(other) == 0) return nozzle_ret; + auto ext_of_nozzle = [&](int nid) -> int { + return (nid >= 0 && nid < (int)ctx.nozzle_info.nozzle_list.size()) ? ctx.nozzle_info.nozzle_list[nid].extruder_id : -1; + }; + std::set group_master, group_other; + for (auto fu : used_filaments) { + int f = (int)fu; + if (f >= (int)nozzle_ret.size()) continue; + int e = ext_of_nozzle(nozzle_ret[f]); + if (e == master) group_master.insert(f); + else if (e == other) group_other.insert(f); + } + if (group_other.size() > group_master.size() && + can_swap_extruder_groups(other, group_other, master, group_master, ctx)) { + const auto& master_nozzles = extruder_nozzle_list.at(master); + const auto& other_nozzles = extruder_nozzle_list.at(other); + if (!master_nozzles.empty() && !other_nozzles.empty()) { + int mi = 0, oi = 0; + for (auto f : group_other) nozzle_ret[f] = master_nozzles[(mi++) % master_nozzles.size()]; + for (auto f : group_master) nozzle_ret[f] = other_nozzles[(oi++) % other_nozzles.size()]; + } + } + return nozzle_ret; +} + +// Nozzle-centric grouping. Dispatches by FilamentMapMode and returns a nozzle-aware +// LayeredNozzleGroupResult. For single-extruder printers (X1/P1/A1/H2S) the grouping engine is not +// invoked — the trivial all-master map is wrapped in a single-nozzle result, so their g-code is +// unaffected. Multi-extruder (H2D) grouping runs the nozzle-centric FilamentGroup engine; +// multi-nozzle (H2C/A2L) resolves to a nozzle-granular result. +MultiNozzleUtils::LayeredNozzleGroupResult ToolOrdering::get_recommended_filament_maps(const std::vector>& layer_filaments, const Print* print, const FilamentMapMode mode, const std::vector>& physical_unprintables, const std::vector>& geometric_unprintables, const std::map>& unprintable_volumes, const std::unordered_map& nozzle_status) +{ + using namespace FilamentGroupUtils; + using namespace MultiNozzleUtils; + + if (!print || layer_filaments.empty()) + return LayeredNozzleGroupResult(); + + const auto& print_config = print->config(); + size_t filament_nums = print_config.filament_colour.values.size(); + size_t extruder_nums = print_config.nozzle_diameter.values.size(); + auto used_filaments = collect_sorted_used_filaments(layer_filaments); + bool has_multiple_nozzle = std::any_of(print_config.extruder_max_nozzle_count.values.begin(), print_config.extruder_max_nozzle_count.values.end(), + [](int v) { return v > 1; }); + bool has_multiple_extruder = extruder_nums > 1; + + auto nozzle_list = build_default_nozzle_list(print_config, extruder_nums); + + // Manual mode: build directly from the user's filament->extruder map. + if (mode == FilamentMapMode::fmmManual && !has_multiple_nozzle) { + auto manual_filament_map = print_config.filament_map.values; + std::transform(manual_filament_map.begin(), manual_filament_map.end(), manual_filament_map.begin(), [](int v) { return v - 1; }); + auto result = LayeredNozzleGroupResult::create(manual_filament_map, nozzle_list, used_filaments); + return result ? *result : LayeredNozzleGroupResult(); + } + + // Fully-manual mode: build the nozzle-granular result from the config nozzle map. + if (mode == FilamentMapMode::fmmNozzleManual) { + auto manual_filament_map = print_config.filament_map.values; + std::transform(manual_filament_map.begin(), manual_filament_map.end(), manual_filament_map.begin(), [](int v) { return v - 1; }); + float diameter = print_config.nozzle_diameter.values.empty() ? 0.4f : (float)print_config.nozzle_diameter.values.front(); + // Orca: create() indexes the volume/nozzle maps per used filament with no bounds check, so + // pass them only when a producer sized them to the filament count (mis-sized maps can + // arrive from stale projects or CLI runs until the per-filament synthesis lands there). + // Without valid maps the fully-manual request cannot be honoured; return the empty result, + // the same failure an unsatisfiable create() yields. + std::optional nozzle_result; + if (print_config.filament_volume_map.values.size() == filament_nums && + print_config.filament_nozzle_map.values.size() == filament_nums) + nozzle_result = LayeredNozzleGroupResult::create(used_filaments, manual_filament_map, print_config.filament_volume_map.values, print_config.filament_nozzle_map.values, get_extruder_nozzle_stats(print_config.extruder_nozzle_stats.values), diameter); + if (!nozzle_result) + BOOST_LOG_TRIVIAL(error) << "Failed to build nozzle group result from filament nozzle map!"; + return nozzle_result ? *nozzle_result : LayeredNozzleGroupResult(); + } + + int master_extruder_id = print_config.master_extruder_id.value - 1; + std::vector ret(filament_nums, master_extruder_id); + + // Non-BBL multi-extruder printers do not support filament grouping: filament id == extruder id. + if (has_multiple_extruder && !print->is_BBL_printer()) { + for (size_t i = 0; i < filament_nums && i < extruder_nums; i++) + ret[i] = (int)i; + auto result_opt = LayeredNozzleGroupResult::create(ret, nozzle_list, used_filaments); + return result_opt ? *result_opt : LayeredNozzleGroupResult(); + } + + if (has_multiple_extruder || has_multiple_nozzle) { + auto context = build_filament_group_context(print, layer_filaments, physical_unprintables, geometric_unprintables, unprintable_volumes, mode, nozzle_status); + + // other_layers_seq custom-sequence lambda (1-based layer/extruder). Only threaded for the + // single-nozzle-per-extruder engine. + std::vector other_layers_seqs = get_other_layers_print_sequence(print_config.other_layers_print_sequence_nums.value, print_config.other_layers_print_sequence.values); + auto get_custom_seq = [other_layers_seqs](int layer_idx, std::vector& out_seq) -> bool { + for (size_t idx = other_layers_seqs.size() - 1; idx != size_t(-1); --idx) { + const auto& other_layers_seq = other_layers_seqs[idx]; + if (layer_idx + 1 >= other_layers_seq.first.first && layer_idx + 1 <= other_layers_seq.first.second) { + out_seq = other_layers_seq.second; + return true; + } + } + return false; }; - int master_extruder_id = print_config.master_extruder_id.value -1; // switch to 0 based idx - std::vectorret(filament_nums, master_extruder_id); - bool ignore_ext_filament = false; // TODO: read from config - // if mutli_extruder, calc group,otherwise set to 0 - if (extruder_nums == 2 && print->is_BBL_printer()) { - std::vector extruder_ams_count_str = print_config.extruder_ams_count.values; - auto extruder_ams_counts = get_extruder_ams_count(extruder_ams_count_str); - std::vector group_size = calc_max_group_size(extruder_ams_counts, ignore_ext_filament); - - auto machine_filament_info = build_machine_filaments(print->get_extruder_filament_info(), extruder_ams_counts, ignore_ext_filament); - - std::vector filament_types = print_config.filament_type.values; - std::vector filament_colours = print_config.filament_colour.values; - std::vector filament_is_support = print_config.filament_is_support.values; - std::vector filament_ids = print_config.filament_ids.values; - // speacially handle tpu filaments - auto used_filaments = collect_sorted_used_filaments(layer_filaments); - auto tpu_filaments = get_filament_by_type(used_filaments, &print_config, "TPU"); - FGMode fg_mode = mode == FilamentMapMode::fmmAutoForMatch ? FGMode::MatchMode: FGMode::FlushMode; - - std::vector> ext_unprintable_filaments; - collect_unprintable_limits(physical_unprintables, geometric_unprintables, ext_unprintable_filaments); - - FilamentGroupContext context; - { - context.model_info.flush_matrix = std::move(nozzle_flush_mtx); - context.model_info.unprintable_filaments = ext_unprintable_filaments; - context.model_info.layer_filaments = layer_filaments; - context.model_info.filament_ids = filament_ids; - - for (size_t idx = 0; idx < filament_types.size(); ++idx) { - FilamentGroupUtils::FilamentInfo info; - info.color = filament_colours[idx]; - info.type = filament_types[idx]; - info.is_support = filament_is_support[idx]; - context.model_info.filament_info.emplace_back(std::move(info)); + if (has_multiple_nozzle && mode == FilamentMapMode::fmmManual) { + auto manual_filament_map = print_config.filament_map.values; + std::transform(manual_filament_map.begin(), manual_filament_map.end(), manual_filament_map.begin(), [](int v) { return v - 1; }); + ret = calc_filament_group_for_manual_multi_nozzle(manual_filament_map, context); + } else if (has_multiple_nozzle && mode == FilamentMapMode::fmmAutoForMatch) { + ret = calc_filament_group_for_match_multi_nozzle(context); + } else { + // TPU: keep the dedicated TPU split for single-nozzle-per-extruder printers. + auto tpu_filaments = get_filament_by_type(used_filaments, &print_config, "TPU"); + if (!has_multiple_nozzle && !tpu_filaments.empty()) { + ret = std::vector(context.group_info.total_filament_num, context.machine_info.master_extruder_id); + for (size_t fidx = 0; fidx < (size_t)context.group_info.total_filament_num; ++fidx) + ret[fidx] = tpu_filaments.count((int)fidx) ? context.machine_info.master_extruder_id : (1 - context.machine_info.master_extruder_id); + } else { + FilamentGroup fg(context); + if (!has_multiple_nozzle) + fg.get_custom_seq = get_custom_seq; + ret = fg.calc_filament_group(); + // Flush-mode auto grouping: restore the master-extruder preference + // (optimize_group_for_master_extruder). Match mode assigns by AMS colour and never had + // it. Kept out of the FilamentGroup engine so the test harness is unaffected. + if (context.group_info.mode == FGMode::FlushMode) + ret = apply_master_extruder_preference(context, used_filaments, ret); } - - context.machine_info.machine_filament_info = machine_filament_info; - context.machine_info.max_group_size = std::move(group_size); - context.machine_info.master_extruder_id = master_extruder_id; - - context.group_info.total_filament_num = (int)(filament_nums); - context.group_info.max_gap_threshold = 0.01; - context.group_info.strategy = FGStrategy::BestCost; - context.group_info.mode = fg_mode; - context.group_info.ignore_ext_filament = ignore_ext_filament; } - - if (!tpu_filaments.empty()) { - ret = calc_filament_group_for_tpu(tpu_filaments, context.group_info.total_filament_num, context.machine_info.master_extruder_id); - } - else { - FilamentGroup fg(context); - fg.get_custom_seq = get_custom_seq; - ret = fg.calc_filament_group(); - } - } else if (extruder_nums > 1) { - // For non-bbl multi-extruder printers we don't support filament group yet, and we use filament id as extruder id - assert(extruder_nums == filament_nums); - for (int i = 0; i < filament_nums; i++) { - ret[i] = i; + if (has_multiple_nozzle) { + auto result_opt = LayeredNozzleGroupResult::create(ret, context.nozzle_info.nozzle_list, used_filaments); + if (!result_opt) + return LayeredNozzleGroupResult(); + auto result = *result_opt; + if (mode == FilamentMapMode::fmmManual) { + // Manual grouping must reproduce the user's filament->extruder map exactly; a + // deviation means the requested assignment cannot be satisfied by the nozzle + // inventory, which must surface as a slicing error instead of silently regrouping. + auto result_map = result.get_extruder_map(); + for (auto fid : used_filaments) { + if (result_map[fid] != print_config.filament_map.values[fid] - 1) { + throw Slic3r::RuntimeError(_L("Group error in manual mode. Please check nozzle count or regroup.")); + } + } + } + return result; } } - return ret; + auto result_opt = LayeredNozzleGroupResult::create(ret, nozzle_list, used_filaments); + return result_opt ? *result_opt : LayeredNozzleGroupResult(); } FilamentChangeStats ToolOrdering::get_filament_change_stats(FilamentChangeMode mode) @@ -1232,6 +1607,344 @@ FilamentChangeStats ToolOrdering::get_filament_change_stats(FilamentChangeMode m return m_stats_by_single_extruder; } +// Build one logical nozzle per extruder. This is the single-nozzle grouping: +// nozzle group_id == extruder_id. Kept file-local. +static std::vector build_default_nozzle_list(const PrintConfig &print_config, size_t extruder_nums) +{ + using namespace MultiNozzleUtils; + std::vector nozzle_list; + for (size_t idx = 0; idx < extruder_nums; ++idx) { + NozzleInfo tmp; + tmp.diameter = format_diameter_to_str(print_config.nozzle_diameter.values[idx]); + tmp.group_id = static_cast(idx); + tmp.extruder_id = static_cast(idx); + // nozzle_volume_type may be shorter than nozzle_diameter on some Orca profiles; default to Standard. + tmp.volume_type = idx < print_config.nozzle_volume_type.values.size() + ? NozzleVolumeType(print_config.nozzle_volume_type.values[idx]) + : nvtStandard; + nozzle_list.emplace_back(std::move(tmp)); + } + return nozzle_list; +} + +// Build a LayeredNozzleGroupResult from an already-resolved 0-based +// filament->extruder map. Used by the by-object (sequential) path, whose grouping is decided +// earlier in Print.cpp — here we only wrap the config map. For single-nozzle-per-extruder printers +// (the common case incl. H2D) each filament resolves to its extruder's one logical nozzle +// (nozzle_id == extruder_id). For a multi-nozzle printer the config's per-filament nozzle/volume +// choice is resolved via the 6-argument create (the per-layer engine owns the auto +// sequential path proper). +static MultiNozzleUtils::LayeredNozzleGroupResult build_group_result_from_map( + const PrintConfig& print_config, + const std::vector& filament_map_0based, + const std::vector& used_filaments) +{ + using namespace MultiNozzleUtils; + const size_t extruder_nums = print_config.nozzle_diameter.values.size(); + const size_t filament_nums = print_config.filament_colour.values.size(); + const bool has_multiple_nozzle = std::any_of(print_config.extruder_max_nozzle_count.values.begin(), print_config.extruder_max_nozzle_count.values.end(), + [](int v) { return v > 1; }); + // Orca: same sizing guard as the manual grouping paths — create() indexes the volume/nozzle + // maps per used filament with no bounds check, so only maps sized to the filament count are + // trusted (mis-sized maps can arrive from stale projects or CLI runs until the per-filament + // synthesis lands there). Unsized maps fall through to the extruder-level wrap below. + if (has_multiple_nozzle && + print_config.filament_volume_map.values.size() == filament_nums && + print_config.filament_nozzle_map.values.size() == filament_nums) { + float diameter = print_config.nozzle_diameter.values.empty() ? 0.4f : static_cast(print_config.nozzle_diameter.values.front()); + if (auto g = LayeredNozzleGroupResult::create(used_filaments, filament_map_0based, print_config.filament_volume_map.values, print_config.filament_nozzle_map.values, get_extruder_nozzle_stats(print_config.extruder_nozzle_stats.values), diameter)) + return *g; + } + auto nozzle_list = build_default_nozzle_list(print_config, extruder_nums); + if (auto group = LayeredNozzleGroupResult::create(filament_map_0based, nozzle_list, used_filaments)) + return *group; + return LayeredNozzleGroupResult(); +} + +// Per-layer nozzle-state refinement. Given a per-range grouping result and the +// physical nozzle occupancy (nozzles_state: nozzle_id -> filament currently loaded), it re-matches +// each logical nozzle to a physical nozzle *within its extruder* by a MinFlushFlowSolver that +// rewards keeping an already-loaded filament (cost -1) and otherwise charges the averaged flush. +// Returns a new result carrying the remapped default filament->nozzle map (falls back to the input +// result if the remap cannot be built). File-local: only the per-layer engine below calls it. +static MultiNozzleUtils::LayeredNozzleGroupResult refine_groups_by_Nozzle_State( + const FilamentGroupContext& ctx, + const MultiNozzleUtils::LayeredNozzleGroupResult& group, + const std::unordered_map& nozzles_state) +{ + std::vector> nozzle_fils(ctx.nozzle_info.nozzle_list.size()); + auto fils = group.get_used_filaments(0); + auto fil_noz_map = group.get_layer_filament_nozzle_map(0); + + for (auto fil : fils) + nozzle_fils[fil_noz_map[fil]].emplace_back(fil); + + // 1. Collect the nozzles each filament may NOT use. + std::map> fil_unplaceable_nozs; + for (auto fil : fils) { + std::set unprintable_volumes; + if (ctx.model_info.unprintable_volumes.count(fil)) + unprintable_volumes = ctx.model_info.unprintable_volumes.at(fil); + auto expected_volume = ctx.group_info.filament_volume_map[fil]; + + for (int noz = 0; noz < (int) ctx.nozzle_info.nozzle_list.size(); noz++) { + auto noz_info = ctx.nozzle_info.nozzle_list[noz]; + int ext_id = noz_info.extruder_id; + auto ext_unprintable_fils = ctx.model_info.unprintable_filaments[ext_id]; + if (ext_unprintable_fils.count(fil) > 0 || + (expected_volume != nvtHybrid && expected_volume != noz_info.volume_type) || (unprintable_volumes.count(noz_info.volume_type) != 0)) + fil_unplaceable_nozs[fil].insert(noz); + } + } + + // 2. Global nozzle-match result. + std::unordered_map global_uv_match; + + // 3. Solve one min-cost flow per extruder. + for (const auto& [ext_id, ext_nozzles] : ctx.nozzle_info.extruder_nozzle_list) { + if (ext_nozzles.empty()) continue; + + // 3.1. u_nodes / v_nodes for this extruder. + std::vector u_nodes = ext_nozzles; + std::vector v_nodes = ext_nozzles; + + // 3.2. global nozzle id -> local index. + std::unordered_map global_to_local; + for (size_t i = 0; i < ext_nozzles.size(); ++i) + global_to_local[ext_nozzles[i]] = static_cast(i); + + // 3.3. cost matrix for this extruder. + std::vector> cost_matrix(u_nodes.size(), std::vector(v_nodes.size(), std::numeric_limits::max())); + std::unordered_map> uv_unlink_limits; + + for (size_t local_u = 0; local_u < u_nodes.size(); ++local_u) { + int u_node = u_nodes[local_u]; + std::set unlink_v_local; + auto u_fils = nozzle_fils[u_node]; + + // Collect the v_nodes this u_node may NOT connect to (as local indices). + for (auto fil : u_fils) { + for (auto unplaceable_noz : fil_unplaceable_nozs[fil]) { + if (global_to_local.count(unplaceable_noz)) + unlink_v_local.insert(global_to_local[unplaceable_noz]); + } + } + uv_unlink_limits[static_cast(local_u)].assign(unlink_v_local.begin(), unlink_v_local.end()); + + // 3.4. compute costs. + for (size_t local_v = 0; local_v < v_nodes.size(); ++local_v) { + int v_node = v_nodes[local_v]; + float cost = 0; + if (unlink_v_local.count(static_cast(local_v))) continue; + + std::optional v_fil_opt = std::nullopt; + if (nozzles_state.count(v_node)) + v_fil_opt = nozzles_state.at(v_node); + + if (!v_fil_opt.has_value() || v_fil_opt.value() >= ctx.model_info.filament_info.size()) { + cost = 0; + } else { + int v_fil = v_fil_opt.value(); + if (std::find(u_fils.begin(), u_fils.end(), v_fil) != u_fils.end()) + cost = -1; + else { + for (auto u_fil : u_fils) + cost += ctx.model_info.flush_matrix[ext_id][u_fil][v_fil]; + if (u_fils.size() > 0) + cost /= u_fils.size(); + } + } + + cost_matrix[local_u][local_v] = cost; + } + } + + // 3.5. min-cost flow -> nozzle match for this extruder. + std::vector local_u_nodes(u_nodes.size()); + std::vector local_v_nodes(v_nodes.size()); + std::iota(local_u_nodes.begin(), local_u_nodes.end(), 0); + std::iota(local_v_nodes.begin(), local_v_nodes.end(), 0); + + MinFlushFlowSolver solver(cost_matrix, local_u_nodes, local_v_nodes, {}, uv_unlink_limits); + auto local_match = solver.solve(); + + // 3.6. local match -> global match. + for (size_t local_u = 0; local_u < u_nodes.size(); ++local_u) { + int global_u = u_nodes[local_u]; + int local_v = local_match[static_cast(local_u)]; + if (local_v == MaxFlowGraph::INVALID_ID || local_v < 0 || local_v >= static_cast(v_nodes.size())) + continue; + int global_v = v_nodes[local_v]; + global_uv_match[global_u] = global_v; + } + } + + // 4. Build the new group_result. + std::vector new_default_filament_nozzle_maps = group.get_layer_filament_nozzle_map(-1); + + for (auto fil : fils) { + int ori_noz = new_default_filament_nozzle_maps[fil]; + if (global_uv_match.count(ori_noz)) + new_default_filament_nozzle_maps[fil] = global_uv_match[ori_noz]; + } + + auto new_group = MultiNozzleUtils::LayeredNozzleGroupResult::create(new_default_filament_nozzle_maps, ctx.nozzle_info.nozzle_list, fils); + if (!new_group.has_value()) new_group = group; + + return *new_group; +} + +// Used as an unordered_map key over a filament-set (the per-layer filament combo). +struct VectorHash +{ + size_t operator()(const std::vector& v) const + { + size_t seed = v.size(); + for (auto& elem : v) + seed ^= std::hash()(elem) + 0x9e3779b9 + (seed << 6) + (seed >> 2); + return seed; + } +}; + +// The per-layer regroup engine. Layers are grouped into +// contiguous runs sharing the same filament set ("combo ranges"); a NozzleStatusRecorder carries the +// physical nozzle occupancy across ranges so the selector rewards keeping an already-loaded filament. +// Per range: get_recommended_filament_maps -> refine_groups_by_Nozzle_State (nozzle re-match) -> +// reorder_filaments_for_multi_nozzle_extruder (in-range ordering). Emits a per-layer +// filament->nozzle match + filament order. Orca: there is no ToolOrdering::OrderingContext here, so +// the custom-sequence function is passed directly instead. Only the dynamic branch +// (H2C selector, is_dynamic_group_reorder) calls this. +static std::vector plan_filament_mapping_and_order_by_combo_ranges( + Print* print, + const FilamentGroupContext& ctx, + const std::function&)> get_custom_seq, + const FilamentMapMode mode, + const std::vector>& physical_unprintables, + const std::vector>& geometric_unprintables, + const std::map>& unprintable_volumes, + MultiNozzleUtils::NozzleStatusRecorder* io_nozzle_status) +{ + std::vector results; + + const auto& layer_fils = ctx.model_info.layer_filaments; + if (layer_fils.empty()) + return results; + + results.resize(layer_fils.size()); + + // key: the sorted+deduped filament set used by a layer; value: the contiguous [start,end] runs. + std::unordered_map, std::vector>, VectorHash> filament_combo_ranges; + for (int layer_idx = 0; layer_idx < static_cast(layer_fils.size()); ++layer_idx) { + std::vector cur_combo = layer_fils[layer_idx]; + std::sort(cur_combo.begin(), cur_combo.end()); + cur_combo.erase(std::unique(cur_combo.begin(), cur_combo.end()), cur_combo.end()); + if (cur_combo.empty()) + continue; + + auto& ranges = filament_combo_ranges[cur_combo]; + if (ranges.empty() || ranges.back().second != layer_idx - 1) + ranges.emplace_back(layer_idx, layer_idx); + else + ranges.back().second = layer_idx; + } + + std::map, std::vector> range_filas_map; + for (auto& [combo, ranges] : filament_combo_ranges) + for (auto& range : ranges) + range_filas_map[range] = combo; + + std::set used_filaments; + + // Per combo range: build the range's layer_filaments, group + refine + reorder. + MultiNozzleUtils::NozzleStatusRecorder tool_status; + if (io_nozzle_status) tool_status = *io_nozzle_status; + + std::vector fil_noz_map(ctx.group_info.total_filament_num, -1); // global filament -> nozzle map + std::unordered_map fil_first_nozzle_map; // filament -> first nozzle it used + for (auto& [range, combo] : range_filas_map) { + auto [start_layer, end_layer] = range; + // 1. layer_filaments for this range. + std::vector> range_layer_fils; + range_layer_fils.reserve(end_layer - start_layer + 1); + for (int layer_idx = start_layer; layer_idx <= end_layer; ++layer_idx) + range_layer_fils.push_back(layer_fils[layer_idx]); + used_filaments.insert(combo.begin(), combo.end()); + + // 2. group the range. + auto nozzle_filament_map = tool_status.get_nozzle_filament_map(); + auto group_result = ToolOrdering::get_recommended_filament_maps(range_layer_fils, print, mode, physical_unprintables, geometric_unprintables, unprintable_volumes, nozzle_filament_map); + + // 3. re-match logical nozzles to physical nozzles by the current nozzle state. + auto new_group_result = refine_groups_by_Nozzle_State(ctx, group_result, nozzle_filament_map); + + auto range_seq_function = [&get_custom_seq, start_layer_ = start_layer, end_layer_ = end_layer](int layer_idx, std::vector& out_seq) -> bool { + if (layer_idx <= end_layer_ - start_layer_) { + int global_idx = start_layer_ + layer_idx; + return get_custom_seq ? get_custom_seq(global_idx, out_seq) : false; + } + return false; + }; + + // 4. order the filaments within the range. + std::vector> fils_sequences; + reorder_filaments_for_multi_nozzle_extruder(range_layer_fils.front(), new_group_result, range_layer_fils, ctx.model_info.flush_matrix, range_seq_function, + &fils_sequences, tool_status); + + // 5. store the range result + advance the nozzle state. + for (auto fil_id : fils_sequences.back()) { + auto noz = new_group_result.get_nozzle_for_filament(fil_id); + if (noz.has_value()) { + int noz_id = noz->group_id; + int ext_id = noz->extruder_id; + + fil_noz_map[fil_id] = noz_id; + fil_first_nozzle_map.emplace(static_cast(fil_id), noz_id); + + tool_status.set_current_extruder_id(ext_id); + tool_status.set_nozzle_status(noz_id, fil_id, ext_id); + } + } + + assert(fils_sequences.size() == range_layer_fils.size()); + for (size_t layer_id = 0; layer_id < fils_sequences.size(); ++layer_id) { + int g_layer_id = start_layer + static_cast(layer_id); + results[g_layer_id].fil_nozzle_match = fil_noz_map; + results[g_layer_id].fil_order = std::vector(fils_sequences[layer_id].begin(), fils_sequences[layer_id].end()); + } + } + + // Fill any never-assigned slot with the filament's first nozzle (or nozzle 0). + for (auto& res : results) { + for (int fil_id = 0; fil_id < (int) res.fil_nozzle_match.size(); fil_id++) { + auto& noz_id = res.fil_nozzle_match[fil_id]; + if (noz_id == -1) + noz_id = (used_filaments.count(fil_id) && fil_first_nozzle_map.count(fil_id)) ? fil_first_nozzle_map[fil_id] : 0; + } + } + + if (io_nozzle_status) *io_nozzle_status = tool_status; + + return results; +} + +MultiNozzleUtils::LayeredNozzleGroupResult ToolOrdering::build_sequential_group_result( + Print* print, + std::vector> nozzle_map_per_layer, + const std::vector>& layer_filaments, + const std::vector>& layer_sequences, + const std::vector& used_filaments, + const std::vector>& physical_unprintables, + const std::vector>& geometric_unprintables, + const std::map>& unprintable_volumes) +{ + MultiNozzleUtils::normalize_nozzle_map_per_layer(nozzle_map_per_layer, layer_filaments); + auto context = build_filament_group_context(print, layer_filaments, physical_unprintables, geometric_unprintables, + unprintable_volumes, FilamentMapMode::fmmAutoForFlush, {}); + auto result = MultiNozzleUtils::LayeredNozzleGroupResult::create(nozzle_map_per_layer, context.nozzle_info.nozzle_list, + used_filaments, layer_sequences); + return result ? *result : MultiNozzleUtils::LayeredNozzleGroupResult(); +} + void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first_layer) { const PrintConfig* print_config = m_print_config_ptr; @@ -1263,7 +1976,9 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first nozzle_flush_mtx.emplace_back(wipe_volumes); } - auto flush_multiplies = print_config->flush_multiplier.values; + // Fast purge mode uses flush_multiplier_fast; Default is inert. + auto flush_multiplies = (print_config->prime_volume_mode == PrimeVolumeMode::pvmFast) ? print_config->flush_multiplier_fast.values + : print_config->flush_multiplier.values; flush_multiplies.resize(nozzle_nums, 1); for (size_t nozzle_id = 0; nozzle_id < nozzle_nums; ++nozzle_id) { for (auto& vec : nozzle_flush_mtx[nozzle_id]) { @@ -1284,34 +1999,18 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first std::vector>geometric_unprintables = m_print->get_geometric_unprintable_filaments(); std::vector>physical_unprintables = m_print->get_physical_unprintable_filaments(used_filaments); + auto filament_unprintable_volumes = m_print->get_filament_unprintable_flow(used_filaments); filament_maps = m_print->get_filament_maps(); map_mode = m_print->get_filament_map_mode(); - // only check and map in sequence mode, in by object mode, we check the map in print.cpp - if (print_config->print_sequence != PrintSequence::ByObject || m_print->objects().size() == 1) { - if (map_mode < FilamentMapMode::fmmManual) { - const PrintConfig* print_config = m_print_config_ptr; - if (!print_config && m_print_object_ptr) { - print_config = &(m_print_object_ptr->print()->config()); - } - filament_maps = ToolOrdering::get_recommended_filament_maps(layer_filaments, m_print, map_mode, physical_unprintables, geometric_unprintables); - - if (filament_maps.empty()) - return; - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; }); - m_print->update_filament_maps_to_config(filament_maps); - } - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); - - if (m_print->is_BBL_printer()) - check_filament_printable_after_group(used_filaments, filament_maps, print_config); - } - else { - // we just need to change the map to 0 based - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); - } + // Grouping now yields a nozzle-aware LayeredNozzleGroupResult; the + // extruder-level filament_maps that feeds the ordering/stats below is derived from it. + MultiNozzleUtils::LayeredNozzleGroupResult grouping_result; + // The custom-sequence machinery is built before the grouping decision so both the static reorder + // and the dynamic per-layer plan can share it. Pure local setup (no dependency on the + // grouping result), so hoisting it above the branch does not change the static path's output. std::vector>filament_sequences; std::vectorfilament_lists(number_of_extruders); std::iota(filament_lists.begin(), filament_lists.end(), 0); @@ -1329,8 +2028,11 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first if (!m_layer_tools.empty()) first_layer_filaments = m_layer_tools[0].extruders; + const bool use_cyclic_ordering = + (print_config->toolchange_ordering == ToolChangeOrderingType::Cyclic); + // other_layers_seq: the layer_idx and extruder_idx are base on 1 - auto get_custom_seq = [&other_layers_seqs, &reorder_first_layer, &first_layer_filaments](int layer_idx, std::vector& out_seq) -> bool { + auto get_custom_seq = [&other_layers_seqs, &reorder_first_layer, &first_layer_filaments, &layer_filaments, use_cyclic_ordering](int layer_idx, std::vector& out_seq) -> bool { if (!reorder_first_layer && layer_idx == 0) { out_seq.resize(first_layer_filaments.size()); std::transform(first_layer_filaments.begin(), first_layer_filaments.end(), out_seq.begin(), [](auto item) {return item + 1; }); @@ -1343,23 +2045,140 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first return true; } } + + if (use_cyclic_ordering && layer_idx >= 0 && size_t(layer_idx) < layer_filaments.size()) { + std::vector ordered = layer_filaments[size_t(layer_idx)]; + std::sort(ordered.begin(), ordered.end()); + out_seq.resize(ordered.size()); + std::transform(ordered.begin(), ordered.end(), out_seq.begin(), [](auto item) { return int(item) + 1; }); + return true; + } + return false; }; + // Dynamic (per-layer filament-selector) regroup. is_dynamic_group_reorder() + // gates on enable_filament_dynamic_map (unset on every current profile), so this is closed for the + // whole shipping fleet AND H2C static mode — the static branch below is the only one they take, so + // their g-code is byte-identical. Only an H2C profile that enables the selector opens this branch. + const bool dynamic_reorder = m_print && m_print->is_dynamic_group_reorder(); + // Orca: there is no is_sequential_print() helper, so the not-sequential check is mirrored with + // the same predicate the static by-object gate below uses. Sequential prints (with more than + // one object) publish and write back from the by-object branch in Print::process instead of + // from each per-object ordering. + const bool not_sequential = print_config->print_sequence != PrintSequence::ByObject || + (m_print && m_print->objects().size() == 1); + + if (dynamic_reorder) { + // Build the grouping context, plan per-combo-range nozzle maps + filament orders, then wrap the + // per-layer maps in a selector (4-arg create) result — which sets support_dynamic_nozzle_map and + // lights the GCode per-layer hotend/nozzle placeholders. filament_sequences is produced here, so + // the static reorder below is skipped for this branch. + auto grouping_context = build_filament_group_context(m_print, layer_filaments, physical_unprintables, geometric_unprintables, filament_unprintable_volumes, FilamentMapMode::fmmAutoForFlush, + m_initial_nozzle_status.get_nozzle_filament_map()); + // The time estimator's per-extruder print times are global and do not apply to per-range + // grouping. + grouping_context.speed_info.group_with_time = false; + + m_nozzle_status = m_initial_nozzle_status; + auto dynamic_plan_res = plan_filament_mapping_and_order_by_combo_ranges(m_print, grouping_context, get_custom_seq, FilamentMapMode::fmmAutoForFlush, + physical_unprintables, geometric_unprintables, filament_unprintable_volumes, &m_nozzle_status); + + std::vector> nozzle_map_per_layer; + for (auto& res : dynamic_plan_res) { + filament_sequences.emplace_back(cast(res.fil_order)); + nozzle_map_per_layer.emplace_back(res.fil_nozzle_match); + } + + auto result = MultiNozzleUtils::LayeredNozzleGroupResult::create(nozzle_map_per_layer, grouping_context.nozzle_info.nozzle_list, used_filaments, filament_sequences); + grouping_result = result ? *result : MultiNozzleUtils::LayeredNozzleGroupResult(); + + // Derive the extruder-level map for the stats path; the write-back resolves the + // per-variant slots from the full grouping result itself. + std::vector derived_maps = grouping_result.get_extruder_map(false); // 1-based + if (!derived_maps.empty()) { + filament_maps = derived_maps; + // A sequential per-object plan must not write its own map: the objects' plans are + // stitched print-wide afterwards and written back once from there. + if (not_sequential) + m_print->update_to_config_by_nozzle_group_result(grouping_result); + } + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); + } + // only check and map in sequence mode, in by object mode, we check the map in print.cpp + else if (print_config->print_sequence != PrintSequence::ByObject || m_print->objects().size() == 1) { + grouping_result = ToolOrdering::get_recommended_filament_maps(layer_filaments, m_print, map_mode, physical_unprintables, geometric_unprintables, filament_unprintable_volumes); + std::vector derived_maps = grouping_result.get_extruder_map(false); // 1-based extruder map + + if (map_mode < FilamentMapMode::fmmManual) { + if (derived_maps.empty()) + return; + filament_maps = derived_maps; + } else if (!derived_maps.empty()) { + // Manual modes: the result mirrors the user's config map; adopt it for consistency. + filament_maps = derived_maps; + } + // Write the maps back for every mode: used filaments adopt the engine's extruder/nozzle + // choice, unused ones keep their config assignment. In manual modes the extruder map + // mirrors the user's map (a deviation throws in get_recommended_filament_maps). + if (!derived_maps.empty()) { + // Orca: the config maps are the merge base; fall back to a synthesized base when no + // producer sized them to the filament count (CLI runs until the per-filament + // synthesis lands there), where indexing per filament would run out of bounds. + std::vector base_filament_map = print_config->filament_map.values; + if (base_filament_map.size() != derived_maps.size()) + base_filament_map.assign(derived_maps.size(), 1); + std::vector base_volume_map = print_config->filament_volume_map.values; + if (base_volume_map.size() != derived_maps.size()) + base_volume_map.assign(derived_maps.size(), (int)nvtStandard); + m_print->update_filament_maps_to_config(FilamentGroupUtils::update_used_filament_values(base_filament_map, derived_maps, used_filaments), + FilamentGroupUtils::update_used_filament_values(base_volume_map, grouping_result.get_volume_map(), used_filaments), + grouping_result.get_nozzle_map()); + } + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value - 1; }); + + if (m_print->is_BBL_printer()) + check_filament_printable_after_group(used_filaments, filament_maps, print_config); + } + else { + // by-object: grouping was decided in Print.cpp; just wrap the (0-based) config map. + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); + grouping_result = build_group_result_from_map(*print_config, filament_maps, used_filaments); + } + + // The grouping result comes from the nozzle-centric engine. For single-nozzle-per-extruder printers + // (incl. H2D) each filament resolves to nozzle_id == extruder_id, so GCode's static hotend/nozzle + // placeholders are unchanged; H2C/A2L resolve to a nozzle-granular result (dynamic mode + // resolves per-layer). GCode consumes this via Print::get_layered_nozzle_group_result(). + m_nozzle_group_result = grouping_result; + // Orca: the ToolOrdering member is stored unconditionally, but the Print-level store is gated + // behind the not-sequential check hoisted above. + if (m_print != nullptr && not_sequential) + m_print->set_nozzle_group_result(std::make_shared(m_nozzle_group_result)); + auto maps_without_group = filament_maps; for (auto& item : maps_without_group) item = 0; - reorder_filaments_for_minimum_flush_volume( - filament_lists, - m_print->is_BBL_printer() ? filament_maps : maps_without_group, // non-bbl printers do not support filament group yet - layer_filaments, - nozzle_flush_mtx, - get_custom_seq, - &filament_sequences - ); + // The dynamic branch produced filament_sequences itself (per-layer selector plan); only the static + // path needs the extruder-map flush reorder here. + if (!dynamic_reorder) { + reorder_filaments_for_minimum_flush_volume( + filament_lists, + m_print->is_BBL_printer() ? filament_maps : maps_without_group, // non-bbl printers do not support filament group yet + layer_filaments, + nozzle_flush_mtx, + get_custom_seq, + &filament_sequences + ); + } - auto curr_flush_info = calc_filament_change_info_by_toolorder(print_config, filament_maps, nozzle_flush_mtx, filament_sequences); + // The three-mode flush-stat caches are now computed from the nozzle-aware grouping result via the + // nozzle-aware calc_filament_change_info_by_toolorder. Stats are GUI-only (surfaced by + // get_filament_change_stats for the mode comparison); they never feed g-code, so this block is + // byte-inert. For single-nozzle-per-extruder printers (H2D/X1/...) nozzle_id == extruder_id, so + // every cached value equals the extruder-level stats. + auto curr_flush_info = calc_filament_change_info_by_toolorder(print_config, grouping_result, nozzle_flush_mtx, filament_sequences); if (nozzle_nums <= 1) m_stats_by_single_extruder = curr_flush_info; else { @@ -1368,35 +2187,71 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first m_stats_by_multi_extruder_best = curr_flush_info; } - // in multi extruder mode,collect data with other mode + // in multi extruder mode, collect data under the other modes (for the GUI mode comparison) if (nozzle_nums > 1) { - // always calculate the info by one extruder + // always calculate the info as if a single extruder were used { - std::vector>filament_sequences_one_extruder; + std::vector> single_extruder_sequences; reorder_filaments_for_minimum_flush_volume( filament_lists, maps_without_group, layer_filaments, nozzle_flush_mtx, get_custom_seq, - &filament_sequences_one_extruder + &single_extruder_sequences ); - m_stats_by_single_extruder = calc_filament_change_info_by_toolorder(print_config, maps_without_group, nozzle_flush_mtx, filament_sequences_one_extruder); + // One logical nozzle (extruder 0, nozzle 0); every filament resolves to it. + // diameter/volume_type are unused by the stat calc. + MultiNozzleUtils::NozzleInfo single_nozzle; + single_nozzle.volume_type = NozzleVolumeType::nvtStandard; + single_nozzle.extruder_id = 0; + single_nozzle.group_id = 0; + auto single_result = MultiNozzleUtils::LayeredNozzleGroupResult::create(maps_without_group, {single_nozzle}, used_filaments); + if (single_result) + m_stats_by_single_extruder = calc_filament_change_info_by_toolorder(print_config, *single_result, nozzle_flush_mtx, single_extruder_sequences); } - // if not in best for flush mode,also calculate the info by best for flush mode + // if not already in best-for-flush mode, also calculate the info under best-for-flush grouping if (map_mode != fmmAutoForFlush) { - std::vector>filament_sequences_one_extruder; - std::vectorfilament_maps_auto = get_recommended_filament_maps(layer_filaments, m_print, fmmAutoForFlush, physical_unprintables, geometric_unprintables); - reorder_filaments_for_minimum_flush_volume( - filament_lists, - filament_maps_auto, - layer_filaments, - nozzle_flush_mtx, - get_custom_seq, - &filament_sequences_one_extruder - ); - m_stats_by_multi_extruder_best = calc_filament_change_info_by_toolorder(print_config, filament_maps_auto, nozzle_flush_mtx, filament_sequences_one_extruder); + std::vector> best_sequences; + if (dynamic_reorder) { + // When the filament selector is active the "best" plan + // is the per-combo-range dynamic regroup, computed over a *copy* of the initial nozzle + // status so it cannot perturb the chosen m_nozzle_status / primary result. NOTE: + // is_dynamic_group_reorder() implies filament_map_mode == fmmAutoForFlush, contradicting + // this map_mode != fmmAutoForFlush guard, so this sub-branch is unreachable under the + // current predicate. It is provably inert. + auto best_context = build_filament_group_context(m_print, layer_filaments, physical_unprintables, geometric_unprintables, filament_unprintable_volumes, FilamentMapMode::fmmAutoForFlush, + m_initial_nozzle_status.get_nozzle_filament_map()); + best_context.speed_info.group_with_time = false; + MultiNozzleUtils::NozzleStatusRecorder best_nozzle_status = m_initial_nozzle_status; + auto best_plan = plan_filament_mapping_and_order_by_combo_ranges(m_print, best_context, get_custom_seq, FilamentMapMode::fmmAutoForFlush, + physical_unprintables, geometric_unprintables, filament_unprintable_volumes, &best_nozzle_status); + std::vector> best_nozzle_map_per_layer; + for (auto& res : best_plan) { + best_sequences.emplace_back(cast(res.fil_order)); + best_nozzle_map_per_layer.emplace_back(res.fil_nozzle_match); + } + auto best_result = MultiNozzleUtils::LayeredNozzleGroupResult::create(best_nozzle_map_per_layer, best_context.nozzle_info.nozzle_list, used_filaments, best_sequences); + if (best_result) + m_stats_by_multi_extruder_best = calc_filament_change_info_by_toolorder(print_config, *best_result, nozzle_flush_mtx, best_sequences); + } + else { + // Best-for-flush grouping (nozzle-aware result). The extruder-level map fed to the flush + // reorder is derived exactly as before, so best_sequences (and the flush weight) are + // identical; only flush_filament_change_count is now charged per physical nozzle. + auto best_group_result = get_recommended_filament_maps(layer_filaments, m_print, fmmAutoForFlush, physical_unprintables, geometric_unprintables, filament_unprintable_volumes); + std::vector best_maps = best_group_result.get_extruder_map(); + reorder_filaments_for_minimum_flush_volume( + filament_lists, + best_maps, + layer_filaments, + nozzle_flush_mtx, + get_custom_seq, + &best_sequences + ); + m_stats_by_multi_extruder_best = calc_filament_change_info_by_toolorder(print_config, best_group_result, nozzle_flush_mtx, best_sequences); + } } } diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index 11e351b99a..c77b152fe9 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -9,6 +9,7 @@ #include #include "../FilamentGroup.hpp" +#include "../MultiNozzleUtils.hpp" #include "../ExtrusionEntity.hpp" #include "../PrintConfig.hpp" @@ -98,19 +99,23 @@ private: struct FilamentChangeStats { int filament_flush_weight{0}; + // flush_filament_change_count counts filament changes that actually flush a physical nozzle. + // It replaces the former (dead, never populated) extruder_change_count. For single-nozzle-per- + // extruder printers it equals the per-extruder filament_change_count, so GUI stat displays are + // unchanged. + int flush_filament_change_count{0}; int filament_change_count{0}; - int extruder_change_count{0}; void clear(){ filament_flush_weight = 0; filament_change_count = 0; - extruder_change_count = 0; + flush_filament_change_count = 0; } FilamentChangeStats& operator+=(const FilamentChangeStats& other) { this->filament_flush_weight += other.filament_flush_weight; this->filament_change_count += other.filament_change_count; - this->extruder_change_count += other.extruder_change_count; + this->flush_filament_change_count += other.flush_filament_change_count; return *this; } @@ -118,7 +123,7 @@ struct FilamentChangeStats FilamentChangeStats ret; ret.filament_flush_weight = this->filament_flush_weight + other.filament_flush_weight; ret.filament_change_count = this->filament_change_count + other.filament_change_count; - ret.extruder_change_count = this->extruder_change_count + other.extruder_change_count; + ret.flush_filament_change_count = this->flush_filament_change_count + other.flush_filament_change_count; return ret; } @@ -236,12 +241,44 @@ public: bool has_wipe_tower() const { return ! m_layer_tools.empty() && m_first_printing_extruder != (unsigned int)-1 && m_layer_tools.front().has_wipe_tower; } int get_most_used_extruder() const { return most_used_extruder; } + + // Logical (extruder, nozzle) grouping of the used filaments, built during reorder. + // For single-nozzle printers this is one logical nozzle per extruder (nozzle id == extruder id). + // Consumed by GCode (get_nozzle_id / get_first_nozzle_for_filament). + const MultiNozzleUtils::LayeredNozzleGroupResult &get_layered_nozzle_group_result() const { return m_nozzle_group_result; } + + // Physical nozzle occupancy threading for the sequential (by-object) selector regroup: the + // setter seeds both the initial recorder (the state the per-layer plan starts from) and the + // running recorder (read back after sort_and_build_data via get_nozzle_status()), so each + // object's plan continues from the nozzle state the previous object ended with. + const MultiNozzleUtils::NozzleStatusRecorder &get_nozzle_status() const { return m_nozzle_status; } + void set_nozzle_status(const MultiNozzleUtils::NozzleStatusRecorder &status) { m_initial_nozzle_status = status; m_nozzle_status = status; } /* * called in single extruder mode, the value in map are all 0 * called in dual extruder mode, the value in map will be 0 or 1 * 0 based group id */ - static std::vector get_recommended_filament_maps(const std::vector>& layer_filaments, const Print* print,const FilamentMapMode mode, const std::vector>& physical_unprintables, const std::vector>& geometric_unprintables); + // Nozzle-centric grouping. Returns a nozzle-aware LayeredNozzleGroupResult instead of a plain + // extruder-level std::vector. Callers derive the 0/1-based extruder map via + // result.get_extruder_map(). unprintable_volumes / nozzle_status default empty for the static + // path; the per-layer engine supplies non-empty values. + static MultiNozzleUtils::LayeredNozzleGroupResult get_recommended_filament_maps(const std::vector>& layer_filaments, const Print* print,const FilamentMapMode mode, const std::vector>& physical_unprintables, const std::vector>& geometric_unprintables, const std::map>& unprintable_volumes = {}, const std::unordered_map& nozzle_status = {}); + + // Wrap stitched per-layer filament->nozzle maps from a sequential (by-object) selector regroup + // into one print-wide result. nozzle_map_per_layer / layer_filaments / layer_sequences are the + // per-object planned layers concatenated in print order; nozzle_map_per_layer is taken by value + // and normalized in place. The nozzle list is rebuilt from the print's grouping context. Returns + // an empty result when the wrap fails. Lives here (not in Print) to reach the file-local + // grouping-context builder. + static MultiNozzleUtils::LayeredNozzleGroupResult build_sequential_group_result( + Print* print, + std::vector> nozzle_map_per_layer, + const std::vector>& layer_filaments, + const std::vector>& layer_sequences, + const std::vector& used_filaments, + const std::vector>& physical_unprintables, + const std::vector>& geometric_unprintables, + const std::map>& unprintable_volumes); // should be called after doing reorder FilamentChangeStats get_filament_change_stats(FilamentChangeMode mode); @@ -283,6 +320,13 @@ private: FilamentChangeStats m_stats_by_single_extruder; FilamentChangeStats m_stats_by_multi_extruder_curr; FilamentChangeStats m_stats_by_multi_extruder_best; + MultiNozzleUtils::LayeredNozzleGroupResult m_nozzle_group_result; + // Physical nozzle occupancy threaded through the per-layer selector regroup. + // m_initial_nozzle_status seeds the first combo range (empty for a fresh slice — there is no + // device continuation state); m_nozzle_status carries the running state out of the plan. Inert + // for every printer except an H2C profile that enables the filament selector (is_dynamic_group_reorder). + MultiNozzleUtils::NozzleStatusRecorder m_initial_nozzle_status; + MultiNozzleUtils::NozzleStatusRecorder m_nozzle_status; int most_used_extruder; }; diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 13807c191b..58df527da5 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -1493,6 +1494,21 @@ WipeTower::WipeTower(const PrintConfig& config, int plate_idx, Vec3d plate_origi m_enable_tower_interface_cooldown_during_tower(config.enable_tower_interface_cooldown_during_tower.value) { m_flat_ironing = (m_flat_ironing && m_use_gap_wall); + + // Prime-tower heating during wipe. m_is_multiple_nozzle mirrors the gate used in ToolOrdering/GCode + // (std::any_of extruder_max_nozzle_count > 1); it is false for every current printer, so the + // heating-during-wipe logic in toolchange_wipe_new is inert. + m_hotend_heating_rate = config.hotend_heating_rate.values; + m_physical_extruder_map = config.physical_extruder_map.values; + m_is_multiple_nozzle = std::any_of(config.extruder_max_nozzle_count.values.begin(), + config.extruder_max_nozzle_count.values.end(), + [](int v) { return v > 1; }); + + // Per-extruder printable-height clamp. Empty for single-extruder printers + // (extruder_printable_height = []), so is_valid_last_layer is inert there. + m_printable_height = config.extruder_printable_height.values; + m_last_layer_id.assign(config.nozzle_diameter.size(), -1); + // Read absolute value of first layer speed, if given as percentage, // it is taken over following default. Speeds from config are not // easily accessible here. @@ -1543,6 +1559,10 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config) //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector m_filpar.push_back(FilamentParameters()); + // Orca: one row per filament, indexed by the raw filament id. Under a per-layer nozzle + // grouping the per-variant arrays may hold several columns per filament; the tower has no + // layer dimension here, so it keeps the filament's first column (tower x per-layer + // grouping is a documented follow-up). m_filpar[idx].material = config.filament_type.get_at(idx); m_filpar[idx].is_soluble = config.wipe_tower_filament == 0 ? config.filament_soluble.get_at(idx) : (idx != size_t(config.wipe_tower_filament - 1)); // BBS @@ -1558,8 +1578,12 @@ void WipeTower::set_extruder(size_t idx, const PrintConfig& config) } m_filpar[idx].tower_interface_pre_extrusion_dist = config.filament_tower_interface_pre_extrusion_dist.get_at(idx); m_filpar[idx].tower_interface_pre_extrusion_length = config.filament_tower_interface_pre_extrusion_length.get_at(idx); + // PETG pre-extrusion offset reuses the tower-interface pre-extrusion distance. Only read by the + // has_filament_switcher-gated PETG branch in get_next_pos (inert fleet-wide). + m_filpar[idx].petg_pre_extrusion_offset_dist = config.filament_tower_interface_pre_extrusion_dist.get_at(idx); m_filpar[idx].tower_ironing_area = config.filament_tower_ironing_area.get_at(idx); m_filpar[idx].tower_interface_purge_length = config.filament_tower_interface_purge_volume.get_at(idx); + m_filpar[idx].filament_cooling_before_tower = config.filament_cooling_before_tower.get_at(idx); // If this is a single extruder MM printer, we will use all the SE-specific config values. // Otherwise, the defaults will be used to turn off the SE stuff. @@ -1651,6 +1675,27 @@ Vec2f WipeTower::get_next_pos(const WipeTower::box_coordinates &cleaning_box, fl break; default: break; } + // Shift the wipe start outward for a PETG pre-extrusion on filament-switcher devices, clamped to the + // shared printable bed. Gated on m_has_filament_switcher, which is false for the whole shipping fleet + // (no profile sets the key), so is_petg_pre_extrusion is always false and res is returned unchanged. + // The tower-interface contact branch is deliberately NOT applied here (enable_tower_interface_features + // DOES ship on H2C/X2D; applying it would change their g-code); is_contact_pre_extrusion is computed + // only as the guard that gives the contact path priority over PETG. + bool is_contact_pre_extrusion = interface_layer && m_enable_tower_interface_features; + bool is_petg_pre_extrusion = !is_contact_pre_extrusion && is_petg_filament(m_current_tool) && m_has_filament_switcher; + if (is_petg_pre_extrusion) { + Vec2f stop_pos = res; + float offset_dist = m_filpar[m_current_tool].petg_pre_extrusion_offset_dist; + auto printer_bbx = unscaled(get_extents(m_shared_print_bed)); // BoundingBoxBase + printer_bbx.translate((-m_wipe_tower_pos - m_rib_offset).cast()); + if (stop_pos.x() < m_wipe_tower_width / 2.f) + stop_pos = Vec2f(stop_pos.x() - offset_dist, stop_pos.y()); + else + stop_pos = Vec2f(stop_pos.x() + offset_dist, stop_pos.y()); + if (stop_pos.x() < printer_bbx.min[0]) stop_pos.x() = printer_bbx.min[0]; + if (stop_pos.x() > printer_bbx.max[0]) stop_pos.x() = printer_bbx.max[0]; + res = stop_pos; + } return res; } @@ -2645,6 +2690,11 @@ bool WipeTower::is_tpu_filament(int filament_id) const return m_filpar[filament_id].material == "TPU"; } +bool WipeTower::is_petg_filament(int filament_id) const +{ + return m_filpar[filament_id].material == "PETG"; +} + // BBS: consider both soluable and support properties // Return index of first toolchange that switches to non-soluble and non-support extruder // ot -1 if there is no such toolchange. @@ -2717,6 +2767,9 @@ void WipeTower::get_wall_skip_points(const WipeTowerInfo &layer) float spacing = m_layer_info->extra_spacing; if (has_tpu_filament() && m_layer_info->extra_spacing < m_tpu_fixed_spacing) spacing = 1; float nozzle_change_depth = tool_change.nozzle_change_depth * spacing; + // Drop the nozzle-change depth on an extruder's final layer above its printable height + // (inert unless is_valid_last_layer clamps, i.e. multi-extruder near Z-max). + if (!is_valid_last_layer(old_filament, m_cur_layer_id, layer.z)) nozzle_change_depth = 0.f; //float nozzle_change_depth = tool_change.nozzle_change_depth * (has_tpu_filament() ? m_tpu_fixed_spacing : layer.extra_spacing); auto* block = get_block_by_category(m_filpar[new_filament].category, false); if (!block) @@ -2760,7 +2813,10 @@ void WipeTower::get_wall_skip_points(const WipeTowerInfo &layer) WipeTower::ToolChangeResult WipeTower::tool_change_new(size_t new_tool, bool solid_toolchange,bool solid_nozzlechange) { m_nozzle_change_result.gcode.clear(); - if (!m_filament_map.empty() && new_tool < m_filament_map.size() && m_filament_map[m_current_tool] != m_filament_map[new_tool]) { + // Skip the cross-extruder nozzle change (ramming) on an extruder's final layer above its printable + // height. is_valid_last_layer is inert unless multi-extruder near Z-max. + if (!m_filament_map.empty() && new_tool < m_filament_map.size() && m_filament_map[m_current_tool] != m_filament_map[new_tool] + && is_valid_last_layer(m_current_tool, m_cur_layer_id, m_z_pos)) { m_nozzle_change_result = nozzle_change_new(m_current_tool, new_tool, solid_nozzlechange); } @@ -3411,23 +3467,103 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat x_to_wipe = solid_tool_toolchange ? std::numeric_limits::max(): x_to_wipe; float target_speed = is_first_layer() ? std::min(m_first_layer_speed * 60.f, 4800.f) : 4800.f; target_speed = solid_tool_toolchange ? 20.f * 60.f : target_speed; - float wipe_speed = 0.33f * target_speed; + // Nominal wipe-speed schedule. The applied wipe_speed is nominal_speed * speed_factor; speed_factor + // stays 1.0 unless the H2C prime-tower heating-during-wipe model below slows the wipe so the hotend + // can reach temperature (nominal_speed == wipe_speed when speed_factor == 1, i.e. single-nozzle). + float nominal_speed = 0.33f * target_speed; m_left_to_right = ((m_cur_layer_id + 3) % 4 >= 2); bool is_from_up = (m_cur_layer_id % 2 == 1); + // Prime-tower heating during wipe. Everything here is gated on m_is_multiple_nozzle (false for every + // current printer); the lambdas emit nothing until add_M104_by_requirement's gate opens, so the + // single-nozzle wipe is untouched. + // WipeSpeedMap mirrors the nominal schedule above and is read only by estimate_wipe_time. It is a + // std::array (stack, no per-call heap allocation); values depend on runtime target_speed so it + // cannot be static const. + const std::array WipeSpeedMap{0.33f * target_speed, 0.375f * target_speed, 0.458f * target_speed, + 0.875f * target_speed, std::min(target_speed, 0.875f * target_speed + 50.f)}; + auto estimate_wipe_time = [&cleaning_box, &x_to_wipe, &xr, &xl, &dy, &WipeSpeedMap, &solid_tool_toolchange]() -> float { + int n = std::ceil(x_to_wipe / (xr - xl)); + if (solid_tool_toolchange) n = (cleaning_box.lu[1] - cleaning_box.ld[1]) / dy; + float one_line_len = xr - xl; + float time = std::numeric_limits::max(); + if (n <= 1) + time = one_line_len / WipeSpeedMap[0]; + else if (n <= 2) + time = one_line_len / WipeSpeedMap[0] + one_line_len / WipeSpeedMap[1]; + else if (n <= 3) + time = one_line_len / WipeSpeedMap[0] + one_line_len / WipeSpeedMap[1] + one_line_len / WipeSpeedMap[2]; + else if (n <= 4) + time = one_line_len / WipeSpeedMap[0] + one_line_len / WipeSpeedMap[1] + one_line_len / WipeSpeedMap[2] + one_line_len / WipeSpeedMap[3]; + else { + time = one_line_len / WipeSpeedMap[0] + one_line_len / WipeSpeedMap[1] + one_line_len / WipeSpeedMap[2] + one_line_len / WipeSpeedMap[3]; + time += (n - 4) * one_line_len / WipeSpeedMap[4]; + } + return time * 60.f; + }; + // Emit the arriving-hotend pre-heat inside the M632/M633 nozzle-change barrier. `M632 S[ H] + // M N` opens the barrier (M = firmware nozzle-change flag, N = slicer generated), the M104 sets the + // arriving hotend temp, and `M633` closes it. H2C's grouping is static (no dynamic nozzle map), so the + // H field is omitted (a dynamic nozzle map would supply a real nozzle id, a static map -1 => no + // H). The counterproductive fan-on (M106 S255) used for departing-tool cooldown is intentionally + // omitted, since this is a pre-HEAT of the arriving tool. The whole helper is only ever called from + // add_M104_by_requirement, which is gated on m_is_multiple_nozzle (extruder_max_nozzle_count>1) => H2C + // only; every other printer's wipe tower is untouched. The M632 M-flag is itself a firmware barrier, so + // a preceding M400 wait is subsumed. + auto format_line_M104 = [this](int target_temp, int target_extruder = -1, bool wait_for_moves = true, const std::string &comment = "") { + std::string buffer; + buffer += "M632 S" + std::to_string(m_current_tool) + " M N\n"; + buffer += "M104"; + if (target_extruder != -1 && target_extruder < (int) m_physical_extruder_map.size()) + buffer += (" T" + std::to_string(m_physical_extruder_map[target_extruder])); + buffer += " S" + std::to_string(target_temp) + " N0"; // N0 means the gcode is generated by the slicer + if (!comment.empty()) buffer += " ;" + comment; + buffer += '\n'; + buffer += "M633\n"; + (void) wait_for_moves; // the M632 M-flag barrier replaces the former M400 wait + return buffer; + }; + // Suppress the pre-heat M104 on the first layer and on solid (contact) toolchanges (should_heating). + // m_is_multiple_nozzle folds in the H2C gate so single-nozzle output is untouched. + // Orca: the arriving extruder id is resolved as m_filament_map[tool]-1 (layer-static) because Orca's + // wipe tower is extruder-level rather than tracking a per-layer nozzle map. + bool should_heating = m_is_multiple_nozzle && m_filpar[m_current_tool].filament_cooling_before_tower > EPSILON && + !solid_tool_toolchange && !is_first_layer(); + auto add_M104_by_requirement = [&writer, &format_line_M104, &should_heating, this]() { + if (m_filpar[m_current_tool].filament_cooling_before_tower < EPSILON) return; + if (!should_heating) return; + float target_temp = is_first_layer() ? m_filpar[m_current_tool].nozzle_temperature_initial_layer : m_filpar[m_current_tool].nozzle_temperature; + writer.append(format_line_M104(target_temp, m_filament_map[m_current_tool] - 1)); + }; + float speed_factor = 1.f; + if (should_heating) { + // The heating-slowdown scaling is disabled — no additional heating time is required, so + // speed_factor stays 1.0. The structure and estimate_wipe_time/WipeSpeedMap are retained for + // future H2C tuning; the divide-by-zero/bounds guard is preserved in the commented body below. + // int extruder_id = m_filament_map[m_current_tool] - 1; + // if (extruder_id >= 0 && extruder_id < (int) m_hotend_heating_rate.size() && m_hotend_heating_rate[extruder_id] > 0.) { + // float estimate_time = estimate_wipe_time(); + // float heat_time = m_filpar[m_current_tool].filament_cooling_before_tower / m_hotend_heating_rate[extruder_id]; + // if (estimate_time < heat_time) speed_factor = estimate_time / heat_time; + // } + (void) estimate_wipe_time; // retain scaffolding above without an unused-lambda warning + } + float wipe_speed = nominal_speed * speed_factor; + // now the wiping itself: for (int i = 0; true; ++i) { if (i != 0) { - if (wipe_speed < 0.34f * target_speed) - wipe_speed = 0.375f * target_speed; - else if (wipe_speed < 0.377 * target_speed) - wipe_speed = 0.458f * target_speed; - else if (wipe_speed < 0.46f * target_speed) - wipe_speed = 0.875f * target_speed; + if (nominal_speed < 0.34f * target_speed) + nominal_speed = 0.375f * target_speed; + else if (nominal_speed < 0.377 * target_speed) + nominal_speed = 0.458f * target_speed; + else if (nominal_speed < 0.46f * target_speed) + nominal_speed = 0.875f * target_speed; else - wipe_speed = std::min(target_speed, wipe_speed + 50.f); + nominal_speed = std::min(target_speed, nominal_speed + 50.f); + wipe_speed = nominal_speed * speed_factor; } bool need_change_flow = need_thick_bridge_flow(writer.y()); @@ -3453,6 +3589,7 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat } else writer.travel(writer.x() + 1.5 * ironing_length, writer.y(), 240.); writer.retract(-retract_length, retract_speed); + add_M104_by_requirement(); // Pre-heat the arriving hotend during the wipe writer.extrude(xr + wipe_tower_wall_infill_overlap * m_perimeter_width, writer.y(), wipe_speed); } else { float dx = xl - wipe_tower_wall_infill_overlap * m_perimeter_width - writer.pos().x(); @@ -3468,9 +3605,11 @@ void WipeTower::toolchange_wipe_new(WipeTowerWriter &writer, const box_coordinat }else writer.travel(writer.x() - 1.5 * ironing_length, writer.y(), 240.); writer.retract(-retract_length, retract_speed); + add_M104_by_requirement(); // Pre-heat the arriving hotend during the wipe writer.extrude(xl - wipe_tower_wall_infill_overlap * m_perimeter_width, writer.y(), wipe_speed); } } else { + if (i == 0) add_M104_by_requirement(); // Pre-heat the arriving hotend during the wipe if (m_left_to_right) writer.extrude(xr + wipe_tower_wall_infill_overlap * m_perimeter_width, writer.y(), wipe_speed); else @@ -3571,6 +3710,47 @@ bool WipeTower::is_in_same_extruder(int filament_id_1, int filament_id_2) return m_filament_map[filament_id_1] == m_filament_map[filament_id_2]; } +// Per-extruder printable-height clamp: is an extruder still allowed to print on this wipe-tower layer, +// or is it its final layer above the extruder's printable height? +// Orca: the arriving extruder id is resolved as m_filament_map[tool]-1 (1-based map, layer-static), +// because Orca's wipe tower is extruder-level rather than tracking a per-layer nozzle map (the same +// idiom the pre-heat path uses in toolchange_wipe_new). Gated on m_is_multi_extruder so that +// single-extruder printers (including ones whose extruder_printable_height defaults to {0}) always +// return true and leave wipe-tower g-code unchanged. +bool WipeTower::is_valid_last_layer(int tool, int layer_id, double layer_z) const +{ + if (!m_is_multi_extruder) + return true; + int extruder_id = (tool >= 0 && tool < (int) m_filament_map.size()) ? m_filament_map[tool] - 1 : -1; + if (extruder_id < 0 || extruder_id >= (int) m_printable_height.size() || extruder_id >= (int) m_last_layer_id.size()) + return true; + if (m_last_layer_id[extruder_id] == layer_id && layer_z > m_printable_height[extruder_id]) + return false; + return true; +} + +// Records, per extruder, the last wipe-tower layer index that uses it, so is_valid_last_layer can +// recognise the extruder's final layer. Inert for single-extruder printers (early return); +// bounds-checked because m_filament_map may be empty/short. +void WipeTower::set_nozzle_last_layer_id() +{ + if (!m_is_multi_extruder) + return; + for (int idx = 0; idx < (int) m_plan.size(); ++idx) { + const auto &info = m_plan[idx]; + for (const auto &tc : info.tool_changes) { + int old_tool = (int) tc.old_tool; + int new_tool = (int) tc.new_tool; + int old_ext = (old_tool >= 0 && old_tool < (int) m_filament_map.size()) ? m_filament_map[old_tool] - 1 : -1; + int new_ext = (new_tool >= 0 && new_tool < (int) m_filament_map.size()) ? m_filament_map[new_tool] - 1 : -1; + if (old_ext >= 0 && old_ext < (int) m_last_layer_id.size()) + m_last_layer_id[old_ext] = idx; + if (new_ext >= 0 && new_ext < (int) m_last_layer_id.size()) + m_last_layer_id[new_ext] = idx; + } + } +} + void WipeTower::reset_block_status() { for (auto &block : m_wipe_tower_blocks) { @@ -3797,6 +3977,7 @@ void WipeTower::plan_tower_new() } update_all_layer_depth(max_depth); + set_nozzle_last_layer_id(); // record per-extruder last layer for is_valid_last_layer float diagonal = sqrt(m_wipe_tower_depth * m_wipe_tower_depth + m_wipe_tower_width * m_wipe_tower_width); m_rib_length = std::max({m_rib_length, diagonal}); m_rib_length += m_extra_rib_length; @@ -3916,9 +4097,12 @@ void WipeTower::generate_new(std::vector m_hotend_heating_rate; // config.hotend_heating_rate (deg/s per extruder) + std::vector m_physical_extruder_map; // logical extruder -> physical tool number (M104 T param) + + // Per-extruder printable-height clamp. m_printable_height = config.extruder_printable_height + // (per-extruder Z limit; empty for single-extruder printers, [320,325] for H2D). m_last_layer_id + // records, per extruder, the last wipe-tower layer that uses it. is_valid_last_layer() is gated on + // m_is_multi_extruder so single-extruder wipe-tower g-code is unchanged; the clamp only bites a + // multi-extruder wipe tower whose final per-extruder layer exceeds that extruder's printable + // height (near the Z limit). + std::vector m_printable_height; + std::vector m_last_layer_id; + // Bed properties enum { RectangularBed, @@ -501,6 +530,11 @@ private: bool m_flat_ironing=false; bool m_enable_tower_interface_features=false; bool m_enable_tower_interface_cooldown_during_tower=false; + // Filament-switcher device flag + shared printable bed for the PETG pre-extrusion offset. + // m_has_filament_switcher is false for the whole shipping fleet (no profile sets the key), so + // the PETG branch in get_next_pos never runs -> no change fleet-wide. + bool m_has_filament_switcher=false; + Polygons m_shared_print_bed; bool m_prev_layer_had_interface=false; bool m_current_layer_has_interface=false; // Calculates length of extrusion line to extrude given volume @@ -520,6 +554,7 @@ private: void save_on_last_wipe(); bool is_tpu_filament(int filament_id) const; + bool is_petg_filament(int filament_id) const; // BBS box_coordinates align_perimeter(const box_coordinates& perimeter_box); @@ -586,6 +621,12 @@ private: const box_coordinates &cleaning_box, float wipe_volume); void get_wall_skip_points(const WipeTowerInfo &layer); + + // Per-extruder printable-height clamp (see m_printable_height). is_valid_last_layer returns + // false only for a multi-extruder wipe tower's final per-extruder layer that exceeds that + // extruder's printable height; returns true (no clamp) in every other case. + bool is_valid_last_layer(int tool, int layer_id, double layer_z) const; + void set_nozzle_last_layer_id(); }; diff --git a/src/libslic3r/GCode/WipeTower2.cpp b/src/libslic3r/GCode/WipeTower2.cpp index 7950034bb1..34b385d4be 100644 --- a/src/libslic3r/GCode/WipeTower2.cpp +++ b/src/libslic3r/GCode/WipeTower2.cpp @@ -1333,6 +1333,10 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config) //while (m_filpar.size() < idx+1) // makes sure the required element is in the vector m_filpar.push_back(FilamentParameters()); + // Orca: one row per filament, indexed by the raw filament id. Under a per-layer nozzle + // grouping the per-variant arrays may hold several columns per filament; the tower has no + // layer dimension here, so it keeps the filament's first column (tower x per-layer + // grouping is a documented follow-up). m_filpar[idx].material = config.filament_type.get_at(idx); if (m_wipe_tower_filament > 0) m_filpar[idx].is_soluble = (idx != size_t(m_wipe_tower_filament - 1)); diff --git a/src/libslic3r/GCodeWriter.cpp b/src/libslic3r/GCodeWriter.cpp index a3d8e66ac3..26db1c61e5 100644 --- a/src/libslic3r/GCodeWriter.cpp +++ b/src/libslic3r/GCodeWriter.cpp @@ -110,6 +110,7 @@ void GCodeWriter::set_extruders(std::vector extruder_ids) m_filament_extruders.clear(); //ORCA: Reset current extruder ID and clear pointers to prevent dangling pointers when extruders are recreated. m_curr_extruder_id = -1; + m_cached_extruder_idx = 0; std::fill(m_curr_filament_extruder.begin(), m_curr_filament_extruder.end(), nullptr); m_filament_extruders.reserve(extruder_ids.size()); for (unsigned int extruder_id : extruder_ids) @@ -594,36 +595,36 @@ std::string GCodeWriter::update_progress(unsigned int num, unsigned int tot, boo std::string GCodeWriter::toolchange_prefix() const { - std::string gcode = "T"; + // Orca: the manual-filament-change tag must stay ahead of the flavor selection so + // MMU manual-change handling keeps working. 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; + return ";" + GCodeProcessor::reserved_tag(GCodeProcessor::ETags::Manual_Tool_Change) + "T"; + return FLAVOR_IS(gcfMakerWare) ? "M135 T" : + FLAVOR_IS(gcfSailfish) ? "M108 T" : "T"; } -std::string GCodeWriter::toolchange(unsigned int filament_id) +std::string GCodeWriter::toolchange(unsigned int filament_id, int nozzle_id) { // set the new extruder auto filament_extruder_iter = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), [filament_id](const Extruder &e) { return e.id() < filament_id; }); assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id); m_curr_extruder_id = filament_extruder_iter->extruder_id(); m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter; + m_cached_extruder_idx = get_extruder_index(this->config, filament_id); // return the toolchange command // if we are running a single-extruder setup, just set the extruder and return nothing std::ostringstream gcode; + // Orca: also emit for non-BBL single-extruder multi-filament setups (MMU-style). if (this->multiple_extruders || (this->config.filament_diameter.values.size() > 1 && !is_bbl_printers())) { - // Orca: call toolchange_prefix() to get the correct command prefix based on the configuration and flavor. - gcode << this->toolchange_prefix() << filament_id; + // Orca: manual filament change keeps its tag line even on BBL machines, so the + // M1020 form must not shadow it. nozzle_id is signed: the null-safe nozzle + // lookup legitimately yields -1 ("no specific nozzle"), matching the literal + // H-1 the stock change templates emit; an unsigned would wrap. + if (m_is_bbl_printers && !config.manual_filament_change) + gcode << "M1020 S" << filament_id << " H" << nozzle_id; + else + gcode << this->toolchange_prefix() << filament_id; if (GCodeWriter::full_gcode_comment) gcode << " ; change extruder"; gcode << "\n"; @@ -632,6 +633,25 @@ std::string GCodeWriter::toolchange(unsigned int filament_id) return gcode.str(); } +// Current parked-retract length of the filament's extruder, share-aware. m_filament_extruders is +// sorted by id (see toolchange), so a lower_bound lookup finds the entry; unknown filament ids +// degrade to 0 rather than dereferencing end(). +double GCodeWriter::get_extruder_retracted_length(const int filament_id) +{ + double res = 0.0; + auto filament_extruder_iter = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), + [filament_id](const Extruder &e) { return (int) e.id() < filament_id; }); + if (filament_extruder_iter == m_filament_extruders.end() || (int) filament_extruder_iter->id() != filament_id) + return res; + + if (filament_extruder_iter->is_share_extruder()) + res = filament_extruder_iter->get_share_retracted_length(); + else + res = filament_extruder_iter->get_single_retracted_length(); + + return res; +} + std::string GCodeWriter::set_speed(double F, const std::string &comment, const std::string &cooling_marker) { assert(F > 0.); @@ -658,7 +678,7 @@ std::string GCodeWriter::travel_to_xy(const Vec2d &point, const std::string &com GCodeG1Formatter w; w.emit_xy(point_on_plate); auto speed = m_is_first_layer - ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())); + ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx); w.emit_f(speed * 60.0); //BBS w.emit_comment(GCodeWriter::full_gcode_comment, comment); @@ -744,7 +764,7 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co // BBS Vec3d dest_point = point; auto travel_speed = - m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())); + m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) : this->config.travel_speed.get_at(m_cached_extruder_idx); //BBS: a z_hop need to be handle when travel if (std::abs(m_to_lift) > EPSILON) { assert(std::abs(m_lifted) < EPSILON); @@ -841,13 +861,13 @@ std::string GCodeWriter::travel_to_xyz(const Vec3d &point, const std::string &co { //force to move xy first then z after filament change w.emit_xy(Vec2d(point_on_plate.x(), point_on_plate.y())); - w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0); + w.emit_f(this->config.travel_speed.get_at(m_cached_extruder_idx) * 60.0); w.emit_comment(GCodeWriter::full_gcode_comment, comment); out_string = w.string() + _travel_to_z(point_on_plate.z(), comment); } else { GCodeG1Formatter w; w.emit_xyz(point_on_plate); - w.emit_f(this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())) * 60.0); + w.emit_f(this->config.travel_speed.get_at(m_cached_extruder_idx) * 60.0); w.emit_comment(GCodeWriter::full_gcode_comment, comment); out_string = w.string(); } @@ -880,10 +900,10 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment) { m_pos(2) = z; - double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id())); + double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx); if (speed == 0.) { - speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) - : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())); + speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) + : this->config.travel_speed.get_at(m_cached_extruder_idx); } GCodeG1Formatter w; @@ -897,11 +917,11 @@ std::string GCodeWriter::_travel_to_z(double z, const std::string &comment) std::string GCodeWriter::_spiral_travel_to_z(double z, const Vec2d &ij_offset, const std::string &comment) { std::string output; - double speed = this->config.travel_speed_z.get_at(get_extruder_index(this->config, filament()->id())); + double speed = this->config.travel_speed_z.get_at(m_cached_extruder_idx); if (speed == 0.) { - speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", get_extruder_index(this->config, filament()->id())) - : this->config.travel_speed.get_at(get_extruder_index(this->config, filament()->id())); + speed = m_is_first_layer ? this->config.get_abs_value_at("initial_layer_travel_speed", m_cached_extruder_idx) + : this->config.travel_speed.get_at(m_cached_extruder_idx); } if (!this->config.enable_arc_fitting) { // Orca: if arc fitting is disabled, approximate the arc with small linear segments @@ -1101,7 +1121,7 @@ std::string GCodeWriter::_retract(double length, double restart_extra, const std return gcode; } -std::string GCodeWriter::unretract() +std::string GCodeWriter::unretract(float extra_retract) { std::string gcode; @@ -1117,7 +1137,9 @@ std::string GCodeWriter::unretract() //BBS // use G1 instead of G0 because G0 will blend the restart with the previous travel move GCodeG1Formatter w; - w.emit_e(filament()->E()); + // extra_retract over-extrudes for the PETG pre-extrusion; 0 by + // default -> identical to the plain deretract E position. + w.emit_e(filament()->E() + extra_retract); w.emit_f(filament()->deretract_speed() * 60.); //BBS w.emit_comment(GCodeWriter::full_gcode_comment, " ; unretract"); @@ -1250,8 +1272,9 @@ std::string GCodeWriter::set_extruder(unsigned int filament_id) auto filament_ext_it = Slic3r::lower_bound_by_predicate(m_filament_extruders.begin(), m_filament_extruders.end(), [filament_id](const Extruder &e) { return e.id() < filament_id; }); unsigned int extruder_id = filament_ext_it->extruder_id(); assert(filament_ext_it != m_filament_extruders.end() && filament_ext_it->id() == filament_id); - //TODO: optmize here, pass extruder_id to toolchange - return this->need_toolchange(filament_id) ? this->toolchange(filament_id) : ""; + // Orca: writer-only context (calibration paths) has no nozzle grouping; the + // filament's own extruder id is the correct degenerate nozzle value. + return this->need_toolchange(filament_id) ? this->toolchange(filament_id, (int) extruder_id) : ""; } void GCodeWriter::init_extruder(unsigned int filament_id) @@ -1261,6 +1284,7 @@ void GCodeWriter::init_extruder(unsigned int filament_id) assert(filament_extruder_iter != m_filament_extruders.end() && filament_extruder_iter->id() == filament_id); m_curr_extruder_id = filament_extruder_iter->extruder_id(); m_curr_filament_extruder[m_curr_extruder_id] = &*filament_extruder_iter; + m_cached_extruder_idx = get_extruder_index(this->config, filament_id); } } diff --git a/src/libslic3r/GCodeWriter.hpp b/src/libslic3r/GCodeWriter.hpp index d3f419df7c..2e7ea2176c 100644 --- a/src/libslic3r/GCodeWriter.hpp +++ b/src/libslic3r/GCodeWriter.hpp @@ -19,6 +19,7 @@ public: GCodeWriter() : multiple_extruders(false), m_curr_filament_extruder(MAXIMUM_EXTRUDER_NUMBER, nullptr), m_curr_extruder_id (-1), + m_cached_extruder_idx(0), m_single_extruder_multi_material(false), m_last_acceleration(0), m_max_acceleration(0),m_last_travel_acceleration(0), m_max_travel_acceleration(0), m_last_jerk(0), m_max_jerk_x(0), m_max_jerk_y(0), @@ -66,10 +67,13 @@ public: bool need_toolchange(unsigned int filament_id) const; std::string set_extruder(unsigned int filament_id); void init_extruder(unsigned int filament_id); + // Current parked-retract length of a filament's extruder (share-aware). Used for the + // new_extruder_retracted_length change-filament placeholder. Returns 0 if the filament is unknown. + double get_extruder_retracted_length(const int filament_id); // Prefix of the toolchange G-code line, to be used by the CoolingBuffer to separate sections of the G-code // printed with the same extruder. std::string toolchange_prefix() const; - std::string toolchange(unsigned int filament_id); + std::string toolchange(unsigned int filament_id, int nozzle_id); std::string set_speed(double F, const std::string &comment = std::string(), const std::string &cooling_marker = std::string()); // SoftFever NOTE: the returned speed is mm/minute double get_current_speed() const { return m_current_speed;} @@ -83,7 +87,9 @@ public: std::string extrude_to_xyz(const Vec3d &point, double dE, const std::string &comment = std::string(), bool force_no_extrusion = false); std::string retract(bool before_wipe = false, double retract_length = 0); std::string retract_for_toolchange(bool before_wipe = false, double retract_length = 0); - std::string unretract(); + // extra_retract adds a small over-extrusion to the deretract move (PETG pre-extrusion). + // Default 0 -> byte-identical to the plain deretract. + std::string unretract(float extra_retract = 0.f); // do lift instantly std::string eager_lift(const LiftType type); // record a lift request, do realy lift in next travel @@ -135,6 +141,8 @@ public: bool m_single_extruder_multi_material; std::vector m_curr_filament_extruder; int m_curr_extruder_id; + // Motion uses the global/base process variant until a filament becomes active. + size_t m_cached_extruder_idx; unsigned int m_last_acceleration; unsigned int m_last_travel_acceleration; std::vector m_max_travel_acceleration; diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index d871bcbea2..8a5aa78036 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -157,6 +157,10 @@ public: ExPolygons lslices; ExPolygons lslices_extrudable; // BBS: the extrudable part of lslices used for tree support std::vector lslices_bboxes; + // Orca: for separated infills / per-model centering. Aligned with lslices: for each island, the + // full bounding box of the 3D connected body (across all layers) it belongs to. Populated by + // PrintObject::infill() only when the feature is used; empty otherwise. + std::vector lslices_separated_component_bboxes; // BBS ExPolygons loverhangs; diff --git a/src/libslic3r/Model.hpp b/src/libslic3r/Model.hpp index 61c7f3f2f1..a8c6ac4d02 100644 --- a/src/libslic3r/Model.hpp +++ b/src/libslic3r/Model.hpp @@ -980,6 +980,13 @@ public: // Extruder ID is only valid for FFF. Returns -1 for SLA or if the extruder ID is not applicable (support volumes). int extruder_id() const; + //Orca: cache clearing procedure to ensure that the shape is positioned accurately when manipulating it + void clear_cache() { + m_cached_trans_matrix = Transform3d::Identity().inverse(); // get unvelivable matrix + m_convex_hull_2d.clear(); + m_cached_2d_polygon.clear(); + }; + bool is_splittable() const; // BBS @@ -1026,34 +1033,34 @@ public: static std::string type_to_string(const ModelVolumeType t); const Geometry::Transformation& get_transformation() const { return m_transformation; } - void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; } - void set_transformation(const Transform3d& trafo) { m_transformation.set_matrix(trafo); } + void set_transformation(const Geometry::Transformation& transformation) { clear_cache(); m_transformation = transformation; } + void set_transformation(const Transform3d& trafo) { clear_cache(); m_transformation.set_matrix(trafo); } Vec3d get_offset() const { return m_transformation.get_offset(); } double get_offset(Axis axis) const { return m_transformation.get_offset(axis); } - void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); } - void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); } + void set_offset(const Vec3d& offset) { clear_cache(); m_transformation.set_offset(offset); } + void set_offset(Axis axis, double offset) { clear_cache(); m_transformation.set_offset(axis, offset); } Vec3d get_rotation() const { return m_transformation.get_rotation(); } double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); } - void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); } - void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); } + void set_rotation(const Vec3d& rotation) { clear_cache(); m_transformation.set_rotation(rotation); } + void set_rotation(Axis axis, double rotation) { clear_cache(); m_transformation.set_rotation(axis, rotation); } Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); } double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); } - void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); } - void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); } + void set_scaling_factor(const Vec3d& scaling_factor) { clear_cache(); m_transformation.set_scaling_factor(scaling_factor); } + void set_scaling_factor(Axis axis, double scaling_factor) {clear_cache(); m_transformation.set_scaling_factor(axis, scaling_factor); } Vec3d get_mirror() const { return m_transformation.get_mirror(); } double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); } bool is_left_handed() const { return m_transformation.is_left_handed(); } - void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); } - void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); } + void set_mirror(const Vec3d& mirror) { clear_cache(); m_transformation.set_mirror(mirror); } + void set_mirror(Axis axis, double mirror) { clear_cache(); m_transformation.set_mirror(axis, mirror); } void convert_from_imperial_units(); void convert_from_meters(); diff --git a/src/libslic3r/MultiNozzleUtils.cpp b/src/libslic3r/MultiNozzleUtils.cpp new file mode 100644 index 0000000000..d5ce550536 --- /dev/null +++ b/src/libslic3r/MultiNozzleUtils.cpp @@ -0,0 +1,970 @@ +#include "MultiNozzleUtils.hpp" +#include "Utils.hpp" +#include "ProjectTask.hpp" // Slic3r::FilamentInfo (StaticNozzleGroupResult / load_nozzle_infos_with_compatibility) +#include +#include +#include +#include +#include +#include + +// Multi-nozzle support. + +namespace Slic3r { namespace MultiNozzleUtils { +// ==================== tool function implementations ==================== +std::vector build_nozzle_list(std::vector nozzle_groups) +{ + std::vector ret; + std::sort(nozzle_groups.begin(), nozzle_groups.end()); + int nozzle_id = 0; + for (auto& group : nozzle_groups) { + for (int i = 0; i < group.nozzle_count; ++i) { + NozzleInfo tmp; + tmp.diameter = group.diameter; + tmp.extruder_id = group.extruder_id; + tmp.volume_type = group.volume_type; + tmp.group_id = nozzle_id++; + ret.emplace_back(std::move(tmp)); + } + } + return ret; +} + +std::vector build_nozzle_list(double diameter, const std::vector& filament_nozzle_map, const std::vector& filament_volume_map, const std::vector& filament_map) +{ + std::string diameter_str = format_diameter_to_str(diameter); + std::map> nozzle_to_filaments; + for(size_t idx = 0; idx < filament_nozzle_map.size(); ++idx){ + int nozzle_id = filament_nozzle_map[idx]; + nozzle_to_filaments[nozzle_id].emplace_back(static_cast(idx)); + } + std::vector ret; + for(auto& elem : nozzle_to_filaments){ + int nozzle_id = elem.first; + auto& filaments = elem.second; + NozzleInfo info; + info.diameter = diameter_str; + info.group_id = nozzle_id; + info.extruder_id = filament_map[filaments.front()]; + info.volume_type = NozzleVolumeType(filament_volume_map[filaments.front()]); + ret.emplace_back(std::move(info)); + } + return ret; +} + +void normalize_nozzle_map_per_layer(std::vector> &layer_filament_nozzle_maps, + const std::vector> &layer_filaments) +{ + if (layer_filament_nozzle_maps.empty()) + return; + + const int total_layers = static_cast(layer_filament_nozzle_maps.size()); + int filament_count = 0; + for (const auto &layer_map : layer_filament_nozzle_maps) + filament_count = std::max(filament_count, static_cast(layer_map.size())); + + auto layer_uses_filament = [](const std::vector &filaments, int filament_id) { + return std::find(filaments.begin(), filaments.end(), static_cast(filament_id)) != filaments.end(); + }; + + std::vector last_used_nozzle(filament_count, -1); + std::unordered_map first_used_nozzle; + std::unordered_map first_used_layer; + + // Forward pass: layers that extrude a filament define its nozzle; layers that don't inherit + // the nozzle it last used (carry-forward), remembering the first-ever nozzle for the back-fill. + for (int layer_id = 0; layer_id < total_layers; ++layer_id) { + auto &layer_map = layer_filament_nozzle_maps[layer_id]; + const auto &used = layer_id < static_cast(layer_filaments.size()) ? layer_filaments[layer_id] : std::vector(); + + for (int filament_id = 0; filament_id < static_cast(layer_map.size()); ++filament_id) { + if (layer_uses_filament(used, filament_id)) { + last_used_nozzle[filament_id] = layer_map[filament_id]; + if (first_used_nozzle.count(filament_id) == 0) { + first_used_nozzle[filament_id] = layer_map[filament_id]; + first_used_layer[filament_id] = layer_id; + } + } else if (last_used_nozzle[filament_id] >= 0) { + layer_map[filament_id] = last_used_nozzle[filament_id]; + } + } + } + + // Back-fill pass: layers before a filament's first use inherit the first nozzle it ever uses. + for (int layer_id = 0; layer_id < total_layers; ++layer_id) { + auto &layer_map = layer_filament_nozzle_maps[layer_id]; + for (int filament_id = 0; filament_id < static_cast(layer_map.size()); ++filament_id) { + if (first_used_layer.count(filament_id) != 0 && layer_id < first_used_layer[filament_id]) + layer_map[filament_id] = first_used_nozzle[filament_id]; + } + } +} + +// ==================== LayeredNozzleGroupResult ==================== +static bool has_filament_mapped_to_multiple_nozzles(const std::vector> &layer_filament_nozzle_maps, + const std::vector &used_filaments) +{ + if (layer_filament_nozzle_maps.empty() || used_filaments.empty()) + return false; + + for (auto filament_id_u : used_filaments) { + int filament_id = static_cast(filament_id_u); + std::set nozzle_ids; + + for (size_t layer_id = 0; layer_id < layer_filament_nozzle_maps.size(); ++layer_id) { + const auto &map = layer_filament_nozzle_maps[layer_id]; + if (filament_id < 0 || filament_id >= static_cast(map.size())) + continue; + + int nozzle_id = map[filament_id]; + if (nozzle_id < 0) + continue; + + nozzle_ids.insert(nozzle_id); + if (nozzle_ids.size() > 1) + return true; + } + } + + return false; +} + +std::optional LayeredNozzleGroupResult::create( + const std::vector& filament_nozzle_map, + const std::vector& nozzle_list, + const std::vector& used_filaments) +{ + if (filament_nozzle_map.empty() || nozzle_list.empty()) { + return std::nullopt; + } + + LayeredNozzleGroupResult result(false); + result._default_filament_nozzle_map = filament_nozzle_map; + result._nozzle_list = nozzle_list; + result._used_filaments = used_filaments; + + return result; +} + +std::optional LayeredNozzleGroupResult::create( + const std::vector>& layer_filament_nozzle_maps, + const std::vector& nozzle_list, + const std::vector& used_filaments, + const std::vector>& layer_filament_sequences) +{ + if (layer_filament_nozzle_maps.empty() || nozzle_list.empty()) { + return std::nullopt; + } + + bool support_dynamic_nozzle_map = has_filament_mapped_to_multiple_nozzles(layer_filament_nozzle_maps, used_filaments); + LayeredNozzleGroupResult result(support_dynamic_nozzle_map); + result._layer_filament_nozzle_maps = layer_filament_nozzle_maps; + result._layer_filament_sequences = layer_filament_sequences; + result._nozzle_list = nozzle_list; + result._used_filaments = used_filaments; + + if (!layer_filament_nozzle_maps.empty()) { + result._default_filament_nozzle_map = layer_filament_nozzle_maps[0]; + } + + return result; +} + +std::optional LayeredNozzleGroupResult::create( + const std::vector& used_filaments, + const std::vector& filament_map, + const std::vector& filament_volume_map, + const std::vector& filament_nozzle_map, + const std::vector> &nozzle_count, + float diameter) +{ + std::vector nozzle_groups; + for (size_t extruder_id = 0; extruder_id < nozzle_count.size(); ++extruder_id) { + for (auto elem : nozzle_count[extruder_id]) { + NozzleGroupInfo group_info; + group_info.diameter = format_diameter_to_str(diameter); + group_info.volume_type = elem.first; + group_info.nozzle_count = elem.second; + group_info.extruder_id = static_cast(extruder_id); + nozzle_groups.emplace_back(group_info); + } + } + + auto nozzle_list = build_nozzle_list(nozzle_groups); + std::vector used_nozzle(nozzle_list.size(), false); + std::map input_nozzle_id_to_output; + std::vector output_nozzle_map(filament_nozzle_map.size(), 0); + + for (auto filament_idx : used_filaments) { + NozzleVolumeType req_type = NozzleVolumeType(filament_volume_map[filament_idx]); + int req_extruder = filament_map[filament_idx]; + int input_nozzle_idx = filament_nozzle_map[filament_idx]; + + if (input_nozzle_id_to_output.find(input_nozzle_idx) != input_nozzle_id_to_output.end()) { + output_nozzle_map[filament_idx] = input_nozzle_id_to_output[input_nozzle_idx]; + continue; + } + + int output_nozzle_idx = -1; + for (size_t nozzle_idx = 0; nozzle_idx < nozzle_list.size(); ++nozzle_idx) { + if (used_nozzle[nozzle_idx]) continue; + + auto &nozzle_info = nozzle_list[nozzle_idx]; + if (!(nozzle_info.extruder_id == req_extruder && nozzle_info.volume_type == req_type)) continue; + + output_nozzle_idx = static_cast(nozzle_idx); + input_nozzle_id_to_output[input_nozzle_idx] = output_nozzle_idx; + used_nozzle[nozzle_idx] = true; + break; + } + + if (output_nozzle_idx == -1) { return std::nullopt; } + output_nozzle_map[filament_idx] = output_nozzle_idx; + } + + return create(output_nozzle_map, nozzle_list, used_filaments); +} + +bool LayeredNozzleGroupResult::are_filaments_same_extruder(int filament_id1, int filament_id2, int layer_id) const +{ + std::optional nozzle_info1 = get_nozzle_for_filament(filament_id1, layer_id); + std::optional nozzle_info2 = get_nozzle_for_filament(filament_id2, layer_id); + + if (!nozzle_info1 || !nozzle_info2) return false; + + return nozzle_info1->extruder_id == nozzle_info2->extruder_id; +} + +bool LayeredNozzleGroupResult::are_filaments_same_nozzle(int filament_id1, int filament_id2, int layer_id) const +{ + std::optional nozzle_info1 = get_nozzle_for_filament(filament_id1, layer_id); + std::optional nozzle_info2 = get_nozzle_for_filament(filament_id2, layer_id); + if (!nozzle_info1 || !nozzle_info2) return false; + + return nozzle_info1->group_id == nozzle_info2->group_id; +} + +int LayeredNozzleGroupResult::get_extruder_count() const +{ + std::set extruder_ids; + for (const auto &nozzle : _nozzle_list) { extruder_ids.insert(nozzle.extruder_id); } + return static_cast(extruder_ids.size()); +} + +std::vector LayeredNozzleGroupResult::get_used_nozzles_in_extruder(int target_extruder_id) const +{ + return get_used_nozzles_in_extruder(target_extruder_id, -1); +} + +std::vector LayeredNozzleGroupResult::get_used_nozzles_in_extruder(int target_extruder_id, int layer_id) const +{ + std::set nozzle_ids; + std::vector result; + + std::vector target_filaments = get_used_filaments(layer_id); + + for (unsigned int filament_id : target_filaments) { + if (layer_id != -1) { + auto nozzle_opt = get_nozzle_for_filament(static_cast(filament_id), layer_id); + if (nozzle_opt) { + if (target_extruder_id == -1 || nozzle_opt->extruder_id == target_extruder_id) { nozzle_ids.insert(nozzle_opt->group_id); } + } + } else { + auto nozzles = get_nozzles_for_filament(static_cast(filament_id)); + for (const auto &nozzle : nozzles) { + if (target_extruder_id == -1 || nozzle.extruder_id == target_extruder_id) { nozzle_ids.insert(nozzle.group_id); } + } + } + } + for (int nozzle_id : nozzle_ids) { + if (nozzle_id >= 0 && nozzle_id < static_cast(_nozzle_list.size())) { result.push_back(_nozzle_list[nozzle_id]); } + } + return result; +} + +std::vector LayeredNozzleGroupResult::get_used_extruders() const +{ + return get_used_extruders(-1); +} + +std::vector LayeredNozzleGroupResult::get_used_extruders(int layer_id) const +{ + std::set used_extruders; + // used filaments on the given layer (or globally) + std::vector target_filaments = get_used_filaments(layer_id); + for (auto filament_id : target_filaments) { + if (layer_id != -1) { + // single-layer: nozzle used by this filament on this layer + auto nozzle_opt = get_nozzle_for_filament(static_cast(filament_id), layer_id); + if (nozzle_opt) { used_extruders.insert(nozzle_opt->extruder_id); } + } else { + // global: every nozzle this filament uses across all layers + auto nozzles = get_nozzles_for_filament(static_cast(filament_id)); + for (const auto &nozzle : nozzles) { used_extruders.insert(nozzle.extruder_id); } + } + } + return std::vector(used_extruders.begin(), used_extruders.end()); +} + +std::vector LayeredNozzleGroupResult::get_extruder_map(bool zero_based, int layer_id) const +{ + const std::vector &filament_nozzle_map = get_layer_filament_nozzle_map(layer_id); + std::vector extruder_map(filament_nozzle_map.size()); + for (size_t idx = 0; idx < filament_nozzle_map.size(); ++idx) { + int nozzle_id = filament_nozzle_map[idx]; + if (nozzle_id >= 0 && nozzle_id < static_cast(_nozzle_list.size())) { + extruder_map[idx] = _nozzle_list[nozzle_id].extruder_id; + } else { + extruder_map[idx] = -1; + } + } + + if (zero_based) return extruder_map; + + auto new_filament_map = extruder_map; + std::transform(new_filament_map.begin(), new_filament_map.end(), new_filament_map.begin(), [](int val) { return val + 1; }); + return new_filament_map; +} + +std::vector LayeredNozzleGroupResult::get_nozzle_map(int layer_id) const +{ + const std::vector &filament_nozzle_map = get_layer_filament_nozzle_map(layer_id); + std::vector nozzle_map(filament_nozzle_map.size()); + for (size_t idx = 0; idx < filament_nozzle_map.size(); ++idx) { + int nozzle_id = filament_nozzle_map[idx]; + if (nozzle_id >= 0 && nozzle_id < static_cast(_nozzle_list.size())) { + nozzle_map[idx] = _nozzle_list[nozzle_id].group_id; + } else { + nozzle_map[idx] = -1; + } + } + return nozzle_map; +} + +std::vector LayeredNozzleGroupResult::get_volume_map(int layer_id) const +{ + const std::vector &filament_nozzle_map = get_layer_filament_nozzle_map(layer_id); + std::vector volume_map(filament_nozzle_map.size()); + for (size_t idx = 0; idx < filament_nozzle_map.size(); ++idx) { + int nozzle_id = filament_nozzle_map[idx]; + if (nozzle_id >= 0 && nozzle_id < static_cast(_nozzle_list.size())) { + volume_map[idx] = _nozzle_list[nozzle_id].volume_type; + } else { + volume_map[idx] = -1; + } + } + return volume_map; +} + +std::vector LayeredNozzleGroupResult::get_used_filaments(int layer_id) const +{ + if (layer_id < 0) { return _used_filaments; } + if (layer_id >= static_cast(_layer_filament_nozzle_maps.size())) { return _used_filaments; } + + if (!_layer_filament_sequences.empty() && layer_id < static_cast(_layer_filament_sequences.size())) { + return _layer_filament_sequences[layer_id]; + } + return {}; +} + +std::optional LayeredNozzleGroupResult::get_nozzle_for_filament(int filament_id, int layer_id) const +{ + const std::vector &filament_nozzle_map = get_layer_filament_nozzle_map(layer_id); + + if (filament_id < 0 || filament_id >= static_cast(filament_nozzle_map.size())) { return std::nullopt; } + + int nozzle_id = filament_nozzle_map[filament_id]; + return get_nozzle_from_id(nozzle_id); +} + +std::vector LayeredNozzleGroupResult::get_nozzles_for_filament(int filament_id) const +{ + std::set nozzle_ids; + + if (!support_dynamic_nozzle_map) { + if (filament_id >= 0 && filament_id < static_cast(_default_filament_nozzle_map.size())) { + nozzle_ids.insert(_default_filament_nozzle_map[filament_id]); + } + } else { + int start_layer = 0; + int end_layer = static_cast(_layer_filament_nozzle_maps.size()); + + for (int i = start_layer; i < end_layer; ++i) { + const auto &map = _layer_filament_nozzle_maps[i]; + if (filament_id >= 0 && filament_id < static_cast(map.size())) { + nozzle_ids.insert(map[filament_id]); + } + } + } + + std::vector result; + for (int id : nozzle_ids) { + if (id >= 0 && id < static_cast(_nozzle_list.size())) { result.push_back(_nozzle_list[id]); } + } + return result; +} + +std::optional LayeredNozzleGroupResult::get_first_nozzle_for_filament(int filament_id) const +{ + if (filament_id < 0) return std::nullopt; + + if (!support_dynamic_nozzle_map) { + if (filament_id >= static_cast(_default_filament_nozzle_map.size())) return std::nullopt; + return get_nozzle_from_id(_default_filament_nozzle_map[filament_id]); + } + + for (size_t layer = 0; layer < _layer_filament_nozzle_maps.size(); ++layer) { + auto layer_used_filaments = get_used_filaments(layer); + if (std::find(layer_used_filaments.begin(), layer_used_filaments.end(), static_cast(filament_id)) == layer_used_filaments.end()){ + continue; + } + const auto &map = _layer_filament_nozzle_maps[layer]; + if (filament_id >= 0 && filament_id < static_cast(map.size())) { + int nozzle_id = map[filament_id]; + auto nozzle = get_nozzle_from_id(nozzle_id); + if (nozzle) return nozzle; + } + } + + return std::nullopt; +} + +std::optional LayeredNozzleGroupResult::get_nozzle_from_id(int nozzle_id) const +{ + if (nozzle_id < 0 || nozzle_id >= static_cast(_nozzle_list.size())) { return std::nullopt; } + return _nozzle_list[nozzle_id]; +} + +int LayeredNozzleGroupResult::get_extruder_id(int filament_id, int layer_id) const +{ + auto nozzle_info = get_nozzle_for_filament(filament_id, layer_id); + return nozzle_info ? nozzle_info->extruder_id : -1; +} + +int LayeredNozzleGroupResult::get_nozzle_id(int filament_id, int layer_id) const +{ + auto nozzle_info = get_nozzle_for_filament(filament_id, layer_id); + return nozzle_info ? nozzle_info->group_id : -1; +} + +const std::vector &LayeredNozzleGroupResult::get_layer_filament_nozzle_map(int layer_id) const +{ + if (layer_id >= 0 && layer_id < static_cast(_layer_filament_nozzle_maps.size())) { return _layer_filament_nozzle_maps[layer_id]; } + return _default_filament_nozzle_map; +} + +// ==================== filament-change-time model ==================== +FilamentChangeSimResult simulate_filament_change_time( + const std::vector& logical_filaments, + const std::vector& nozzle_list, + const std::vector& filament_change_seq, + const std::vector& nozzle_change_seq, + const std::vector& group_of_filament, + const FilamentChangeTimeParams& time_params, + const std::vector& ams_preload_enabled, + bool calc_sliced_time) +{ + FilamentChangeSimResult result; + if (logical_filaments.empty() || nozzle_list.empty() || filament_change_seq.empty() || nozzle_change_seq.empty()) + return result; + + // Re-map the parameter semantics: + // standard = AMS -> selector -> extruder (full path), selector = selector -> extruder (short path) + // so AMS -> selector = standard - selector + const float load_ams_to_selector = time_params.standard_load_time - time_params.selector_load_time; + const float unload_ams_to_selector = time_params.standard_unload_time - time_params.selector_unload_time; + const float load_selector_to_ext = time_params.selector_load_time; + const float unload_ext_to_selector = time_params.selector_unload_time; + + // nozzle_id -> extruder_id + std::unordered_map nozzle_to_extruder; + nozzle_to_extruder.reserve(nozzle_list.size()); + for (const auto& nozzle : nozzle_list) + nozzle_to_extruder[nozzle.group_id] = nozzle.extruder_id; + + // filament_id -> AMS group + std::unordered_map filament_to_group; + filament_to_group.reserve(logical_filaments.size()); + for (size_t i = 0; i < logical_filaments.size(); ++i) + filament_to_group[logical_filaments[i]] = group_of_filament[i]; + + const auto get_group = [&](int filament_id) -> int { + auto it = filament_to_group.find(filament_id); + return it != filament_to_group.end() ? it->second : -1; + }; + + const auto is_preload_enabled = [&](int group_id) -> bool { + if (group_id < 0 || group_id >= static_cast(ams_preload_enabled.size())) + return false; + return ams_preload_enabled[group_id]; + }; + + // Filament location states + enum class Location { IN_AMS, IN_SELECTOR, IN_EXTRUDER }; + std::unordered_map filament_location; // filament_id -> current location + std::unordered_map filament_extruder; // filament_id -> extruder it sits in (only valid when IN_EXTRUDER) + std::unordered_map extruder_filament; // extruder_id -> currently loaded filament + // group_id -> filaments currently occupying that AMS channel (IN_SELECTOR or IN_EXTRUDER) + std::unordered_map> ams_group_occupied; + + filament_location.reserve(logical_filaments.size()); + filament_extruder.reserve(logical_filaments.size()); + + // Initial state: every filament is in the AMS, every extruder is empty + for (int f : logical_filaments) + filament_location[f] = Location::IN_AMS; + + // Slicer-estimate simulator: use NozzleStatusRecorder to track what each nozzle/extruder holds during slicing + NozzleStatusRecorder sliced_recorder; + + const size_t seq_len = std::min(filament_change_seq.size(), nozzle_change_seq.size()); + double actual_time = 0.0; + double sliced_time = 0.0; + + for (size_t i = 0; i < seq_len; ++i) { + int B = filament_change_seq[i]; + int nozzle_id = nozzle_change_seq[i]; + + auto nozzle_iter = nozzle_to_extruder.find(nozzle_id); + if (nozzle_iter == nozzle_to_extruder.end()) continue; + + int E = nozzle_iter->second; // target extruder + + // Step 0: compute the slicer-estimated time + // Slicer estimate: simulate the slicer's view (no selector awareness); + // count a load/unload when nozzle_in_extruder_change || filament_in_nozzle_change + if (calc_sliced_time) { + int old_nozzle_in_E = sliced_recorder.get_nozzle_in_extruder(E); + int old_filament_in_nozzle = sliced_recorder.get_filament_in_nozzle(nozzle_id); + int old_filament_in_ext = sliced_recorder.get_filament_in_nozzle(old_nozzle_in_E); + + bool nozzle_change = (old_nozzle_in_E != nozzle_id); + bool filament_change = (old_filament_in_nozzle != B); + + if (nozzle_change || filament_change) { + if (old_filament_in_ext != -1) + sliced_time += time_params.standard_unload_time; + sliced_time += time_params.standard_load_time; + } + sliced_recorder.set_nozzle_status(nozzle_id, B, E); + } + + // Step 1: find the filament A currently loaded in the target extruder E + int A = -1; + { + auto it = extruder_filament.find(E); + if (it != extruder_filament.end()) + A = it->second; + } + + int group_B = get_group(B); + int group_A = (A != -1) ? get_group(A) : -1; + + // Step 2: clear B's AMS-channel occupancy + auto group_it = ams_group_occupied.find(group_B); + if (group_it != ams_group_occupied.end()) { + for (int X : group_it->second) { + if (X == B) continue; + // X shares B's AMS channel, retreat it to the AMS to make way + Location loc_X = filament_location[X]; + if (loc_X == Location::IN_EXTRUDER) { + actual_time += unload_ext_to_selector + unload_ams_to_selector; + int E2 = filament_extruder[X]; + extruder_filament.erase(E2); + filament_extruder.erase(X); + } else if (loc_X == Location::IN_SELECTOR) { + actual_time += unload_ams_to_selector; + } + filament_location[X] = Location::IN_AMS; + } + group_it->second.clear(); + } + + // Step 3: A exits E (while A is still in the extruder) + // Step 3.5: pre-load B (in parallel with Step 3) + // actual time = max(Step 3, Step 3.5) + bool step3_executed = false; + float step3_time = 0.0f; + if (A != -1 && A != B && filament_location[A] == Location::IN_EXTRUDER) { + if (is_preload_enabled(group_A) && group_A != group_B) { + step3_time = unload_ext_to_selector; + filament_location[A] = Location::IN_SELECTOR; + } else { + step3_time = unload_ext_to_selector + unload_ams_to_selector; + filament_location[A] = Location::IN_AMS; + ams_group_occupied[group_A].erase(A); + } + extruder_filament.erase(E); + filament_extruder.erase(A); + step3_executed = true; + } + + float step3_5_time = 0.0f; + if (step3_executed && + filament_location[B] == Location::IN_AMS && + group_A != group_B && + is_preload_enabled(group_B)) { + step3_5_time = load_ams_to_selector; + filament_location[B] = Location::IN_SELECTOR; + ams_group_occupied[group_B].insert(B); + } + + actual_time += std::max(step3_time, step3_5_time); + + // Step 4: push B into E + // Step 6: pre-load the next filament C (in parallel with Step 4) + // actual time = max(Step 4, Step 6) + float step4_time = 0.0f; + Location loc_B = filament_location[B]; + if (loc_B == Location::IN_AMS) { + step4_time = load_ams_to_selector + load_selector_to_ext; + } else if (loc_B == Location::IN_SELECTOR) { + step4_time = load_selector_to_ext; + } + + // Step 5: update state + extruder_filament[E] = B; + filament_location[B] = Location::IN_EXTRUDER; + filament_extruder[B] = E; + ams_group_occupied[group_B].insert(B); + + float step6_time = 0.0f; + if (i + 1 < seq_len) { + int C = filament_change_seq[i + 1]; + int group_C = get_group(C); + if (filament_location[C] == Location::IN_AMS && + group_C != group_B && + is_preload_enabled(group_C) && + ams_group_occupied[group_C].empty()) { + step6_time = load_ams_to_selector; + filament_location[C] = Location::IN_SELECTOR; + ams_group_occupied[group_C].insert(C); + } + } + + actual_time += std::max(step4_time, step6_time); + } + + result.actual_time = actual_time; + result.sliced_time = sliced_time; + return result; +} + +// ==================== NozzleStatusRecorder implementation ==================== + +bool NozzleStatusRecorder::is_nozzle_empty(int nozzle_id) const +{ + auto iter = nozzle_filament_status.find(nozzle_id); + if (iter == nozzle_filament_status.end()) return true; + return false; +} + +int NozzleStatusRecorder::get_filament_in_nozzle(int nozzle_id) const +{ + auto iter = nozzle_filament_status.find(nozzle_id); + if (iter == nozzle_filament_status.end()) return -1; + return iter->second; +} + +int NozzleStatusRecorder::get_nozzle_in_extruder(int extruder_id) const +{ + auto iter = extruder_nozzle_status.find(extruder_id); + if (iter == extruder_nozzle_status.end()) return -1; + return iter->second; +} + +void NozzleStatusRecorder::set_nozzle_status(int nozzle_id, int filament_id, int extruder_id) +{ + nozzle_filament_status[nozzle_id] = filament_id; + if (extruder_id != -1) { + extruder_nozzle_status[extruder_id] = nozzle_id; + } +} + +void NozzleStatusRecorder::clear_nozzle_status(int nozzle_id) +{ + auto iter = nozzle_filament_status.find(nozzle_id); + if (iter == nozzle_filament_status.end()) return; + nozzle_filament_status.erase(iter); +} + +int LayeredNozzleGroupResult::estimate_seq_flush_weight(const std::vector>>& flush_matrix, const std::vector& filament_change_seq) const +{ + auto get_weight_from_volume = [](float volume){ + return static_cast(volume * 1.26 * 0.01); + }; + + float total_flush_volume = 0; + NozzleStatusRecorder recorder; + for(auto filament: filament_change_seq){ + auto nozzle = get_nozzle_for_filament(filament, -1); + if(!nozzle) + continue; + + int extruder_id = nozzle->extruder_id; + int nozzle_id = nozzle->group_id; + int last_filament = recorder.get_filament_in_nozzle(nozzle_id); + + if(last_filament!= -1 && last_filament != filament){ + // bounds check to avoid out-of-range access + if (extruder_id >= 0 && extruder_id < static_cast(flush_matrix.size()) && + last_filament >= 0 && last_filament < static_cast(flush_matrix[extruder_id].size()) && + filament >= 0 && filament < static_cast(flush_matrix[extruder_id][last_filament].size())) { + float flush_volume = flush_matrix[extruder_id][last_filament][filament]; + total_flush_volume += flush_volume; + } + } + recorder.set_nozzle_status(nozzle_id, filament); + } + + return get_weight_from_volume(total_flush_volume); +} + +// ==================== StaticNozzleGroupResult ==================== + +std::optional StaticNozzleGroupResult::create( + const std::vector& filaments_info, + const std::vector& nozzles_info, + const std::vector& filament_change_seq, + const std::vector& nozzle_change_seq, + bool support_dynamic_nozzle_map) +{ + if (filaments_info.empty() || nozzles_info.empty()) return std::nullopt; + + std::map nozzle_list_map; + std::map> filament_to_nozzles; + + for (auto nozzle_info : nozzles_info) + nozzle_list_map[nozzle_info.group_id] = nozzle_info; + + for (auto filament_info : filaments_info) { + auto fil_id = filament_info.id; + auto nozzles_id = filament_info.group_id; + std::set nozzles_set(nozzles_id.begin(), nozzles_id.end()); + // Backward compat with older (single-nozzle) gcode.3mf: filament has no group_id, avoid an empty map. + if (nozzles_set.empty()) { + for (const auto& nozzle_entry : nozzle_list_map) + nozzles_set.insert(nozzle_entry.first); + } + filament_to_nozzles[fil_id] = nozzles_set; + } + + StaticNozzleGroupResult result(support_dynamic_nozzle_map); + result._filament_to_nozzles = filament_to_nozzles; + result._nozzle_list_map = nozzle_list_map; + result._filament_change_seq = filament_change_seq; + result._nozzle_change_seq = nozzle_change_seq; + + return result; +} + +std::optional StaticNozzleGroupResult::get_nozzle_from_id(int nozzle_id) const +{ + auto iter = _nozzle_list_map.find(nozzle_id); + if (iter == _nozzle_list_map.end()) { return std::nullopt; } + return iter->second; +} + +int StaticNozzleGroupResult::get_extruder_count() const +{ + std::set extruder_ids; + for (const auto &elem : _nozzle_list_map) { extruder_ids.insert(elem.second.extruder_id); } + return static_cast(extruder_ids.size()); +} + +std::vector StaticNozzleGroupResult::get_used_nozzles_in_extruder(int target_extruder_id) const +{ + std::vector result; + for (const auto &elem : _nozzle_list_map) { + const auto &nozzle = elem.second; + if (target_extruder_id == -1 || nozzle.extruder_id == target_extruder_id) { + result.push_back(nozzle); + } + } + return result; +} + +std::vector StaticNozzleGroupResult::get_used_extruders() const +{ + std::set used_extruders; + for (const auto &elem : _nozzle_list_map) { used_extruders.insert(elem.second.extruder_id); } + return std::vector(used_extruders.begin(), used_extruders.end()); +} + +std::vector StaticNozzleGroupResult::get_used_filaments() const +{ + std::vector used_filaments; + used_filaments.reserve(_filament_to_nozzles.size()); + for (const auto &elem : _filament_to_nozzles) { + if (elem.first >= 0) { + used_filaments.push_back(static_cast(elem.first)); + } + } + return used_filaments; +} + +std::vector StaticNozzleGroupResult::get_nozzles_for_filament(int filament_id) const +{ + auto iter = _filament_to_nozzles.find(filament_id); + if (iter == _filament_to_nozzles.end()) { return std::vector(); } + + std::vector result; + for (int nozzle_id : iter->second) { + auto nozzle_iter = _nozzle_list_map.find(nozzle_id); + if (nozzle_iter != _nozzle_list_map.end()) { + result.push_back(nozzle_iter->second); + } + } + return result; +} + +std::optional StaticNozzleGroupResult::get_first_nozzle_for_filament(int filament_id) const +{ + if (filament_id < 0) return std::nullopt; + + if (!_filament_change_seq.empty() && _filament_change_seq.size() == _nozzle_change_seq.size()) { + for (size_t idx = 0; idx < _filament_change_seq.size(); ++idx) { + if (_filament_change_seq[idx] == filament_id) { + int nozzle_id = _nozzle_change_seq[idx]; + auto nozzle = get_nozzle_from_id(nozzle_id); + if (nozzle) return nozzle; + } + } + } + + auto iter = _filament_to_nozzles.find(filament_id); + if (iter == _filament_to_nozzles.end()) return std::nullopt; + + for (int nozzle_id : iter->second) { + auto nozzle = get_nozzle_from_id(nozzle_id); + if (nozzle) return nozzle; + } + + return std::nullopt; +} + +// ==================== serialization ==================== + +std::string NozzleInfo::serialize() const +{ + std::ostringstream oss; + oss << "id=\"" << group_id << "\" " + << "extruder_id=\"" << extruder_id + 1 << "\" " + << "nozzle_diameter=\"" << diameter << "\" " + << "volume_type=\"" << get_nozzle_volume_type_string(volume_type) << "\""; + return oss.str(); +} + +std::string NozzleGroupInfo::serialize() const +{ + std::ostringstream oss; + oss << extruder_id << "-" + << std::setprecision(2) << diameter << "-" + << get_nozzle_volume_type_string(volume_type) << "-" + << nozzle_count; + return oss.str(); +} + +std::optional NozzleGroupInfo::deserialize(const std::string &str) +{ + std::istringstream iss(str); + std::string token; + std::vector tokens; + + while (std::getline(iss, token, '-')) { tokens.push_back(token); } + + if (tokens.size() != 4) { return std::nullopt; } + + try { + int extruder_id = std::stoi(tokens[0]); + std::string diameter = tokens[1]; + NozzleVolumeType volume_type = NozzleVolumeType(ConfigOptionEnum::get_enum_values().at(tokens[2])); + int nozzle_count = std::stoi(tokens[3]); + + return NozzleGroupInfo(diameter, volume_type, extruder_id, nozzle_count); + } catch (const std::exception &) { + return std::nullopt; + } +} + +std::vector load_nozzle_infos_with_compatibility( + const std::vector& nozzle_infos, + const std::vector& filament_infos, + const std::vector& filament_map, + const std::vector& extruder_volume_types, + const std::vector& nozzle_diameter +) +{ + bool has_nozzle_info = !nozzle_infos.empty(); + bool has_valid_filament_info = !filament_infos.empty() && std::all_of(filament_infos.begin(), filament_infos.end(), [](const FilamentInfo& info){ + return info.group_id.size() == 1; + }); + + if(!has_nozzle_info && !has_valid_filament_info){ + BOOST_LOG_TRIVIAL(warning)<<__FUNCTION__ << ": building nozzle list from filament map and volume types"; + + // Backward compatibility for older gcode.3mf: + // - nozzle_diameter is always present and its size defines extruder count. + // - filament_map may be missing; treat it as [0, 0, ...] for each extruder. + // - extruder_volume_types may be missing; treat it as all Standard. + const size_t extruder_count = nozzle_diameter.size(); + + std::vector volume_types_fixed = extruder_volume_types; + volume_types_fixed.resize(extruder_count, NozzleVolumeType::nvtStandard); + + std::vector result; + result.reserve(extruder_count); + for (size_t extruder_id = 0; extruder_id < extruder_count; ++extruder_id) { + NozzleInfo info; + info.diameter = format_diameter_to_str(nozzle_diameter[extruder_id]); + info.group_id = static_cast(extruder_id); + info.extruder_id = static_cast(extruder_id); + info.volume_type = volume_types_fixed[extruder_id]; + result.emplace_back(std::move(info)); + } + return result; + } + + if(!has_nozzle_info){ + BOOST_LOG_TRIVIAL(info)<<__FUNCTION__ << ": building nozzle list from filament info"; + std::map nozzle_map; // group_id -> NozzleInfo + for(auto& filament : filament_infos){ + int group_id = filament.group_id.front(); + if(group_id < 0 || nozzle_map.find(group_id) != nozzle_map.end()){ + continue; + } + + auto volume_type_str_to_enum = ConfigOptionEnum::get_enum_values(); + + NozzleInfo info; + info.diameter = format_diameter_to_str(filament.nozzle_diameter); + info.group_id = group_id; + // Orca: bounds-check filament_map[filament.id] so a malformed 3mf (filament id + // beyond the map) degrades to extruder 0 instead of dereferencing out of range. + info.extruder_id = (filament.id >= 0 && filament.id < static_cast(filament_map.size())) + ? filament_map[filament.id] - 1 + : 0; // to 0-based + + if (volume_type_str_to_enum.count(filament.nozzle_volume_type)) + info.volume_type = NozzleVolumeType(volume_type_str_to_enum.at(filament.nozzle_volume_type)); + else { + info.volume_type = NozzleVolumeType::nvtStandard; + } + + nozzle_map[group_id] = std::move(info); + } + + std::vector ret; + for(auto& elem : nozzle_map){ + ret.emplace_back(elem.second); + } + return ret; + } + + auto result = nozzle_infos; + std::sort(result.begin(), result.end()); + BOOST_LOG_TRIVIAL(info)<<__FUNCTION__ << ": using new 3mf format with " << result.size() << " nozzle infos."; + return result; +} + +}} // namespace Slic3r::MultiNozzleUtils diff --git a/src/libslic3r/MultiNozzleUtils.hpp b/src/libslic3r/MultiNozzleUtils.hpp new file mode 100644 index 0000000000..5ae56e497d --- /dev/null +++ b/src/libslic3r/MultiNozzleUtils.hpp @@ -0,0 +1,296 @@ +#ifndef MULTI_NOZZLE_UTILS_HPP +#define MULTI_NOZZLE_UTILS_HPP + +#include +#include +#include +#include +#include +#include "PrintConfig.hpp" + +// Multi-nozzle support types. +// Declares the filament-grouping result types the slicing pipeline needs, plus the analytic +// filament-change-time model (FilamentChangeTimeParams, NozzleStatusRecorder, +// FilamentChangeSimResult, simulate_filament_change_time) — self-contained analytic code that +// never touches the time estimator; its first consumer is the filament_group golden harness. +// The gcode.3mf serialization surface lives here too: NozzleInfo/NozzleGroupInfo +// serialize+deserialize, the device-side StaticNozzleGroupResult, +// load_nozzle_infos_with_compatibility (the backward-compat 3mf reader) and +// LayeredNozzleGroupResult::estimate_seq_flush_weight. The change-time-tuning helpers +// calc_filament_change_gap_for_assignment / find_optimal_physical_assignment (used only by the +// AMS pre-load optimizer, a later feature) are not implemented here. + +namespace Slic3r { +struct FilamentInfo; // Slic3r::FilamentInfo (ProjectTask.hpp) — consumed by StaticNozzleGroupResult / the 3mf reader +namespace MultiNozzleUtils { + +// Information about a single logical nozzle. +struct NozzleInfo +{ + std::string diameter; + NozzleVolumeType volume_type; + int extruder_id{-1}; // logical extruder id + int group_id{-1}; // logical nozzle id + + std::string serialize() const; + + bool operator<(const NozzleInfo& other) const { + if(group_id != other.group_id) return group_id < other.group_id; + if(extruder_id != other.extruder_id) return extruder_id < other.extruder_id; + if(volume_type != other.volume_type) return volume_type < other.volume_type; + return diameter < other.diameter; + } +}; + +// A group of identical nozzles on one extruder (diameter + volume type + count). +struct NozzleGroupInfo +{ + std::string diameter; + NozzleVolumeType volume_type; + int extruder_id; + int nozzle_count; + + NozzleGroupInfo() = default; + + NozzleGroupInfo(const std::string& nozzle_diameter_, const NozzleVolumeType volume_type_, const int extruder_id_, const int nozzle_count_) + : diameter(nozzle_diameter_), volume_type(volume_type_), extruder_id(extruder_id_), nozzle_count(nozzle_count_) + {} + + inline bool operator<(const NozzleGroupInfo &rhs) const + { + if (extruder_id != rhs.extruder_id) return extruder_id < rhs.extruder_id; + if (diameter != rhs.diameter) return diameter < rhs.diameter; + if (volume_type != rhs.volume_type) return volume_type < rhs.volume_type; + return nozzle_count < rhs.nozzle_count; + } + + bool is_same_type(const NozzleGroupInfo &rhs) const + { + return diameter == rhs.diameter && volume_type == rhs.volume_type && extruder_id == rhs.extruder_id; + } + + inline bool operator==(const NozzleGroupInfo &rhs) const + { + return diameter == rhs.diameter && volume_type == rhs.volume_type && extruder_id == rhs.extruder_id && nozzle_count == rhs.nozzle_count; + } + + std::string serialize() const; + static std::optional deserialize(const std::string& str); +}; + +// Load/unload time constants used by the filament-change-time model. +// Consumed by simulate_filament_change_time() below and carried by the grouping-context +// substrate (FilamentGroupContext::SpeedInfo). +struct FilamentChangeTimeParams +{ + float selector_load_time{0.0f}; + float selector_unload_time{0.0f}; + float standard_load_time{0.0f}; + float standard_unload_time{0.0f}; +}; + +/** + * @brief Abstract base for a nozzle-grouping result. + */ +class NozzleGroupResultBase +{ +protected: + bool support_dynamic_nozzle_map{false}; // whether dynamic (selector) mapping is used + +public: + NozzleGroupResultBase(bool support_dynamic_map = false) : support_dynamic_nozzle_map(support_dynamic_map) {} + virtual ~NozzleGroupResultBase() = default; + + virtual std::optional get_nozzle_from_id(int nozzle_id) const = 0; + virtual std::optional get_first_nozzle_for_filament(int filament_id) const = 0; // logical nozzle a filament first uses + + virtual std::vector get_nozzles_for_filament(int filament_id) const = 0; // every nozzle a filament may use (across all layers) + + bool is_support_dynamic_nozzle_map() const { return support_dynamic_nozzle_map; } + + virtual int get_extruder_count() const = 0; + + virtual std::vector get_used_nozzles_in_extruder(int extruder_id =-1) const = 0; + virtual std::vector get_used_extruders() const = 0; + virtual std::vector get_used_filaments() const = 0; +}; + +/** + * @brief Layer-aware nozzle-grouping result. + * Used by the back-end slicing code; supports per-layer nozzle mapping. + */ +class LayeredNozzleGroupResult : public NozzleGroupResultBase +{ +private: + std::vector> _layer_filament_nozzle_maps; // per-layer filament -> nozzle map + std::vector> _layer_filament_sequences; // per-layer filament print order + std::vector _default_filament_nozzle_map; // global filament -> nozzle map + std::vector _used_filaments; // all used filament indices + std::vector _nozzle_list; // global nozzle list + +public: + LayeredNozzleGroupResult(bool support_dynamic_map = false) : NozzleGroupResultBase(support_dynamic_map) {} + + // No selector: one global filament->nozzle map. + static std::optional create( + const std::vector& filament_nozzle_map, + const std::vector& nozzle_list, + const std::vector& used_filaments); + + // Selector: built from per-layer maps (each layer may differ). + static std::optional create( + const std::vector>& layer_filament_nozzle_maps, + const std::vector& nozzle_list, + const std::vector& used_filaments, + const std::vector>& layer_filament_sequences); + + // Multi-nozzle without selector: resolve each requested logical nozzle to a physical nozzle. + static std::optional create( + const std::vector& used_filaments, + const std::vector& filament_map, + const std::vector& filament_volume_map, + const std::vector& filament_nozzle_map, + const std::vector>& nozzle_count, + float diameter); + + bool are_filaments_same_extruder(int filament_id1, int filament_id2, int layer_id = -1) const; + bool are_filaments_same_nozzle(int filament_id1, int filament_id2, int layer_id = -1) const; + int get_extruder_count() const override; + + std::vector get_used_nozzles_in_extruder(int target_extruder_id = -1) const override; + std::vector get_used_nozzles_in_extruder(int target_extruder_id, int layer_id) const; // layer_id=-1 uses default map + std::vector get_used_extruders() const override; + std::vector get_used_extruders(int layer_id) const; // layer_id=-1 returns global extruders + + std::vector get_extruder_map(bool zero_based = true, int layer_id = -1) const; + std::vector get_nozzle_map(int layer_id = -1) const; + std::vector get_volume_map(int layer_id = -1) const; + + std::vector get_used_filaments() const override { return _used_filaments; } + std::vector get_used_filaments(int layer_id) const; + + std::optional get_nozzle_for_filament(int filament_id, int layer_id = -1) const; + std::vector get_nozzles_for_filament(int filament_id) const override; + + std::optional get_nozzle_from_id(int nozzle_id) const override; + std::optional get_first_nozzle_for_filament(int filament_id) const override; + int get_extruder_id(int filament_id, int layer_id = -1) const; + int get_nozzle_id(int filament_id, int layer_id = -1) const; + + size_t get_layer_count() const { return _layer_filament_nozzle_maps.size(); } + const std::vector& get_layer_filament_nozzle_map(int layer_id) const; + const std::vector> &get_layer_filament_nozzle_maps() const { return _layer_filament_nozzle_maps; } + const std::vector>& get_layer_filament_sequences() const { return _layer_filament_sequences; } + + // Estimate the flush weight of a filament-change sequence given the per-extruder flush matrix + // (extruder -> from-filament -> to-filament). + int estimate_seq_flush_weight(const std::vector>>& flush_matrix, const std::vector& filament_change_seq) const; +}; + +/** + * @brief Layer-less nozzle-grouping result for the device side (static nozzle mapping only). + * Reconstructed from a loaded gcode.3mf together with the filament/nozzle change sequences. + */ +class StaticNozzleGroupResult : public NozzleGroupResultBase +{ +private: + std::map> _filament_to_nozzles; // every nozzle a filament may map to + std::map _nozzle_list_map; // used nozzles, keyed by logical nozzle id + std::vector _filament_change_seq; // filament sequence used to resolve first-use + std::vector _nozzle_change_seq; // logical-nozzle sequence paired with the filament sequence + +public: + StaticNozzleGroupResult(bool support_dynamic_map) : NozzleGroupResultBase(support_dynamic_map) {} + // Build from a loaded 3mf, with the filament/nozzle change sequences. + static std::optional create( + const std::vector& filaments_info, + const std::vector& nozzles_info, + const std::vector& filament_change_seq, + const std::vector& nozzle_change_seq, + bool support_dynamic_map); + + int get_extruder_count() const override; + std::vector get_used_nozzles_in_extruder(int extruder_id = -1) const override; + std::vector get_used_extruders() const override; + std::vector get_used_filaments() const override; + + std::optional get_nozzle_from_id(int nozzle_id) const override; + + std::vector get_nozzles_for_filament(int filament_id) const override; + std::optional get_first_nozzle_for_filament(int filament_id) const override; +}; + +// Tracks, during the filament-change simulation, which filament sits in each physical nozzle +// and which nozzle each extruder currently carries. +class NozzleStatusRecorder +{ +private: + std::unordered_map nozzle_filament_status; // Track filament in each nozzle + std::unordered_map extruder_nozzle_status; // Track nozzle for each extruder + int current_extruder_id_ = -1; // Track current extruder id + +public: + NozzleStatusRecorder() = default; + bool is_nozzle_empty(int nozzle_id) const; + int get_filament_in_nozzle(int nozzle_id) const; + int get_nozzle_in_extruder(int extruder_id) const; + int get_current_extruder_id() const { return current_extruder_id_; } + + void clear_nozzle_status(int nozzle_id); + void set_current_extruder_id(int extruder_id) { current_extruder_id_ = extruder_id; } + + // Update the status of a nozzle with new filament and extruder information + void set_nozzle_status(int nozzle_id, int filament_id, int extruder_id = -1); + + // key: nozzle id, value: filament id (-1 = the nozzle carries no filament) + const std::unordered_map& get_nozzle_filament_map() const { return nozzle_filament_status; } + // key: extruder id, value: nozzle id (-1 = the extruder carries no nozzle) + const std::unordered_map& get_extruder_nozzle_map() const { return extruder_nozzle_status; } +}; + +struct FilamentChangeSimResult { + double actual_time = 0.0; + double sliced_time = 0.0; +}; + +// Analytic filament-change-time model. Given the used filaments, the nozzle +// list, the filament/nozzle change sequences, each filament's AMS group and the load/unload time +// constants, it simulates AMS->selector->extruder transport (with optional AMS pre-load overlap) +// and returns the actual print time plus the slicer-estimated time. Self-contained: it never +// touches the g-code time estimator. +FilamentChangeSimResult simulate_filament_change_time( + const std::vector& logical_filaments, + const std::vector& nozzle_list, + const std::vector& filament_change_seq, + const std::vector& nozzle_change_seq, + const std::vector& group_of_filament, + const FilamentChangeTimeParams& time_params, + const std::vector& ams_preload_enabled = {}, + bool calc_sliced_time = false); + +// ==================== tool functions ==================== +// Make each filament's per-layer nozzle assignment gap-free: layers where a filament is not +// extruded inherit the nozzle it last used (forward carry); layers before its first use inherit +// the first nozzle it ever uses (back-fill). Entries on layers where the filament is actually +// used stay untouched. Needed for stitched sequential maps, where consumers indexing with an +// object-local layer id must resolve the same nozzle as global-id consumers except across a +// genuine mid-print reassignment. +void normalize_nozzle_map_per_layer(std::vector>& layer_filament_nozzle_maps, + const std::vector>& layer_filaments); +std::vector build_nozzle_list(std::vector info); +std::vector build_nozzle_list(double diameter, const std::vector& filament_nozzle_map, + const std::vector& filament_volume_map, const std::vector& filament_map); +// Load nozzle infos from a gcode.3mf, handling backward compatibility with older 3mf that did not +// record standalone tags: falls back to the per-filament group_id/diameter/volume_type, and +// (for the oldest single-nozzle 3mf) to the filament_map + extruder volume types + nozzle diameters. +std::vector load_nozzle_infos_with_compatibility( + const std::vector& nozzle_infos, + const std::vector& filament_infos, + const std::vector& filament_map, + const std::vector& extruder_volume_types, + const std::vector& nozzle_diameter +); +} // namespace MultiNozzleUtils +} // namespace Slic3r + +#endif // MULTI_NOZZLE_UTILS_HPP diff --git a/src/libslic3r/Orient.cpp b/src/libslic3r/Orient.cpp index 367d6b0967..ae1954087d 100644 --- a/src/libslic3r/Orient.cpp +++ b/src/libslic3r/Orient.cpp @@ -27,19 +27,20 @@ namespace Slic3r { namespace orientation { struct CostItems { - float overhang; - float bottom; - float bottom_hull; - float contour; - float area_laf; // area_of_low_angle_faces - float area_projected; // area of projected 2D profile - float volume; - float area_total; // total area of all faces - float radius; // radius of bounding box - float height_to_bottom_hull_ratio; // affects stability, the lower the better - float unprintability; + float overhang = 0; + float bottom = 0; + float bottom_hull = 0; + float contour = 0; + float area_laf = 0; // area_of_low_angle_faces + float area_projected = 0; // area of projected 2D profile + float volume = 0; + float area_total = 0; // total area of all faces + float radius = 0; // radius of bounding box + float height_to_bottom_hull_ratio = 0; // affects stability, the lower the better + float unprintability = 0; + Eigen::VectorXf areas_cooling; CostItems(CostItems const & other) = default; - CostItems() { memset(this, 0, sizeof(*this)); } + CostItems() = default; static std::string field_names() { return " overhang, bottom, bothull, contour, A_laf, A_prj, unprintability"; } @@ -68,10 +69,11 @@ public: Eigen::VectorXf z_max, z_max_hull; // max of projected z Eigen::VectorXf z_median; // median of projected z Eigen::VectorXf z_mean; // mean of projected z + Eigen::VectorXf areas_cooling; // weighted areas for cool direction std::vector face_normals; std::vector face_normals_hull; OrientParams params; - + bool has_cooling_fan = false; std::vector< Vec3f> orientations; // Vec3f == stl_normal std::function progressind = { }; // default empty indicator function @@ -85,6 +87,7 @@ public: orient_mesh = orient_mesh_; mesh = &orient_mesh->mesh; params = params_; + has_cooling_fan = orient_mesh->has_cooling_fan; progressind = progressind_; params.ASCENT = cos(PI - orient_mesh->overhang_angle * PI / 180); // use per-object overhang angle @@ -158,12 +161,14 @@ public: //To avoid flipping, we need to verify if there are orientations with same unprintability. Vec3f n1 = {0, 0, 1}; auto best_orientation = results_vector[0].first; + size_t best_index = 0; for (int i = 1; i< results_vector.size()-1; i++) { if (abs(results_vector[i].second.unprintability - results_vector[0].second.unprintability) < EPSILON && abs(results_vector[0].first.dot(n1)-1) > EPSILON) { - if (abs(results_vector[i].first.dot(n1)-1) < EPSILON*EPSILON) { + if (abs(results_vector[i].first.dot(n1)-1) < EPSILON*EPSILON) { best_orientation = n1; - break; + best_index = i; + break; } } else { @@ -172,6 +177,9 @@ public: } + // cooling weights are per-orientation, so take them from the orientation actually chosen + areas_cooling = results_vector[best_index].second.areas_cooling; + BOOST_LOG_TRIVIAL(info) << std::fixed << std::setprecision(6) << "best:" << best_orientation.transpose() << ", costs:" << results_vector[0].second.field_values(); std::cout << std::fixed << std::setprecision(6) << "best:" << best_orientation.transpose() << ", costs:" << results_vector[0].second.field_values() << std::endl; @@ -441,6 +449,19 @@ public: Eigen::MatrixXf laf_areas = ((normal_projection_abs.array() < params.LAF_MAX) * (normal_projection_abs.array() > params.LAF_MIN) * (z_max.array() > total_min_z + params.FIRST_LAY_H)).select(areas, 0); costs.area_laf = laf_areas.sum(); + if (has_cooling_fan) + { + // Angle range of overhang faces requiring cooling + float angle_thres_high = -0.6427f; + float angle_thres_low = -0.97f; + // compute the weighted overhang faces area + Eigen::VectorXf ones_f = Eigen::VectorXf::Ones(mesh->facets_count()); + auto overhang_area_condition = (normal_projection.array() < angle_thres_high && normal_projection.array() > angle_thres_low).eval(); + Eigen::VectorXf areas_ = (overhang_area_condition * !bottom_condition_2nd).select(areas, 0); + Eigen::VectorXf weighted_areas = areas_.cwiseProduct(ones_f - normal_projection); + costs.areas_cooling = weighted_areas; + } + // height to bottom_hull_area ratio //float total_max_z = z_projected.maxCoeff(); //costs.height_to_bottom_hull_ratio = SQ(total_max_z) / (costs.bottom_hull + 1e-7); @@ -468,6 +489,67 @@ public: return cost; } + + Vec3d find_cooling_direction2(Vec3d euler_angles, const Eigen::VectorXf& areas_in, TriangleMesh& mesh) + { + Vec3f machine_cool_dir = this->orient_mesh->cooling_direction.cast(); + const size_t num_faces = areas.rows(); + Vec3f best_direction = { 0, 0, 0 }; + + // 1. Make a copy of input mesh, rotate and translate to the best orientation + TriangleMesh mesh_copy = TriangleMesh(mesh.its); + mesh_copy.rotate_x(euler_angles(0, 0)); + mesh_copy.rotate_y(euler_angles(1, 0)); + mesh_copy.rotate_z(euler_angles(2, 0)); + auto bounding_box = mesh_copy.bounding_box(); + Eigen::VectorXf translate_distance = bounding_box.min.array().cast(); + Vec3d mesh_center = mesh_copy.center(); + mesh_copy.translate(-mesh_center(0), -mesh_center(1), -translate_distance(2)); + + // 2. sample cooling direction + const size_t sample_nums = 180; + std::vector cool_dirs; + for (size_t i = 0; i < sample_nums; i++) + { + float angle_deg = i * (360.0 / sample_nums); + float angle_rad = angle_deg * (PI / 180.0); + cool_dirs.push_back(Vec3f{ std::cos(angle_rad), std::sin(angle_rad), 0}); + } + + // 3. accumulate the weighted projected overhang area, find the max weighted project area direction + std::vector face_normals_copy = its_face_normals(mesh_copy.its); + float overhang_projected_max = 0.f; + float overhang_projected_origin = 0.f; + for (auto cool_dir : cool_dirs) + { + float overhang_projected_tmp = 0.f; + for (size_t i = 0; i < num_faces; i++) + { + float cool_dir_projection = face_normals_copy[i].dot(cool_dir); + if (areas_in[i] > 0 && cool_dir_projection > 0) + { + overhang_projected_tmp += areas_in[i] * cool_dir_projection; + } + } + if (overhang_projected_tmp > overhang_projected_max) + { + overhang_projected_max = overhang_projected_tmp; + best_direction = cool_dir; + } + if (cool_dir.dot(machine_cool_dir) > 0.999) + { + overhang_projected_origin = overhang_projected_tmp; + } + } + + // The symmetric model has similar overhang projection at all angles, so Z-axis rotation is unnecessary. + if (std::abs(overhang_projected_origin - overhang_projected_max) < 1.0f) + { + best_direction = machine_cool_dir; + } + BOOST_LOG_TRIVIAL(info) << "best cooling dir = " << best_direction.transpose() << "\n"; + return best_direction.cast(); + } }; void _orient(OrientMeshs& meshs_, @@ -497,6 +579,13 @@ void _orient(OrientMeshs& meshs_, mesh_.orientation = orienter.process(); Geometry::rotation_from_two_vectors(mesh_.orientation, { 0,0,1 }, mesh_.axis, mesh_.angle, &mesh_.rotation_matrix); mesh_.euler_angles = Geometry::extract_euler_angles(mesh_.rotation_matrix); + // find cool direction + if (mesh_.has_cooling_fan) + { + mesh_.orientation_vertical = orienter.find_cooling_direction2(mesh_.euler_angles, orienter.areas_cooling, mesh_.mesh); + BOOST_LOG_TRIVIAL(info) << "cooling direction: " << mesh_.orientation_vertical.transpose() << "\n"; + Geometry::rotation_from_two_vectors(mesh_.orientation_vertical, mesh_.cooling_direction, mesh_.axis_vertical, mesh_.angle_vertical, &mesh_.rotation_matrix_vertical); + } BOOST_LOG_TRIVIAL(debug) << "rotation_from_two_vectors: " << mesh_.orientation << "; " << mesh_.axis << "; " << mesh_.angle << "; euler: " << mesh_.euler_angles.transpose(); }}); } @@ -539,6 +628,94 @@ void orient(ModelInstance* instance) instance->rotate(rotation_matrix); } +void orient_for_cooling(TriangleMesh& mesh, const FanDirection& fan_dir) +{ + Vec3f best_direction{ 0, 0, 0 }; + Vec3f machine_cool_dir{ 0, 0, 0 }; + + if (fan_dir == FanDirection::fdUndefine) + { + // no cooling fan, do not rotate along z axis + return; + } + else if (fan_dir == FanDirection::fdRight) + { + machine_cool_dir = { 1, 0, 0 }; // the cooling fan is on the right side. + } + else + { + // the cooling fan is on the left side or both side has cooling fans + machine_cool_dir = { -1, 0, 0 }; + } + + // 1. filter the overhang_areas + int nfaces = mesh.facets_count(); + auto face_normals = its_face_normals(mesh.its); + + Eigen::VectorXf normal_projection(nfaces, 1); + for (auto i = 0; i < nfaces; i++) + { + normal_projection(i) = face_normals[i].dot(Vec3f(0, 0, 1)); + } + float angle_thres_high = -0.6427f; + float angle_thres_low = -0.97f; + // 2. compute the weighted overhang faces area + Eigen::VectorXf weighted_areas = Eigen::VectorXf::Zero(nfaces); + for (int i = 0; i < nfaces; i++) + { + if (normal_projection(i) < angle_thres_high && normal_projection(i) > angle_thres_low) + { + weighted_areas(i) = mesh.its.facet_area(i) * (1.0f - normal_projection(i)); + } + } + + const size_t sample_nums = 180; + std::vector cool_dirs; + for (size_t i = 0; i < sample_nums; i++) + { + float angle_deg = i * (360.0 / sample_nums); + float angle_rad = angle_deg * (PI / 180.0); + cool_dirs.push_back(Vec3f{ std::cos(angle_rad), std::sin(angle_rad), 0 }); + } + + // 3. accumulate the weighted projected overhang area, find the max weighted project area direction + float overhang_projected_max = 0.f; + float overhang_projected_origin = 0.f; + for (auto cool_dir : cool_dirs) + { + float overhang_projected_tmp = 0.f; + for (size_t i = 0; i < nfaces; i++) + { + float cool_dir_projection = face_normals[i].dot(cool_dir); + if (weighted_areas[i] > 0 && cool_dir_projection > 0) + { + overhang_projected_tmp += weighted_areas[i] * cool_dir_projection; + } + } + if (overhang_projected_tmp > overhang_projected_max) + { + overhang_projected_max = overhang_projected_tmp; + best_direction = cool_dir; + } + if (cool_dir.dot(machine_cool_dir) > 0.999) + { + overhang_projected_origin = overhang_projected_tmp; + } + } + + // The symmetric model has similar overhang projection at all angles, so Z-axis rotation is unnecessary. + if (std::abs(overhang_projected_origin - overhang_projected_max) < 1.0f) + { + return; + } + + // rotate the mesh + Vec3d axis; + double angle; + Matrix3d rotation_matrix; + Geometry::rotation_from_two_vectors(best_direction.cast(), machine_cool_dir.cast(), axis, angle, &rotation_matrix); + mesh.rotate(angle, axis); +} } // namespace arr } // namespace Slic3r diff --git a/src/libslic3r/Orient.hpp b/src/libslic3r/Orient.hpp index 76be064cd1..30dbdd3a20 100644 --- a/src/libslic3r/Orient.hpp +++ b/src/libslic3r/Orient.hpp @@ -26,10 +26,18 @@ struct OrientMesh { TriangleMesh mesh; /// The real mesh data double overhang_angle = 30; double angle{ 0 }; + double angle_vertical{ 0 }; Vec3d axis{ 0,0,1 }; + Vec3d axis_vertical{ 0,0,1 }; Vec3d orientation{ 0,0,1 }; - Matrix3d rotation_matrix; - Vec3d euler_angles; + Vec3d orientation_vertical{ -1,0,0 }; + Matrix3d rotation_matrix = Matrix3d::Identity(); + Matrix3d rotation_matrix_vertical = Matrix3d::Identity(); + Vec3d euler_angles = {0, 0, 0}; + Vec3d euler_angles_vertical = {0, 0, 0}; + Vec3d cooling_direction = {0, 0, 0}; + bool has_cooling_fan{false}; + std::string name; /// Optional setter function which can store arbitrary data in its closure @@ -154,6 +162,9 @@ void orient(ModelObject* obj); void orient(ModelInstance* instance); +// rotate z axis for cooling +void orient_for_cooling(TriangleMesh& mesh, const FanDirection& fan_dir); + }} // namespace Slic3r::orientment #endif // MODELORIENT_HPP diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 6c29367c01..1c785c3184 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -571,6 +571,19 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p return extrusion_coll; } +// ORCA: only_one_wall_top detects the top as "slice − upper", so a feature rising from the middle of a +// top surface becomes an enclosed hole that gets ringed with extra inner walls. Fill those holes back +// into the top. Only holes that are both covered by the upper layer (excludes bridges) and backed by +// solid material (excludes voids) are filled. +static ExPolygons fill_enclosed_top_feature_holes(const ExPolygons &top, const Polygons &covered_by_upper, const ExPolygons &solid) +{ + ExPolygons filled = top; + for (ExPolygon &ex : filled) + ex.holes.clear(); + const ExPolygons feature_holes = intersection_ex(intersection_ex(diff_ex(filled, top), covered_by_upper), solid); + return feature_holes.empty() ? top : union_ex(top, feature_holes); +} + void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExPolygons &top_fills, ExPolygons &non_top_polygons, ExPolygons &fill_clip) const { // other perimeters @@ -636,6 +649,8 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP ExPolygons delete_bridge = diff_ex(orig_polygons, bridge_checker, ApplySafetyOffset::Yes); ExPolygons top_polygons = diff_ex(delete_bridge, upper_polygons_series_clipped, ApplySafetyOffset::Yes); + top_polygons = fill_enclosed_top_feature_holes(top_polygons, upper_polygons_series_clipped, orig_polygons); + // get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the // min_width_top_surface we removed a bit before) ExPolygons temp_gap = diff_ex(top_polygons, fill_clip); @@ -2194,6 +2209,7 @@ void PerimeterGenerator::process_arachne() upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*upper_slices, infill_contour_bbox); top_expolygons = diff_ex(infill_contour, upper_slices_clipped); + top_expolygons = fill_enclosed_top_feature_holes(top_expolygons, upper_slices_clipped, infill_contour); if (!top_expolygons.empty()) { if (lower_slices != nullptr) { diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 98a5a4fcb6..16ae49bdc1 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -252,7 +252,7 @@ void extend_default_config_length(DynamicPrintConfig& config, const bool set_nil auto replace_nil_and_resize = [&](const std::string & key, int length){ ConfigOption* raw_ptr = config.option(key); ConfigOptionVectorBase* opt_vec = static_cast(raw_ptr); - if(set_nil_to_default && raw_ptr->is_nil() && defaults.has(key) && std::find(filament_extruder_override_keys.begin(), filament_extruder_override_keys.end(), key) == filament_extruder_override_keys.end()){ + if(set_nil_to_default && raw_ptr->is_nil() && defaults.has(key) && !is_filament_extruder_override_key(key)){ opt_vec->clear(); opt_vec->resize(length, defaults.option(key)); } @@ -470,6 +470,8 @@ void Preset::normalize(DynamicPrintConfig &config) continue; if (filament_options_with_variant.find(key) != filament_options_with_variant.end()) continue; + if (filament_dev_options.find(key) != filament_dev_options.end()) + continue; auto *opt = config.option(key, false); /*assert(opt != nullptr); assert(opt->is_vector());*/ @@ -890,12 +892,11 @@ std::string Preset::get_printer_type(PresetBundle *preset_bundle) { if (preset_bundle) { auto config = &preset_bundle->printers.get_edited_preset().config; - std::string vendor_name; - for (auto vendor_profile : preset_bundle->vendors) { - for (auto vendor_model : vendor_profile.second.models) - if (vendor_model.name == config->opt_string("printer_model")) + const auto& printer_model = config->opt_string("printer_model"); + for (const auto& vendor_profile : preset_bundle->vendors) { + for (const auto& vendor_model : vendor_profile.second.models) + if (vendor_model.name == printer_model) { - vendor_name = vendor_profile.first; return vendor_model.model_id; } } @@ -907,11 +908,10 @@ std::string Preset::get_current_printer_type(PresetBundle *preset_bundle) { if (preset_bundle) { auto config = &(this->config); - std::string vendor_name; - for (auto vendor_profile : preset_bundle->vendors) { - for (auto vendor_model : vendor_profile.second.models) - if (vendor_model.name == config->opt_string("printer_model")) { - vendor_name = vendor_profile.first; + const auto& printer_model = config->opt_string("printer_model"); + for (const auto& vendor_profile : preset_bundle->vendors) { + for (const auto& vendor_model : vendor_profile.second.models) + if (vendor_model.name == printer_model) { return vendor_model.model_id; } } @@ -1044,7 +1044,12 @@ static std::vector s_Preset_print_options{ "lightning_prune_angle", "lightning_straightening_angle", "top_surface_pattern", + "top_surface_expansion", + "top_surface_expansion_margin", + "top_surface_expansion_direction", "bottom_surface_pattern", + "top_surface_fill_order", + "bottom_surface_fill_order", "infill_direction", "solid_infill_direction", "top_layer_direction", @@ -1060,6 +1065,8 @@ static std::vector s_Preset_print_options{ "skin_infill_density", "align_infill_direction_to_model", "extra_solid_infills", + "center_of_surface_pattern", + "separated_infills", "minimum_sparse_infill_area", "reduce_infill_retraction", "internal_solid_infill_pattern", @@ -1272,6 +1279,7 @@ static std::vector s_Preset_print_options{ "wipe_tower_bridging", "wipe_tower_extra_flow", "single_extruder_multi_material_priming", + "toolchange_ordering", "wipe_tower_rotation_angle", "tree_support_branch_distance_organic", "tree_support_branch_diameter_organic", @@ -1312,7 +1320,7 @@ static std::vector s_Preset_print_options{ }; static std::vector s_Preset_filament_options {/*"filament_colour", */ "default_filament_colour", "required_nozzle_HRC", "filament_diameter", "pellet_flow_coefficient", "volumetric_speed_coefficients", "filament_type", - "filament_soluble", "filament_is_support", "filament_printable", + "filament_soluble", "filament_is_support", "filament_printable", "filament_extruder_compatibility", "filament_max_volumetric_speed", "filament_adaptive_volumetric_speed", "filament_flow_ratio", "filament_density", "filament_adhesiveness_category", "filament_cost", "filament_minimal_purge_on_wipe_tower", "filament_tower_interface_pre_extrusion_dist", "filament_tower_interface_pre_extrusion_length", "filament_tower_ironing_area", "filament_tower_interface_purge_volume", @@ -1328,8 +1336,20 @@ static std::vector s_Preset_filament_options {/*"filament_colour", //exhaust fan control "activate_air_filtration","activate_air_filtration_during_print","activate_air_filtration_on_completion","during_print_exhaust_fan_speed","complete_print_exhaust_fan_speed", // Retract overrides - "filament_retraction_length", "filament_z_hop", "filament_z_hop_types", "filament_retract_lift_above", "filament_retract_lift_below", "filament_retract_lift_enforce", "filament_retraction_speed", "filament_deretraction_speed", "filament_retract_restart_extra", "filament_retraction_minimum_travel", - "filament_retract_when_changing_layer", "filament_wipe", "filament_retract_before_wipe", + "filament_deretraction_speed", + "filament_retract_after_wipe", // Orca + "filament_retract_before_wipe", + "filament_retract_lift_above", + "filament_retract_lift_below", + "filament_retract_lift_enforce", + "filament_retract_restart_extra", + "filament_retract_when_changing_layer", + "filament_retraction_length", + "filament_retraction_minimum_travel", + "filament_retraction_speed", + "filament_wipe", + "filament_z_hop", + "filament_z_hop_types", // Profile compatibility "filament_vendor", "compatible_prints", "compatible_prints_condition", "compatible_printers", "compatible_printers_condition", "inherits", //BBS @@ -1347,8 +1367,18 @@ static std::vector s_Preset_filament_options {/*"filament_colour", "filament_multitool_ramming", "filament_multitool_ramming_volume", "filament_multitool_ramming_flow", "activate_chamber_temp_control", "chamber_minimal_temperature", "filament_long_retractions_when_cut","filament_retraction_distances_when_cut", "idle_temperature", //BBS filament change length while the extruder color - "filament_change_length","filament_flush_volumetric_speed","filament_flush_temp", "filament_cooling_before_tower", - "long_retractions_when_ec", "retraction_distances_when_ec" + "filament_change_length","filament_flush_volumetric_speed","filament_flush_temp","filament_flush_temp_fast", "filament_cooling_before_tower", + // Multi-nozzle pre-cooling / ramming / nozzle-change (nc) filament overrides + "filament_ramming_volumetric_speed", "filament_ramming_volumetric_speed_nc", + "filament_ramming_travel_time", "filament_ramming_travel_time_nc", + "filament_pre_cooling_temperature", "filament_pre_cooling_temperature_nc", + "filament_preheat_temperature_delta", "filament_retract_length_nc", + "filament_change_length_nc", "filament_prime_volume_nc", + "long_retractions_when_ec", "retraction_distances_when_ec", + //ams chamber + "filament_dev_ams_drying_ams_limitations", "filament_dev_ams_drying_temperature", "filament_dev_ams_drying_time", "filament_dev_ams_drying_heat_distortion_temperature", + "filament_dev_chamber_drying_bed_temperature", "filament_dev_chamber_drying_time", + "filament_dev_drying_softening_temperature", "filament_dev_drying_cooling_temperature" }; static std::vector s_Preset_machine_limits_options { @@ -1358,6 +1388,8 @@ static std::vector s_Preset_machine_limits_options { "machine_min_extruding_rate", "machine_min_travel_rate", "machine_max_jerk_x", "machine_max_jerk_y", "machine_max_jerk_z", "machine_max_jerk_e", "machine_max_junction_deviation", + // Bedslinger mass/force limits + "machine_max_force_Y", "machine_bed_mass_Y", "machine_max_printed_mass", //resonance avoidance ported from qidi slicer "resonance_avoidance", "min_resonance_avoidance_speed", "max_resonance_avoidance_speed", // Orca: input shaping @@ -1375,7 +1407,7 @@ static std::vector s_Preset_printer_options { "default_print_profile", "inherits", "silent_mode", "scan_first_layer", "enable_power_loss_recovery", "wrapping_detection_layers", "wrapping_exclude_area", "machine_load_filament_time", "machine_unload_filament_time", "machine_tool_change_time", "time_cost", "machine_pause_gcode", "template_custom_gcode", - "nozzle_type", "nozzle_hrc","auxiliary_fan", "nozzle_volume","upward_compatible_machine", "z_hop_types", "travel_slope", "retract_lift_enforce","support_chamber_temp_control","support_air_filtration","printer_structure", + "nozzle_type", "nozzle_hrc","auxiliary_fan", "fan_direction", "nozzle_volume","upward_compatible_machine", "z_hop_types", "travel_slope", "retract_lift_enforce","support_chamber_temp_control","support_air_filtration","support_cooling_filter","cooling_filter_enabled","printer_structure","farthest_point_timelapse", "best_object_pos", "head_wrap_detect_zone", "host_type", "print_host", "printhost_apikey", "flashforge_serial_number", "bbl_use_printhost", "printer_agent", "print_host_webui", @@ -1387,7 +1419,13 @@ static std::vector s_Preset_printer_options { "cooling_tube_length", "high_current_on_filament_swap", "parking_pos_retraction", "extra_loading_move", "wipe_tower_type", "purge_in_prime_tower", "enable_filament_ramming", "tool_change_on_wipe_tower", "z_offset", "disable_m73", "preferred_orientation", "emit_machine_limits_to_gcode", "pellet_modded_printer", "support_multi_bed_types", "use_3mf", "default_bed_type", "bed_mesh_min","bed_mesh_max","bed_mesh_probe_distance", "adaptive_bed_mesh_margin", "enable_long_retraction_when_cut","long_retractions_when_cut","retraction_distances_when_cut", - "bed_temperature_formula", "nozzle_flush_dataset" + "bed_temperature_formula", "nozzle_flush_dataset", + // Multi-nozzle count + pre-heat model printer options + "extruder_max_nozzle_count", "group_algo_with_time", "enable_pre_heating", "hotend_heating_rate", "hotend_cooling_rate", + "machine_hotend_change_time", "machine_prepare_compensation_time", + // Fast-purge printer flag + device/firmware-facing per-variant extruder-change + // deretraction speed (unconsumed by the slicer; carried by H2D/A2L/X2D/P2S machine profiles). + "support_fast_purge_mode", "deretract_speed_extruder_change" }; static std::vector s_Preset_sla_print_options { @@ -3781,6 +3819,26 @@ void PresetCollection::set_custom_preset_alias(Preset &preset) set_printer_hold_alias(preset.alias, preset); } +std::string PresetCollection::get_preset_alias(Preset &preset, bool force) +{ + if (!preset.alias.empty()) + return preset.alias; + else + set_custom_preset_alias(preset); + + if (!preset.alias.empty() || !force) + return preset.alias; + + std::string alias_name; + std::string preset_name = preset.name; + size_t end_pos = preset_name.find_first_of("@"); + if (end_pos != std::string::npos) { + alias_name = preset_name.substr(0, end_pos); + boost::trim_right(alias_name); + } + return alias_name; +} + void PresetCollection::set_printer_hold_alias(const std::string &alias, Preset &preset, bool remove) { auto compatible_printers = dynamic_cast(preset.config.option("compatible_printers")); diff --git a/src/libslic3r/Preset.hpp b/src/libslic3r/Preset.hpp index bbbdc6c5ff..8863f04672 100644 --- a/src/libslic3r/Preset.hpp +++ b/src/libslic3r/Preset.hpp @@ -72,6 +72,7 @@ #define BBL_JSON_KEY_BOTTOM_TEXTURE_END_NAME "bottom_texture_end_name" #define BBL_JSON_KEY_USE_DOUBLE_EXTRUDER_DEFAULT_TEXTURE "use_double_extruder_default_texture" #define BBL_JSON_KEY_BOTTOM_TEXTURE_RECT "bottom_texture_rect" +#define BBL_JSON_KEY_BOTTOM_TEXTURE_RECT_LONGER "bottom_texture_rect_longer" #define BBL_JSON_KEY_MIDDLE_TEXTURE_RECT "middle_texture_rect" #define BBL_JSON_KEY_HOTEND_MODEL "hotend_model" @@ -150,6 +151,7 @@ public: std::string bottom_texture_end_name; std::string use_double_extruder_default_texture; std::string bottom_texture_rect; + std::string bottom_texture_rect_longer; std::string middle_texture_rect; std::string hotend_model; PrinterVariant* variant(const std::string &name) { @@ -803,6 +805,9 @@ public: std::string path_from_name(const std::string &new_name, bool detach = false) const; std::string path_for_preset(const Preset & preset) const; + // Get the alias of a preset, setting it if it's empty + std::string get_preset_alias(Preset &preset, bool force = false); + size_t num_default_presets() { return m_num_default_presets; } protected: diff --git a/src/libslic3r/PresetBundle.cpp b/src/libslic3r/PresetBundle.cpp index fccbd13b98..01cbc43bc2 100644 --- a/src/libslic3r/PresetBundle.cpp +++ b/src/libslic3r/PresetBundle.cpp @@ -52,9 +52,23 @@ static std::vector s_project_options { "wipe_tower_rotation_angle", "curr_bed_type", "flush_multiplier", + // Fast-purge mode: project-level purge control, inert at Default. + "flush_multiplier_fast", + "prime_volume_mode", "nozzle_volume_type", "filament_map_mode", - "filament_map" + "filament_map", + // Per-filament nozzle-volume choice; project-level like filament_map so the per-filament + // slot resolution survives preset switches. + "filament_volume_map", + // Per-filament physical-nozzle choice the grouping engine writes back; project-level so a + // saved project round-trips the assignment alongside filament_map/filament_volume_map. + "filament_nozzle_map", + // Filament Track Switch device state: whether the switch is installed and ready, and + // whether dynamic per-nozzle filament mapping is active. Persisted with the project and + // restored from a saved 3mf; reset to false on load and set true only by live device sync. + "has_filament_switcher", + "enable_filament_dynamic_map" }; //Orca: add custom as default @@ -71,7 +85,8 @@ DynamicPrintConfig PresetBundle::construct_full_config( const DynamicPrintConfig& project_config, std::vector& in_filament_presets, bool apply_extruder, - std::optional> filament_maps_new) + std::optional> filament_maps_new, + std::optional> filament_volume_maps_new) { DynamicPrintConfig &printer_config = in_printer_preset.config; DynamicPrintConfig &print_config = in_print_preset.config; @@ -86,12 +101,23 @@ DynamicPrintConfig PresetBundle::construct_full_config( size_t num_filaments = in_filament_presets.size(); std::vector filament_maps = out.option("filament_map")->values; + std::vector filament_volume_maps(num_filaments, (int)nvtStandard); + + ConfigOptionInts* filament_volume_map_opt = out.option("filament_volume_map"); if (filament_maps_new.has_value()) filament_maps = *filament_maps_new; + if (filament_volume_maps_new.has_value()) + filament_volume_maps = *filament_volume_maps_new; + else if (filament_volume_map_opt && filament_volume_map_opt->values.size() == num_filaments) + filament_volume_maps = filament_volume_map_opt->values; + // in some middle state, they may be different if (filament_maps.size() != num_filaments) { filament_maps.resize(num_filaments, 1); } + if (filament_volume_maps.size() != num_filaments) { + filament_volume_maps.resize(num_filaments, nvtStandard); + } auto *extruder_diameter = dynamic_cast(out.option("nozzle_diameter")); // Collect the "compatible_printers_condition" and "inherits" values over all presets (print, filaments, printers) into a single vector. @@ -112,17 +138,34 @@ DynamicPrintConfig PresetBundle::construct_full_config( inherits.emplace_back(print_inherits); // BBS: update printer config related with variants + std::vector> nozzle_volume_types; + int extruder_count = 1, extruder_volume_type_count = 1; + bool different_extruder = false; if (apply_extruder) { - out.update_values_to_printer_extruders(out, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); - out.update_values_to_printer_extruders(out, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); - // update print config related with variants - out.update_values_to_printer_extruders(out, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + different_extruder = out.support_different_extruders(extruder_count); + extruder_volume_type_count = out.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + if ((extruder_count > 1) || different_extruder) { + // Orca: keep processing variant_1 before variant_2 here; variant_2 slots are resolved + // against the printer id/variant lists as rewritten by the variant_1 pass, and the + // composed values depend on that order. Note the order is load-bearing, not correct + // in general: the variant_2 pass reads the original full-width arrays through indices + // resolved on the shrunk lists, which mis-reads presets whose variant_2 columns differ + // per variant (e.g. X2D machine_max_speed_e/machine_max_acceleration_e). The slicing + // path composes variant_2 first and is unaffected; changing the order here would alter + // long-standing composed values, so any fix must re-baseline them. + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); + // update print config related with variants + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + } } if (num_filaments <= 1) { // BBS: update filament config related with variants DynamicPrintConfig filament_config = in_filament_presets[0].config; - if (apply_extruder) filament_config.update_values_to_printer_extruders(out, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0]); + if (apply_extruder && ((extruder_count > 1) || different_extruder)) + filament_config.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0], (NozzleVolumeType)filament_volume_maps[0]); out.apply(filament_config); compatible_printers_condition.emplace_back(in_filament_presets[0].compatible_printers_condition()); compatible_prints_condition.emplace_back(in_filament_presets[0].compatible_prints_condition()); @@ -145,8 +188,8 @@ DynamicPrintConfig PresetBundle::construct_full_config( filament_temp_configs.resize(num_filaments); for (size_t i = 0; i < num_filaments; ++i) { filament_temp_configs[i] = *(filament_configs[i]); - if (apply_extruder) - filament_temp_configs[i].update_values_to_printer_extruders(out, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i]); + if (apply_extruder && ((extruder_count > 1) || different_extruder)) + filament_temp_configs[i].update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i], (NozzleVolumeType)filament_volume_maps[i]); } // loop through options and apply them to the resulting config. @@ -221,6 +264,7 @@ DynamicPrintConfig PresetBundle::construct_full_config( out.option("printer_settings_id", true)->value = in_printer_preset.name; out.option("filament_ids", true)->values = filament_ids; out.option("filament_map", true)->values = filament_maps; + out.option("filament_volume_map", true)->values = filament_volume_maps; auto add_if_some_non_empty = [&out](std::vector &&values, const std::string &key) { bool nonempty = false; @@ -348,7 +392,7 @@ PresetBundle::PresetBundle() auto& default_config = this->filaments.default_preset().config; for(const std::string& opt_key : default_config.keys()){ ConfigOption* opt = default_config.optptr(opt_key, false); - bool is_override_key = std::find(filament_extruder_override_keys.begin(),filament_extruder_override_keys.end(), opt_key) != filament_extruder_override_keys.end(); + bool is_override_key = is_filament_extruder_override_key(opt_key); if(!is_override_key || !opt->nullable()) continue; opt->deserialize("nil",ForwardCompatibilitySubstitutionRule::Disable); @@ -721,6 +765,8 @@ std::optional PresetBundle::get_filament_by_filament_id(const auto iter = std::find(compatible_printers.begin(), compatible_printers.end(), printer_name); if (iter != compatible_printers.end() && config.has("filament_printable")) { info.filament_printable = config.option("filament_printable")->values[0]; + if (config.has("filament_extruder_compatibility")) + info.set_filament_extruder_compatibility(config.option("filament_extruder_compatibility")->values[0]); return info; } } @@ -2674,6 +2720,12 @@ void PresetBundle::update_selections(AppConfig &config) std::vector filament_maps(filament_colors.size(), 1); project_config.option("filament_map")->values = filament_maps; + std::vector filament_nozzle_maps(filament_colors.size(), 0); + project_config.option("filament_nozzle_map")->values = filament_nozzle_maps; + + std::vector filament_volume_maps(filament_colors.size(), static_cast(NozzleVolumeType::nvtStandard)); + project_config.option("filament_volume_map")->values = filament_volume_maps; + std::vector extruder_ams_count_str; if (config.has_printer_setting(initial_printer_profile_name, "extruder_ams_count")) { boost::algorithm::split(extruder_ams_count_str, config.get_printer_setting(initial_printer_profile_name, "extruder_ams_count"), boost::algorithm::is_any_of(",")); @@ -2818,6 +2870,12 @@ void PresetBundle::load_selections(AppConfig &config, const PresetPreferences& p std::vector filament_maps(filament_colors.size(), 1); project_config.option("filament_map")->values = filament_maps; + std::vector filament_nozzle_maps(filament_colors.size(), 0); + project_config.option("filament_nozzle_map")->values = filament_nozzle_maps; + + std::vector filament_volume_maps(filament_colors.size(), static_cast(NozzleVolumeType::nvtStandard)); + project_config.option("filament_volume_map")->values = filament_volume_maps; + std::vector extruder_ams_count_str; if (config.has_printer_setting(initial_printer_profile_name, "extruder_ams_count")) { boost::algorithm::split(extruder_ams_count_str, config.get_printer_setting(initial_printer_profile_name, "extruder_ams_count"), boost::algorithm::is_any_of(",")); @@ -2994,7 +3052,8 @@ void PresetBundle::set_num_filaments(unsigned int n, std::vector ne ConfigOptionStrings *filament_multi_color = project_config.option("filament_multi_colour"); ConfigOptionStrings* filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts* filament_map = project_config.option("filament_map"); - + ConfigOptionInts* filament_nozzle_map = project_config.option("filament_nozzle_map"); + ConfigOptionInts* filament_volume_map = project_config.option("filament_volume_map"); filament_color->resize(n); // Sync filament multi colour @@ -3004,6 +3063,8 @@ void PresetBundle::set_num_filaments(unsigned int n, std::vector ne } filament_color_type->resize(n); filament_map->values.resize(n, 1); + filament_nozzle_map->values.resize(n, 0); + filament_volume_map->values.resize(n, static_cast(NozzleVolumeType::nvtStandard)); ams_multi_color_filment.resize(n); // BBS set new filament color to new_color @@ -3031,7 +3092,8 @@ void PresetBundle::set_num_filaments(unsigned int n, std::string new_color) ConfigOptionStrings *filament_multi_color = project_config.option("filament_multi_colour"); ConfigOptionStrings* filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts* filament_map = project_config.option("filament_map"); - + ConfigOptionInts* filament_nozzle_map = project_config.option("filament_nozzle_map"); + ConfigOptionInts* filament_volume_map = project_config.option("filament_volume_map"); filament_color->resize(n); // Sync filament multi colour @@ -3041,6 +3103,8 @@ void PresetBundle::set_num_filaments(unsigned int n, std::string new_color) } filament_color_type->resize(n); filament_map->values.resize(n, 1); + filament_nozzle_map->values.resize(n, 0); + filament_volume_map->values.resize(n, static_cast(NozzleVolumeType::nvtStandard)); ams_multi_color_filment.resize(n); //BBS set new filament color to new_color @@ -3081,15 +3145,25 @@ void PresetBundle::update_num_filaments(unsigned int to_del_flament_id) ConfigOptionStrings *filament_multi_color = project_config.option("filament_multi_colour"); ConfigOptionStrings *filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts* filament_map = project_config.option("filament_map"); + ConfigOptionInts* filament_nozzle_map = project_config.option("filament_nozzle_map"); + ConfigOptionInts* filament_volume_map = project_config.option("filament_volume_map"); if (filament_color->values.size() > to_del_flament_id) { filament_color->values.erase(filament_color->values.begin() + to_del_flament_id); if (filament_map->values.size() > to_del_flament_id) { filament_map->values.erase(filament_map->values.begin() + to_del_flament_id); } + if (filament_nozzle_map->values.size() > to_del_flament_id) { + filament_nozzle_map->values.erase(filament_nozzle_map->values.begin() + to_del_flament_id); + } + if (filament_volume_map->values.size() > to_del_flament_id) { + filament_volume_map->values.erase(filament_volume_map->values.begin() + to_del_flament_id); + } } else { filament_color->values.resize(to_del_flament_id); filament_map->values.resize(to_del_flament_id, 1); + filament_nozzle_map->values.resize(to_del_flament_id, 0); + filament_volume_map->values.resize(to_del_flament_id, static_cast(NozzleVolumeType::nvtStandard)); } // lambda function to erase or resize the container @@ -3312,6 +3386,7 @@ unsigned int PresetBundle::sync_ams_list(std::vector("filament_colour"); ConfigOptionStrings *filament_color_type = project_config.option("filament_colour_type"); ConfigOptionInts * filament_map = project_config.option("filament_map"); + ConfigOptionInts * filament_volume_map = project_config.option("filament_volume_map"); if (color_only) { auto get_map_index = [&ams_infos](const std::vector &infos, const AMSMapInfo &temp) { for (int i = 0; i < infos.size(); i++) { @@ -3493,6 +3568,7 @@ unsigned int PresetBundle::sync_ams_list(std::vectorfilament_presets = exist_filament_presets; filament_map->values.resize(exist_filament_presets.size(), 1); + filament_volume_map->values.resize(exist_filament_presets.size(), static_cast(NozzleVolumeType::nvtStandard)); } else {//overwrite; bool has_placeholders = std::any_of(ams_infos.begin(), ams_infos.end(), @@ -3547,12 +3623,14 @@ unsigned int PresetBundle::sync_ams_list(std::vectorfilament_presets = result_presets; ams_multi_color_filment = result_multi_colors; filament_map->values.resize(total, 1); + filament_volume_map->values.resize(total, static_cast(NozzleVolumeType::nvtStandard)); } else { // BBL: existing wholesale replace filament_color->values = ams_filament_colors; filament_color_type->values = ams_filament_color_types; this->filament_presets = ams_filament_presets; filament_map->values.resize(ams_filament_colors.size(), 1); + filament_volume_map->values.resize(ams_filament_colors.size(), static_cast(NozzleVolumeType::nvtStandard)); } auto& print_config = this->prints.get_edited_preset().config; @@ -3855,10 +3933,26 @@ bool PresetBundle::support_different_extruders() const return supported; } -DynamicPrintConfig PresetBundle::full_config(bool apply_extruder, std::optional>filament_maps) const +std::vector PresetBundle::get_default_nozzle_volume_types_for_filaments(std::vector& f_maps) +{ + std::vector result; + int filament_count = f_maps.size(); + result.resize(filament_count, static_cast(NozzleVolumeType::nvtStandard)); + + auto opt_nozzle_volume_type = dynamic_cast(this->project_config.option("nozzle_volume_type")); + for (int index = 0; index < filament_count; index++) + { + if (opt_nozzle_volume_type && opt_nozzle_volume_type->values.size() > (f_maps[index] - 1)) + result[index] = opt_nozzle_volume_type->values[f_maps[index] - 1]; + } + + return result; +} + +DynamicPrintConfig PresetBundle::full_config(bool apply_extruder, std::optional>filament_maps, std::optional> filament_volume_maps) const { return (this->printers.get_edited_preset().printer_technology() == ptFFF) ? - this->full_fff_config(apply_extruder, filament_maps) : + this->full_fff_config(apply_extruder, filament_maps, filament_volume_maps) : this->full_sla_config(); } @@ -3872,16 +3966,52 @@ DynamicPrintConfig PresetBundle::full_config_secure(std::optional>> PresetBundle::get_full_flush_matrix(bool with_multiplier) const +{ + auto full_config = this->full_config(); + int extruder_nums = full_config.option("nozzle_diameter")->values.size(); + std::vector flush_volume_value = full_config.option("flush_volumes_matrix")->values; + int filament_nums = full_config.option("filament_type")->values.size(); + + std::vector>> matrix; + for (size_t extruder_id = 0; extruder_id < extruder_nums; ++extruder_id) { + std::vector flush_matrix(cast(get_flush_volumes_matrix(flush_volume_value, extruder_id, extruder_nums))); + std::vector> wipe_volumes; + for (unsigned int i = 0; i < filament_nums; ++i) + wipe_volumes.push_back(std::vector(flush_matrix.begin() + i * filament_nums, flush_matrix.begin() + (i + 1) * filament_nums)); + + matrix.emplace_back(wipe_volumes); + } + + if (with_multiplier) { + // Fast purge mode uses flush_multiplier_fast; the default prime_volume_mode==Default + // (or the key absent) reads flush_multiplier, so this is inert. + auto* mode_opt = project_config.option>("prime_volume_mode"); + const bool use_fast = mode_opt && mode_opt->value == PrimeVolumeMode::pvmFast; + auto* mult_opt = project_config.option(use_fast ? "flush_multiplier_fast" : "flush_multiplier"); + auto flush_multiplies = mult_opt ? mult_opt->values : project_config.option("flush_multiplier")->values; + flush_multiplies.resize(extruder_nums, 1); + for (size_t extruder_id = 0; extruder_id < extruder_nums; ++extruder_id) { + for (auto& vec : matrix[extruder_id]) { + for (auto& v : vec) + v *= flush_multiplies[extruder_id]; + } + } + } + + return matrix; +} + const std::set ignore_settings_list ={ "inherits", "print_settings_id", "filament_settings_id", "printer_settings_id" }; -DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optional> filament_maps_new) const +DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optional> filament_maps_new, std::optional> filament_volume_maps_new) const { DynamicPrintConfig out; out.apply(FullPrintConfig::defaults()); @@ -3895,8 +4025,17 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio size_t num_filaments = this->filament_presets.size(); std::vector filament_maps = out.option("filament_map")->values; + std::vector filament_volume_maps(num_filaments, (int)nvtStandard); + + ConfigOptionInts* filament_volume_map_opt = out.option("filament_volume_map"); if (filament_maps_new.has_value()) filament_maps = *filament_maps_new; + if (filament_volume_maps_new.has_value()) { + filament_volume_maps = *filament_volume_maps_new; + out.option("filament_volume_map", true)->values = filament_volume_maps; + } + else if (filament_volume_map_opt && filament_volume_map_opt->values.size() == num_filaments) + filament_volume_maps = filament_volume_map_opt->values; //in some middle state, they may be different if (filament_maps.size() != num_filaments) { filament_maps.resize(num_filaments, 1); @@ -3904,6 +4043,9 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio else { assert(filament_maps.size() == num_filaments); } + if (filament_volume_maps.size() != num_filaments) { + filament_volume_maps.resize(num_filaments, nvtStandard); + } auto* extruder_diameter = dynamic_cast(out.option("nozzle_diameter")); // Collect the "compatible_printers_condition" and "inherits" values over all presets (print, filaments, printers) into a single vector. @@ -3933,18 +4075,34 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio different_settings.emplace_back(different_print_settings); //BBS: update printer config related with variants + std::vector> nozzle_volume_types; + int extruder_count = 1, extruder_volume_type_count = 1; + bool different_extruder = false; if (apply_extruder) { - out.update_values_to_printer_extruders(out, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); - out.update_values_to_printer_extruders(out, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); - //update print config related with variants - out.update_values_to_printer_extruders(out, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + different_extruder = out.support_different_extruders(extruder_count); + extruder_volume_type_count = out.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + if ((extruder_count > 1) || different_extruder) { + // Orca: keep processing variant_1 before variant_2 here; variant_2 slots are resolved + // against the printer id/variant lists as rewritten by the variant_1 pass, and the + // composed values depend on that order. Note the order is load-bearing, not correct + // in general: the variant_2 pass reads the original full-width arrays through indices + // resolved on the shrunk lists, which mis-reads presets whose variant_2 columns differ + // per variant (e.g. X2D machine_max_speed_e/machine_max_acceleration_e). The slicing + // path composes variant_2 first and is unaffected; changing the order here would alter + // long-standing composed values, so any fix must re-baseline them. + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); + //update print config related with variants + out.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + } } if (num_filaments <= 1) { //BBS: update filament config related with variants DynamicPrintConfig filament_config = this->filaments.get_edited_preset().config; - if (apply_extruder) - filament_config.update_values_to_printer_extruders(out, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0]); + if (apply_extruder && ((extruder_count > 1) || different_extruder)) + filament_config.update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[0], (NozzleVolumeType)filament_volume_maps[0]); out.apply(filament_config); compatible_printers_condition.emplace_back(this->filaments.get_edited_preset().compatible_printers_condition()); compatible_prints_condition .emplace_back(this->filaments.get_edited_preset().compatible_prints_condition()); @@ -4037,8 +4195,8 @@ DynamicPrintConfig PresetBundle::full_fff_config(bool apply_extruder, std::optio filament_temp_configs.resize(num_filaments); for (size_t i = 0; i < num_filaments; ++i) { filament_temp_configs[i] = *(filament_configs[i]); - if (apply_extruder) - filament_temp_configs[i].update_values_to_printer_extruders(out, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i]); + if (apply_extruder && ((extruder_count > 1) || different_extruder)) + filament_temp_configs[i].update_values_to_printer_extruders(out, extruder_count, extruder_volume_type_count, nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, filament_maps[i], (NozzleVolumeType)filament_volume_maps[i]); } // loop through options and apply them to the resulting config. @@ -4282,6 +4440,10 @@ void PresetBundle::load_config_file_config(const std::string &name_or_path, bool }; clear_compatible_printers(config); + // Dynamic per-nozzle filament mapping reflects live device state, not a stored setting; + // drop it from any imported config so it only comes from the connected printer. + config.erase("enable_filament_dynamic_map"); + #if 0 size_t num_extruders = (printer_technology == ptFFF) ? std::min(config.option("nozzle_diameter" )->values.size(), @@ -4770,6 +4932,8 @@ std::pair PresetBundle::load_vendor_configs_ model.use_double_extruder_default_texture = it.value(); } else if (boost::iequals(it.key(), BBL_JSON_KEY_BOTTOM_TEXTURE_RECT)) { model.bottom_texture_rect = it.value(); + } else if (boost::iequals(it.key(), BBL_JSON_KEY_BOTTOM_TEXTURE_RECT_LONGER)) { + model.bottom_texture_rect_longer = it.value(); } else if (boost::iequals(it.key(), BBL_JSON_KEY_MIDDLE_TEXTURE_RECT)) { model.middle_texture_rect = it.value(); } diff --git a/src/libslic3r/PresetBundle.hpp b/src/libslic3r/PresetBundle.hpp index fc03ff8d3b..685687975b 100644 --- a/src/libslic3r/PresetBundle.hpp +++ b/src/libslic3r/PresetBundle.hpp @@ -72,6 +72,25 @@ struct FilamentBaseInfo bool is_support{ false }; bool is_system{ true }; int filament_printable = 3; + + // filament_extruder_compatibility packs one compatibility level per extruder into a single + // 32-bit int, 3 bits per extruder (up to 10 extruders). Levels: 0 = printable, 1 = error, + // 2 = critical warning, 3 = warning (4-7 reserved). extruder_id is 0-based. + int get_extruder_compatibility(int extruder_id) const { + constexpr int bits_per_extruder = 3; + constexpr int extruder_mask = (1 << bits_per_extruder) - 1; // 0x7 + constexpr int max_extruder_count = 32 / bits_per_extruder; // 10 + + if (extruder_id < 0 || extruder_id >= max_extruder_count) + return 0; + return (m_filament_extruder_compatibility >> (bits_per_extruder * extruder_id)) & extruder_mask; + } + + void set_filament_extruder_compatibility(int value) { m_filament_extruder_compatibility = value; } + int get_filament_extruder_compatibility() const { return m_filament_extruder_compatibility; } + +private: + int m_filament_extruder_compatibility = 0; }; enum BundleType{ @@ -156,7 +175,8 @@ public: const DynamicPrintConfig &project_config, std::vector &in_filament_presets, bool apply_extruder, - std::optional> filament_maps_new); + std::optional> filament_maps_new, + std::optional> filament_volume_maps_new = std::nullopt); // ORCA: utility function to find the vendor for a given preset name static std::string find_preset_vendor(const std::string& preset_name, Preset::Type type); @@ -364,10 +384,19 @@ public: bool has_defauls_only() const { return prints.has_defaults_only() && filaments.has_defaults_only() && printers.has_defaults_only(); } - DynamicPrintConfig full_config(bool apply_extruder = true, std::optional>filament_maps = std::nullopt) const; + DynamicPrintConfig full_config(bool apply_extruder = true, std::optional>filament_maps = std::nullopt, std::optional> filament_volume_maps = std::nullopt) const; // full_config() with the some "useless" config removed. DynamicPrintConfig full_config_secure(std::optional>filament_maps = std::nullopt) const; + // Default per-filament nozzle-volume types: each filament inherits the volume type of the + // extruder it maps to (1-based f_maps), Standard when unknown. + std::vector get_default_nozzle_volume_types_for_filaments(std::vector& f_maps); + + // Per-extruder flush matrix [extruder_id][from_filament][to_filament] in mm^3, optionally scaled + // by the per-extruder flush_multiplier (or flush_multiplier_fast when prime_volume_mode==Fast). + // Used by the print-dispatch nozzle-mapping flush-weight estimate. + std::vector>> get_full_flush_matrix(bool with_multiplier = true) const; + //BBS: add some functions for multiple extruders int get_printer_extruder_count() const; bool support_different_extruders() const; @@ -519,7 +548,7 @@ private: /*ConfigSubstitutions load_config_file_config_bundle( const std::string &path, const boost::property_tree::ptree &tree, ForwardCompatibilitySubstitutionRule compatibility_rule);*/ - DynamicPrintConfig full_fff_config(bool apply_extruder, std::optional> filament_maps=std::nullopt) const; + DynamicPrintConfig full_fff_config(bool apply_extruder, std::optional> filament_maps=std::nullopt, std::optional> filament_volume_maps=std::nullopt) const; DynamicPrintConfig full_sla_config() const; // Orca: used for validation only diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index a676d24cc0..0c65f5dcd5 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -176,6 +177,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "filename_format", "retraction_minimum_travel", "retract_before_wipe", + // Orca: + "retract_after_wipe", "retract_when_changing_layer", "retraction_length", "retract_length_toolchange", @@ -209,6 +212,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n "chamber_minimal_temperature", "thumbnails", "thumbnails_format", + "center_of_surface_pattern", + "separated_infills", "seam_gap", "role_based_wipe_speed", "wipe_speed", @@ -330,9 +335,13 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "first_layer_print_sequence" || opt_key == "other_layers_print_sequence" || opt_key == "other_layers_print_sequence_nums" + || opt_key == "toolchange_ordering" || opt_key == "extruder_ams_count" + || opt_key == "extruder_nozzle_stats" || opt_key == "filament_map_mode" || opt_key == "filament_map" + || opt_key == "filament_nozzle_map" + || opt_key == "filament_volume_map" || opt_key == "filament_adhesiveness_category" || opt_key == "filament_tower_interface_pre_extrusion_dist" || opt_key == "filament_tower_interface_pre_extrusion_length" @@ -2482,6 +2491,9 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) std::vector::const_iterator print_object_instance_sequential_active; std::vector>> layers_to_print = GCode::collect_layers_to_print(*this); std::vector printExtruders; + // Cleared on every process so a print-sequence or selector-mode change can never leave + // stale object pointers behind; repopulated below only by the sequential selector path. + m_sequential_dynamic_orderings.clear(); if (this->config().print_sequence == PrintSequence::ByObject) { // Order object instances for sequential print. print_object_instances_ordering = sort_object_instances_by_model_order(*this); @@ -2502,26 +2514,100 @@ void Print::process(long long *time_cost_with_cache, bool use_cache) auto physical_unprintables = this->get_physical_unprintable_filaments(used_filaments); auto geometric_unprintables = this->get_geometric_unprintable_filaments(); - std::vectorfilament_maps = this->get_filament_maps(); - auto map_mode = get_filament_map_mode(); - // get recommended filament map - if (map_mode < FilamentMapMode::fmmManual) { - filament_maps = ToolOrdering::get_recommended_filament_maps(all_filaments, this, map_mode, physical_unprintables, geometric_unprintables); - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) { return value + 1; }); - update_filament_maps_to_config(filament_maps); + auto filament_unprintable_volumes = this->get_filament_unprintable_flow(used_filaments); + // Selector (per-layer regroup) prints skip the static grouping: their print-wide result + // is stitched from the per-object plans after the ordering loop below. + const bool dynamic_reorder = this->is_dynamic_group_reorder(); + if (!dynamic_reorder) { + std::vectorfilament_maps = this->get_filament_maps(); + auto map_mode = get_filament_map_mode(); + // Grouping returns a nozzle-aware result; the 1-based extruder map for the by-object + // path is derived from it. It is computed in every static map mode (in manual modes it + // mirrors the user's assignment) and published print-wide: GCode's per-nozzle + // placeholder and config-index lookups read it via get_layered_nozzle_group_result(), + // and without it sequential exports on multi-nozzle printers see an empty nozzle table + // (e.g. nozzle_diameter_at_nozzle_id[]) and custom g-code fails to resolve. + auto grouping_result = ToolOrdering::get_recommended_filament_maps(all_filaments, this, map_mode, physical_unprintables, geometric_unprintables, filament_unprintable_volumes); + this->set_nozzle_group_result(std::make_shared(grouping_result)); + // Orca: the sequential write-back stays gated to auto modes. In manual modes the + // config maps already carry the user's assignment (the per-object ToolOrdering below + // consumes them directly), so a write-back would only re-store the pre-slice values; + // keeping the gate avoids churning the config on every sequential manual slice. + if (map_mode < FilamentMapMode::fmmManual) { + auto derived_maps = grouping_result.get_extruder_map(false); + if (!derived_maps.empty()) { + filament_maps = derived_maps; + // Write the maps back: used filaments adopt the engine's extruder/nozzle + // choice, unused ones keep their config assignment. + // Orca: the config maps are the merge base; fall back to a synthesized base + // when no producer sized them to the filament count (CLI runs until the + // per-filament synthesis lands there), where indexing per filament would + // run out of bounds. + std::vector base_filament_map = m_config.filament_map.values; + if (base_filament_map.size() != derived_maps.size()) + base_filament_map.assign(derived_maps.size(), 1); + std::vector base_volume_map = m_config.filament_volume_map.values; + if (base_volume_map.size() != derived_maps.size()) + base_volume_map.assign(derived_maps.size(), (int)nvtStandard); + update_filament_maps_to_config(FilamentGroupUtils::update_used_filament_values(base_filament_map, derived_maps, used_filaments), + FilamentGroupUtils::update_used_filament_values(base_volume_map, grouping_result.get_volume_map(), used_filaments), + grouping_result.get_nozzle_map()); + } + } + // check map valid both in auto and mannual mode + std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); } - // check map valid both in auto and mannual mode - std::transform(filament_maps.begin(), filament_maps.end(), filament_maps.begin(), [](int value) {return value - 1; }); // print_object_instances_ordering = sort_object_instances_by_max_z(print); + const PrintObject *prev_planned_object = nullptr; + unsigned int seq_last_extruder = (unsigned int)-1; + MultiNozzleUtils::NozzleStatusRecorder nozzle_status; + std::vector> nozzle_map_per_layer; + std::vector> stitched_layer_filaments; print_object_instance_sequential_active = print_object_instances_ordering.begin(); for (; print_object_instance_sequential_active != print_object_instances_ordering.end(); ++print_object_instance_sequential_active) { - tool_ordering = ToolOrdering(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); - tool_ordering.sort_and_build_data(*(*print_object_instance_sequential_active)->print_object, initial_extruder_id); + const PrintObject *print_object = (*print_object_instance_sequential_active)->print_object; + if (dynamic_reorder) { + if (print_object != prev_planned_object) { + // Plan each unique object once, threading the physical nozzle occupancy and + // the previous object's last filament into the next plan; repeated instances + // of an object reuse the plan, mirroring the export loop's reuse. + ToolOrdering ordering(*print_object, seq_last_extruder); + ordering.set_nozzle_status(nozzle_status); + ordering.sort_and_build_data(*print_object, seq_last_extruder); + nozzle_status = ordering.get_nozzle_status(); + if (ordering.last_extruder() != static_cast(-1)) + seq_last_extruder = ordering.last_extruder(); + const auto &object_maps = ordering.get_layered_nozzle_group_result().get_layer_filament_nozzle_maps(); + nozzle_map_per_layer.insert(nozzle_map_per_layer.end(), object_maps.begin(), object_maps.end()); + // Orca: the stitch input comes from the same orderings that produced the + // per-layer maps — the collection loop above is per-instance and seeded -1, + // so its layers are misaligned with these plans. layer_tools() of a sorted + // ordering already carries the planned per-layer filament order. + for (const auto &layer_tool : ordering.layer_tools()) + stitched_layer_filaments.emplace_back(layer_tool.extruders); + m_sequential_dynamic_orderings[print_object] = std::move(ordering); + prev_planned_object = print_object; + } + tool_ordering = m_sequential_dynamic_orderings.at(print_object); + } else { + tool_ordering = ToolOrdering(*print_object, initial_extruder_id); + tool_ordering.sort_and_build_data(*print_object, initial_extruder_id); + } if ((initial_extruder_id = tool_ordering.first_extruder()) != static_cast(-1)) { append(printExtruders, tool_ordering.tools_for_layer(layers_to_print.front().first).extruders); } } + if (dynamic_reorder && m_objects.size() > 1) { + // Stitch the per-object plans into one print-wide selector result. A single-object + // sequential print publishes (and writes back) from its own ordering instead: the + // per-object publish gate treats one object as not sequential. + auto stitched = ToolOrdering::build_sequential_group_result(this, std::move(nozzle_map_per_layer), stitched_layer_filaments, + stitched_layer_filaments, used_filaments, physical_unprintables, + geometric_unprintables, filament_unprintable_volumes); + this->set_nozzle_group_result(std::make_shared(stitched)); + update_to_config_by_nozzle_group_result(stitched); + } } else { tool_ordering = this->tool_ordering(); @@ -2658,8 +2744,14 @@ std::string Print::export_gcode(const std::string& path_template, GCodeProcessor gcode.do_export(this, path.c_str(), result, thumbnail_cb); gcode.export_layer_filaments(result); //BBS - if (result != nullptr) + if (result != nullptr) { result->conflict_result = m_conflict_result; + // Surface the slicer's per-filament nozzle grouping onto the post-slice result + // the device GUI reads. This is the static L/R + rack subset the multi-nozzle path computes; + // null for single-nozzle prints where nothing computes it. It is assigned after g-code + // generation and read by no emitter, so it does not affect the emitted g-code. + result->nozzle_group_result = this->get_layered_nozzle_group_result(); + } return path.c_str(); } @@ -3183,16 +3275,70 @@ void Print::finalize_first_layer_convex_hull() m_first_layer_convex_hull = Geometry::convex_hull(m_first_layer_convex_hull.points); } -void Print::update_filament_maps_to_config(std::vector f_maps) +void Print::update_filament_maps_to_config(std::vector f_maps, std::vector f_volume_maps, std::vector f_nozzle_maps) { - if (m_config.filament_map.values != f_maps) + if ((m_config.filament_map.values != f_maps) || (m_config.filament_volume_map.values != f_volume_maps) || (m_config.filament_nozzle_map.values != f_nozzle_maps)) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": filament maps changed after pre-slicing."); m_ori_full_print_config.option("filament_map", true)->values = f_maps; m_config.filament_map.values = f_maps; + if (!f_volume_maps.empty()) { + m_ori_full_print_config.option("filament_volume_map", true)->values = f_volume_maps; + m_config.filament_volume_map.values = f_volume_maps; + } + else { + m_ori_full_print_config.option("filament_volume_map", true)->values.resize(f_maps.size(), nvtStandard); + m_config.filament_volume_map.values.resize(f_maps.size(), nvtStandard); + } + + if (!f_nozzle_maps.empty()) { + m_ori_full_print_config.option("filament_nozzle_map", true)->values = f_nozzle_maps; + m_config.filament_nozzle_map.values = f_nozzle_maps; + } + } + + { + int extruder_count = 1, extruder_volume_type_count = 1; + bool support_multi = m_ori_full_print_config.support_different_extruders(extruder_count); + std::vector> nozzle_volume_types; + extruder_volume_type_count = m_ori_full_print_config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + //filament_map_2 + // Orca: seed with 0-based extruder indices so the override keying below degenerates to the + // plain per-extruder slot when the rebuild loop is skipped; the loop overwrites every + // entry when it runs. + m_config.filament_map_2.values = f_maps; + for (auto& v : m_config.filament_map_2.values) + --v; + auto opt_extruder_type = dynamic_cast(m_ori_full_print_config.option("extruder_type")); + auto opt_nozzle_volume_type = dynamic_cast(m_ori_full_print_config.option("nozzle_volume_type")); + // Orca: the loop tolerates configs without the extruder options (unit tests, degenerate + // presets); the backfill and the override are bounds-checked because the change block above + // is skipped when the maps are unchanged, in which case the stored map may be shorter than + // the filament count. + auto* ori_volume_map = m_ori_full_print_config.option("filament_volume_map", true); + for (int index = 0; opt_extruder_type && opt_nozzle_volume_type && index < f_maps.size(); index++) + { + ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(f_maps[index] - 1)); + NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(f_maps[index] - 1)); + if (f_volume_maps.empty()) { + // No per-filament map supplied: backfill from the extruder's own volume type. + if (m_config.filament_volume_map.values.size() > index) + m_config.filament_volume_map.values[index] = nozzle_volume_type; + if (ori_volume_map->values.size() > index) + ori_volume_map->values[index] = nozzle_volume_type; + } + else if ((extruder_volume_type_count > extruder_count) && (m_config.filament_volume_map.values.size() > index)) + nozzle_volume_type = (NozzleVolumeType)(m_config.filament_volume_map.values[index]); + m_config.filament_map_2.values[index] = m_ori_full_print_config.get_index_for_extruder(f_maps[index], "print_extruder_id", extruder_type, nozzle_volume_type, "print_extruder_variant"); + } + m_full_print_config = m_ori_full_print_config; - m_full_print_config.update_values_to_printer_extruders_for_multiple_filaments(m_full_print_config, filament_options_with_variant, "filament_self_index", "filament_extruder_variant"); + std::set filament_keys = filament_options_with_variant; + filament_keys.insert("filament_self_index"); + if ((extruder_count > 1) || support_multi) + m_full_print_config.update_values_to_printer_extruders_for_multiple_filaments(m_full_print_config, extruder_count, extruder_volume_type_count, filament_keys, "filament_self_index", "filament_extruder_variant"); const std::vector &extruder_retract_keys = print_config_def.extruder_retract_keys(); const std::string filament_prefix = "filament_"; @@ -3205,16 +3351,147 @@ void Print::update_filament_maps_to_config(std::vector f_maps) const ConfigOption *opt_old_machine = m_config.option(opt_key); if (opt_new_filament) - compute_filament_override_value(opt_key, opt_old_machine, opt_new_machine, opt_new_filament, m_full_print_config, print_diff, filament_overrides, f_maps); + compute_filament_override_value(opt_key, opt_old_machine, opt_new_machine, opt_new_filament, m_full_print_config, print_diff, filament_overrides, m_config.filament_map_2.values); } - t_config_option_keys keys(filament_options_with_variant.begin(), filament_options_with_variant.end()); - m_config.apply_only(m_full_print_config, keys, true); + if ((extruder_count > 1) || support_multi) { + t_config_option_keys keys(filament_options_with_variant.begin(), filament_options_with_variant.end()); + keys.push_back("filament_self_index"); + m_config.apply_only(m_full_print_config, keys, true); + } if (!print_diff.empty()) { m_placeholder_parser.apply_config(filament_overrides); m_config.apply(filament_overrides); } } + update_filament_self_index_cache(); + m_has_auto_filament_map_result = true; +} + +bool Print::collect_filament_variant_uses(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result, + const DynamicPrintConfig& config, + std::unordered_map>& uses) const +{ + auto opt_filament_type = config.option("filament_type"); + auto opt_extruder_type = dynamic_cast(config.option("extruder_type")); + if (!opt_filament_type || !opt_extruder_type) + return false; + + const size_t filament_count = opt_filament_type->values.size(); + const size_t extruder_count = opt_extruder_type->values.size(); + auto add_use = [&](std::set &variant_set, const MultiNozzleUtils::NozzleInfo &nozzle) { + // Orca: a persisted result can outlive a printer swap; never index the extruder + // arrays with a stale nozzle record. + if (nozzle.extruder_id < 0 || static_cast(nozzle.extruder_id) >= extruder_count) + return; + FilamentVariantUse use; + use.extruder_type = static_cast(opt_extruder_type->get_at(nozzle.extruder_id)); + use.nozzle_volume_type = nozzle.volume_type; + use.extruder_id = nozzle.extruder_id; + variant_set.insert(use); + }; + for (size_t f_index = 0; f_index < filament_count; ++f_index) { + std::set variant_set; + for (const MultiNozzleUtils::NozzleInfo &nozzle : group_result.get_nozzles_for_filament(static_cast(f_index))) + add_use(variant_set, nozzle); + // A filament the plan never routes (not printed) still needs a deterministic slot: take + // its default-map assignment from the result itself, so both the slice-time write-back + // and the apply-time reproduction resolve the same slot even when the surrounding + // filament_map has not round-tripped through the plate config in between. + if (variant_set.empty()) { + if (auto default_nozzle = group_result.get_nozzle_for_filament(static_cast(f_index), -1); default_nozzle.has_value()) + add_use(variant_set, *default_nozzle); + } + // Filaments still without a variant stay absent from the map: the slot rebuild then + // resolves them from their static filament_map / filament_volume_map assignment. + if (!variant_set.empty()) + uses[static_cast(f_index)] = std::vector(variant_set.begin(), variant_set.end()); + } + return true; +} + +void Print::update_to_config_by_nozzle_group_result(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result) +{ + std::vector derived_maps = group_result.get_extruder_map(false); // 1-based + if (derived_maps.empty()) + return; + + if (!group_result.is_support_dynamic_nozzle_map()) { + // No filament actually migrated between nozzles, so the plan reduces to a single + // grouping: write all maps like the static paths do, and the next apply re-derives + // identical slots from the written maps. + std::vector base_filament_map = m_config.filament_map.values; + if (base_filament_map.size() != derived_maps.size()) + base_filament_map.assign(derived_maps.size(), 1); + std::vector base_volume_map = m_config.filament_volume_map.values; + if (base_volume_map.size() != derived_maps.size()) + base_volume_map.assign(derived_maps.size(), (int)nvtStandard); + const std::vector used_filaments = group_result.get_used_filaments(); + update_filament_maps_to_config(FilamentGroupUtils::update_used_filament_values(base_filament_map, derived_maps, used_filaments), + FilamentGroupUtils::update_used_filament_values(base_volume_map, group_result.get_volume_map(), used_filaments), + group_result.get_nozzle_map()); + return; + } + + // Orca: keep the coarse per-filament extruder map published even though the per-layer truth + // lives in the grouping result: the pre-export consumers, the plate read-back after slicing + // and the preview panel all key on filament_map. The write is direct — the full map + // write-back's single-slot rebuild would undo the per-variant expansion below. + m_ori_full_print_config.option("filament_map", true)->values = derived_maps; + m_config.filament_map.values = derived_maps; + + std::unordered_map> filament_variant_uses; + if (!collect_filament_variant_uses(group_result, m_ori_full_print_config, filament_variant_uses)) { + // Degenerate config (no filament/extruder typing): fall back to the single-slot + // write-back so the maps and overrides stay coherent. + update_filament_maps_to_config(derived_maps); + return; + } + + int extruder_count = 1, extruder_volume_type_count = 1; + m_ori_full_print_config.support_different_extruders(extruder_count); + std::vector> nozzle_volume_types; + extruder_volume_type_count = m_ori_full_print_config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + // Note: filament_map_2 keeps its apply-time (static) derivation here; the per-slot machine + // indices below key the override merge instead, so nothing on this path reads it. Its other + // consumers are the three-map write-back (which recomputes it) and the diagnostic copy in + // the g-code header; the time estimator resolves per-(extruder x volume-type) machine limits + // from the live nozzle occupancy instead (see GCodeProcessor::get_machine_config_idx). + m_full_print_config = m_ori_full_print_config; + std::set filament_keys = filament_options_with_variant; + filament_keys.insert("filament_self_index"); + std::vector slot_machine_indices; + m_full_print_config.update_filament_config_values_for_multiple_extruders(m_full_print_config, filament_variant_uses, + extruder_count, extruder_volume_type_count, + filament_keys, "filament_self_index", "filament_extruder_variant", + &slot_machine_indices); + + const std::vector &extruder_retract_keys = print_config_def.extruder_retract_keys(); + const std::string filament_prefix = "filament_"; + t_config_option_keys print_diff; + DynamicPrintConfig filament_overrides; + for (auto& opt_key: extruder_retract_keys) + { + const ConfigOption *opt_new_filament = m_full_print_config.option(filament_prefix + opt_key); + const ConfigOption *opt_new_machine = m_full_print_config.option(opt_key); + const ConfigOption *opt_old_machine = m_config.option(opt_key); + + if (opt_new_filament) + compute_filament_override_value(opt_key, opt_old_machine, opt_new_machine, opt_new_filament, m_full_print_config, print_diff, filament_overrides, slot_machine_indices); + } + + { + t_config_option_keys keys(filament_options_with_variant.begin(), filament_options_with_variant.end()); + keys.push_back("filament_self_index"); + m_config.apply_only(m_full_print_config, keys, true); + } + if (!print_diff.empty()) { + m_placeholder_parser.apply_config(filament_overrides); + m_config.apply(filament_overrides); + } + + update_filament_self_index_cache(); m_has_auto_filament_map_result = true; } @@ -3228,6 +3505,16 @@ std::vector Print::get_filament_maps() const return m_config.filament_map.values; } +std::vector Print::get_filament_nozzle_maps() const +{ + return m_config.filament_nozzle_map.values; +} + +std::vector Print::get_filament_volume_maps() const +{ + return m_config.filament_volume_map.values; +} + FilamentMapMode Print::get_filament_map_mode() const { return m_config.filament_map_mode; @@ -3267,6 +3554,41 @@ std::vector> Print::get_physical_unprintable_filaments(const std:: return physical_unprintables; } +std::map> Print::get_filament_unprintable_flow(const std::vector &used_filaments) const +{ + std::map> ret; + std::vector extruder_variant_list = m_config.printer_extruder_variant.values; + // A filament that declares no extruder variants carries no flow restriction. + const ConfigOptionStrings *filament_variant_opt = m_ori_full_print_config.option("filament_extruder_variant"); + if (filament_variant_opt == nullptr) + return ret; + std::vector filament_variant_list = filament_variant_opt->values; + std::vector filament_self_index; + if (!m_ori_full_print_config.has("filament_self_index")) + filament_self_index.resize(filament_variant_list.size(), 1); + else + filament_self_index = m_ori_full_print_config.option("filament_self_index")->values; + std::unordered_set used_fils_set(used_filaments.begin(), used_filaments.end()); + + std::unordered_map> filament_variant_map; + for(int i = 0; i < filament_variant_list.size(); ++i){ + NozzleVolumeType volume = convert_to_nvt_type(filament_variant_list[i]); + if(volume != nvtHybrid) filament_variant_map[filament_self_index[i]].insert(volume); + } + + for (auto iter : filament_variant_map) { + int fil_idx = iter.first - 1; + if (used_fils_set.find(fil_idx) == used_fils_set.end()) continue; + const std::set &volumes = iter.second; + for (int exd_idx = 0; exd_idx < extruder_variant_list.size(); ++exd_idx) { + auto exd_volume = convert_to_nvt_type(extruder_variant_list[exd_idx]); + assert(exd_volume != nvtHybrid); + if (volumes.find(exd_volume) == volumes.end() && exd_volume != nvtHybrid) ret[fil_idx].insert(exd_volume); + } + } + return ret; +} + std::vector Print::get_extruder_printable_height() const { @@ -3306,6 +3628,158 @@ size_t Print::get_extruder_id(unsigned int filament_id) const return 0; } +// Region reachable by every extruder = intersection of all per-extruder printable areas. +// For single-nozzle printers, or whenever extruder_printable_area is unpopulated / degenerate (all +// current single/dual profiles), fall back to the full printable_area so the wipe-tower-center clamp +// is identical to the previous full-bed clamp. +Polygons Print::get_extruder_shared_printable_polygon() const +{ + const std::vector& extruder_printable_areas = m_config.extruder_printable_area.values; + if (m_config.nozzle_diameter.size() < 2 || extruder_printable_areas.empty()) + return {Polygon::new_scale(m_config.printable_area.values)}; + for (const Vec2ds& area : extruder_printable_areas) + if (area.size() < 3) + return {Polygon::new_scale(m_config.printable_area.values)}; + + Polygons shared_printable_polys = {Polygon::new_scale(extruder_printable_areas.front())}; + for (size_t i = 1; i < extruder_printable_areas.size(); ++i) + shared_printable_polys = intersection(shared_printable_polys, Polygons{Polygon::new_scale(extruder_printable_areas[i])}); + return shared_printable_polys; +} + +// Narrow the stored grouping result to the layer-aware type the slicing pipeline uses. +std::shared_ptr Print::get_layered_nozzle_group_result() const +{ + return std::dynamic_pointer_cast(m_nozzle_group_result); +} + +// Dynamic (per-layer selector) regroup predicate. +// Orca: enable_filament_dynamic_map is a project flag registered in the ConfigDef but NOT a static +// PrintConfig member, so it is read from the applied full config. No profile sets it; it is turned +// on per project by the "smart filament assign" checkbox (shown when a filament track switch is +// ready), so absent-key -> nullptr -> false keeps the static grouping path (identical output) for +// everything else. There is no mixed-colour-filament guard (mixed-colour filaments are not +// supported). The remaining gates (auto-for-flush mode, multi-extruder machine) read the static +// PrintConfig members. +bool Print::is_dynamic_group_reorder() const +{ + const auto *opt = m_full_print_config.option("enable_filament_dynamic_map"); + const bool enabled = opt && opt->value; + if (!enabled || m_config.filament_map_mode != FilamentMapMode::fmmAutoForFlush || m_config.nozzle_diameter.size() <= 1) + return false; + return true; +} + +int Print::get_filament_config_indx(int filament_id, int layer_id) +{ + return get_config_index(filament_id, layer_id, m_config.filament_extruder_variant.values, m_filament_self_index, m_filament_index_map); +} + +void Print::update_filament_self_index_cache() +{ + m_missing_nozzle_group_logged.clear(); // reset the per-slice get_config_index log dedupe + + std::vector values; + if (m_full_print_config.has("filament_self_index")) { + values = m_full_print_config.option("filament_self_index")->values; + } else if (m_ori_full_print_config.has("filament_self_index")) { + values = m_ori_full_print_config.option("filament_self_index")->values; + } else { + values = m_config.filament_self_index.values; + } + + size_t expected_size = m_config.filament_extruder_variant.values.size(); + m_filament_self_index.clear(); + if (expected_size == 0) { + m_filament_index_map.clear(); + m_nozzle_index_map.clear(); + return; + } + m_filament_self_index.resize(expected_size, 1); + if (!values.empty()) { + for (size_t i = 0; i < expected_size; ++i) { + int v = i < values.size() ? values[i] : 1; + if (v <= 0) + v = 1; + m_filament_self_index[i] = v; + } + } + m_filament_index_map.clear(); + m_nozzle_index_map.clear(); +} + +int Print::get_nozzle_config_index(int filament_id, int layer_id) +{ + // Orca: print_extruder_id/print_extruder_variant are PrintRegionConfig members in this codebase; + // the process-wide expanded values live in the default region config (regions never override them). + return get_config_index(filament_id, layer_id, m_default_region_config.print_extruder_variant.values, m_default_region_config.print_extruder_id.values, m_nozzle_index_map); +} + +int Print::get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap &index_map) +{ + auto group_result = get_layered_nozzle_group_result(); + // Orca: defensive — when no grouping producer has published a result yet, fall back to the + // static identity: one filament-variant column per filament. + if (!group_result) + return filament_id; + auto nozzle_info = group_result->get_nozzle_for_filament(filament_id, layer_id); + if (!nozzle_info.has_value()) { + // Orca: this fallback runs per-filament/per-layer in the g-code hot path — log once per filament + // (reset each slice) instead of flooding thousands of identical lines that bury the real error. + if (m_missing_nozzle_group_logged.insert(filament_id).second) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ + << boost::format(", Line %1%: could not found group_nozzle_info corresponding to filament_id %2%, layer_id %3% (further occurrences for this filament suppressed)") % __LINE__ % filament_id % + layer_id; + return 0; + } + + ExtruderType extruder_type = ExtruderType(m_config.extruder_type.get_at(nozzle_info->extruder_id)); + NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type; + + FilamentIndexKey key{filament_id, extruder_type, nozzle_volume_type}; + auto iter = index_map.find(key); + if (iter == index_map.end()) { + int index = get_config_index_base(nozzle_volume_type, extruder_type, filament_id + 1, variant_list, self_index_list); + index_map[key] = index; + return index; + } else { + return index_map[key]; + } +} + +int Print::get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, PrintIndexMap &index_map) +{ + auto group_result = get_layered_nozzle_group_result(); + // Orca: same static fallback as the filament overload; the slot degenerates to the filament's + // extruder column (filament_map is 1 based, get_extruder_id guards the filament id range). + if (!group_result) + return (int)get_extruder_id(filament_id); + auto nozzle_info = group_result->get_nozzle_for_filament(filament_id, layer_id); + if (!nozzle_info.has_value()) { + // Orca: this fallback runs per-filament/per-layer in the g-code hot path — log once per filament + // (reset each slice) instead of flooding thousands of identical lines that bury the real error. + if (m_missing_nozzle_group_logged.insert(filament_id).second) + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ + << boost::format(", Line %1%: could not found group_nozzle_info corresponding to filament_id %2%, layer_id %3% (further occurrences for this filament suppressed)") % __LINE__ % filament_id % + layer_id; + return 0; + } + + int extruder_id = nozzle_info->extruder_id + 1; // to 1 based + ExtruderType extruder_type = ExtruderType(m_config.extruder_type.get_at(nozzle_info->extruder_id)); + NozzleVolumeType nozzle_volume_type = nozzle_info->volume_type; + + PrintIndexKey key{filament_id, extruder_id, extruder_type, nozzle_volume_type}; + auto iter = index_map.find(key); + if (iter == index_map.end()) { + int index = get_config_index_base(nozzle_volume_type, extruder_type, extruder_id, variant_list, self_index_list); + index_map[key] = index; + return index; + } else { + return index_map[key]; + } +} + // Wipe tower support. bool Print::has_wipe_tower() const { @@ -3466,6 +3940,14 @@ void Print::_make_wipe_tower() m_wipe_tower_data.tool_ordering.empty() ? 0.f : m_wipe_tower_data.tool_ordering.back().print_z, m_wipe_tower_data.tool_ordering.all_extruders()); wipe_tower.set_has_tpu_filament(this->has_tpu_filament()); wipe_tower.set_filament_map(this->get_filament_maps()); + // Feed the has_filament_switcher device flag (develop-only dynamic key, read defensively from + // the full config — no shipping profile sets it) and the shared printable bed used by the PETG + // pre-extrusion offset clamp. Both are inert unless has_filament_switcher is set. + { + const ConfigOptionBool* hfs = m_full_print_config.option("has_filament_switcher"); + wipe_tower.set_has_filament_switcher(hfs && hfs->value); + } + wipe_tower.set_shared_print_bed(this->get_extruder_shared_printable_polygon()); // Set the extruder & material properties at the wipe tower object. for (size_t i = 0; i < number_of_extruders; ++i) wipe_tower.set_extruder(i, m_config); @@ -3517,7 +3999,10 @@ void Print::_make_wipe_tower() float volume_to_purge = 0; if (pre_filament_id != (unsigned int)(-1) && pre_filament_id != filament_id) { volume_to_purge = multi_extruder_flush[nozzle_id][pre_filament_id][filament_id]; - volume_to_purge *= m_config.flush_multiplier.get_at(nozzle_id); + // Fast purge mode uses flush_multiplier_fast; Default is inert. + float flush_multiplier = (m_config.prime_volume_mode == PrimeVolumeMode::pvmFast) ? m_config.flush_multiplier_fast.get_at(nozzle_id) + : m_config.flush_multiplier.get_at(nozzle_id); + volume_to_purge *= flush_multiplier; volume_to_purge = pre_filament_id == -1 ? 0 : layer_tools.wiping_extrusions().mark_wiping_extrusions(*this, current_filament_id, filament_id, volume_to_purge); } @@ -3526,8 +4011,10 @@ void Print::_make_wipe_tower() float grab_purge_volume = m_config.grab_length.get_at(nozzle_id) * 2.4; //(diameter/2)^2*PI=2.4 volume_to_purge = std::max(0.f, volume_to_purge - grab_purge_volume); + // Saving mode reduces the prime volume to 15 mm3; Default is inert. + float prime_volume = (m_config.prime_volume_mode == PrimeVolumeMode::pvmSaving) ? 15.f : (float) m_config.prime_volume; wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id, - m_config.prime_volume, volume_to_purge); + prime_volume, volume_to_purge); current_filament_id = filament_id; nozzle_cur_filament_ids[nozzle_id] = filament_id; } @@ -3781,10 +4268,20 @@ void Print::export_gcode_from_previous_file(const std::string& file, GCodeProces GCodeProcessor::s_IsBBLPrinter = is_BBL_printer(); const Vec3d origin = this->get_plate_origin(); processor.set_xy_offset(origin(0), origin(1)); + // Reloaded sliced projects re-estimate with the same nozzle-grouping slot context as the + // original export; process_file re-derives the device-side nozzle grouping onto the result + // (via ensure_nozzle_group_result), so the multi-nozzle send/monitor mapping survives here. + if (result != nullptr && result->nozzle_group_result) + processor.initialize_from_context(result->nozzle_group_result); //processor.enable_producers(true); processor.process_file(file); + // filament seq is loaded from file, processor result will override the value + auto filament_seq_loaded = result->filament_change_sequence; + auto nozzle_seq_loaded = result->nozzle_change_sequence; *result = std::move(processor.extract_result()); + result->filament_change_sequence = filament_seq_loaded; + result->nozzle_change_sequence = nozzle_seq_loaded; } catch (std::exception & /* ex */) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(": found errors when process gcode file %1%") %file.c_str(); throw Slic3r::RuntimeError( diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index b9f70506fb..bda0804b3a 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -23,6 +23,7 @@ #include #include +#include #include "calib.hpp" @@ -38,6 +39,7 @@ class SupportLayer; class TreeSupportData; class TreeSupport; class ExtrusionLayers; +namespace MultiNozzleUtils { class NozzleGroupResultBase; class LayeredNozzleGroupResult; } #define MAX_OUTER_NOZZLE_DIAMETER 4 // BBS: move from PrintObjectSlice.cpp @@ -418,7 +420,7 @@ public: // (layer height, first layer height, raft settings, print nozzle diameter etc). const SlicingParameters& slicing_parameters() const { return m_slicing_params; } // Orca: XYZ shrinkage compensation has introduced the const Vec3d &object_shrinkage_compensation parameter to the function below - static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation); + static SlicingParameters slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation, std::vector variant_index = std::vector()); size_t num_printing_regions() const throw() { return m_shared_regions->all_regions.size(); } const PrintRegion& printing_region(size_t idx) const throw() { return *m_shared_regions->all_regions[idx].get(); } @@ -489,7 +491,7 @@ public: // If ! m_slicing_params.valid, recalculate. void update_slicing_parameters(); - static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders); + static PrintObjectConfig object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders, std::vector& variant_index); private: void make_perimeters(); @@ -772,6 +774,7 @@ struct WipeTowerData number_of_toolchanges = -1; depth = 0.f; brim_width = 0.f; + height = 0.f; rib_offset = Vec2f::Zero(); wipe_tower_mesh_data = std::nullopt; } @@ -1003,15 +1006,50 @@ public: const WipeTowerData& wipe_tower_data(size_t filaments_cnt = 0) const; const ToolOrdering& tool_ordering() const { return m_tool_ordering; } - void update_filament_maps_to_config(std::vector f_maps); + void update_filament_maps_to_config(std::vector f_maps, std::vector f_volume_maps = std::vector{}, std::vector f_nozzle_maps = std::vector{}); + // Write-back for a selector (per-layer planned) grouping result. When a filament actually + // migrates between nozzle variants, rebuilds the per-slot filament arrays so it holds one + // slot per variant and recomputes the extruder retract overrides against the expanded + // slots — update_filament_maps_to_config's single-slot rebuild cannot represent a + // migration. A result without migration reduces to a single grouping and takes the + // three-map write-back like the static paths. + void update_to_config_by_nozzle_group_result(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result); void apply_config_for_render(const DynamicConfig &config); // 1 based group ids std::vector get_filament_maps() const; FilamentMapMode get_filament_map_mode() const; + std::vector get_filament_volume_maps() const; + std::vector get_filament_nozzle_maps() const; // get the group label of filament size_t get_extruder_id(unsigned int filament_id) const; + // The region every extruder can reach, + // i.e. the intersection of all per-extruder printable areas. Falls back to the full printable_area + // for single-nozzle printers and whenever extruder_printable_area is not populated (all current + // single/dual profiles), so the wipe-tower-center clamp is byte-identical to full-bed clamping there. + Polygons get_extruder_shared_printable_polygon() const; + + // Logical (extruder, nozzle) grouping result produced by ToolOrdering during reorder. + // Consumed by GCode via get_layered_nozzle_group_result()->get_nozzle_id(filament, layer) etc. + void set_nozzle_group_result(std::shared_ptr result) { m_nozzle_group_result = result; } + std::shared_ptr get_nozzle_group_result() const { return m_nozzle_group_result; } + std::shared_ptr get_layered_nozzle_group_result() const; + + // True only when the project opts into the per-layer filament selector + // (enable_filament_dynamic_map) in auto-for-flush mode on a multi-extruder machine. Gates the + // dynamic (per-layer) regroup branch in ToolOrdering::reorder_extruders_for_minimum_flush_volume, + // the sequential (by-object) plan stitching in Print::process, and GCode's use of the cached + // sequential plans. No profile sets the flag, so the static grouping path (byte-identical + // output) is the only one taken unless the user enables the selector. + bool is_dynamic_group_reorder() const; + + // Per-object tool orderings planned by the sequential (by-object) selector regroup with + // cross-object nozzle-status threading. GCode export must consume these exact plans: a fresh + // per-object construction would re-plan from a different seed and diverge from the published + // stitched result. Empty on the static path. + const std::map& sequential_dynamic_orderings() const { return m_sequential_dynamic_orderings; } + const std::vector>& get_extruder_filament_info() const { return m_extruder_filament_info; } void set_extruder_filament_info(const std::vector>& filament_info) { m_extruder_filament_info = filament_info; } @@ -1037,6 +1075,18 @@ public: */ std::vector> get_physical_unprintable_filaments(const std::vector& used_filaments) const; + /** + * @brief Determines the forbidden nozzle volume types for each used filament + * + * A filament may declare the extruder variants it supports. Every volume type offered by the + * printer's extruders that the filament does not support is forbidden for that filament. + * Hybrid volumes are ignored on both sides, and filaments declaring no variants are unrestricted. + * + * @param used_filaments Totally used filaments when slicing + * @return A map from used filament index to the set of nozzle volume types it cannot print on + */ + std::map> get_filament_unprintable_flow(const std::vector &used_filaments) const; + std::vector get_extruder_printable_height() const; std::vector get_extruder_printable_polygons() const; std::vector get_extruder_unprintable_polygons() const; @@ -1120,7 +1170,12 @@ public: bool is_all_objects_are_short() const { return std::all_of(this->objects().begin(), this->objects().end(), [&](PrintObject* obj) { return obj->height() < scale_(this->config().nozzle_height.value); }); } - + + // Post-slicing config-slot resolvers: map a (filament, layer) pair to the index of its + // per-(extruder x volume type) column in the expanded variant arrays, cached by grouping context. + int get_filament_config_indx(int filament_id, int layer_id); + int get_nozzle_config_index(int filament_id, int layer_id); + // Orca: Implement prusa's filament shrink compensation approach // Returns if all used filaments have same shrinkage compensations. bool has_same_shrinkage_compensations() const; @@ -1130,6 +1185,57 @@ public: std::tuple object_skirt_offset(double margin_height = 0) const; protected: + struct FilamentIndexKey + { + int filament_id; + ExtruderType extruder; + NozzleVolumeType nozzle_volume_type; + + bool operator==(const FilamentIndexKey &other) const + { + return filament_id == other.filament_id && extruder == other.extruder && nozzle_volume_type == other.nozzle_volume_type; + } + }; + + struct PrintIndexKey + { + int filament_id; + int extruder_id; + ExtruderType extruder; + NozzleVolumeType nozzle_volume_type; + + bool operator==(const PrintIndexKey &other) const + { + return filament_id == other.filament_id && extruder_id == other.extruder_id && extruder == other.extruder && nozzle_volume_type == other.nozzle_volume_type; + } + }; + + struct FilamentIndexKeyHash + { + std::size_t operator()(const FilamentIndexKey &k) const + { + size_t h1 = std::hash{}(k.filament_id); + size_t h2 = std::hash{}(static_cast(k.extruder)); + size_t h3 = std::hash{}(static_cast(k.nozzle_volume_type)); + return h1 ^ (h2 << 8) ^ (h3 << 12); + } + }; + struct PrintIndexKeyHash + { + std::size_t operator()(const PrintIndexKey &k) const + { + size_t h1 = std::hash{}(k.filament_id); + size_t h2 = std::hash{}(k.extruder_id); + size_t h3 = std::hash{}(static_cast(k.extruder)); + size_t h4 = std::hash{}(static_cast(k.nozzle_volume_type)); + return h1 ^ (h2 << 8) ^ (h3 << 12) ^ (h4 << 16); + } + }; + using FilamentIndexMap = std::unordered_map; + using PrintIndexMap = std::unordered_map; + int get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, FilamentIndexMap &index_map); + int get_config_index(int filament_id, int layer_id, const std::vector &variant_list, const std::vector& self_index_list, PrintIndexMap &index_map); + // Invalidates the step, and its depending steps in Print. bool invalidate_step(PrintStep step); @@ -1143,6 +1249,16 @@ private: void _make_skirt(); void _make_wipe_tower(); void finalize_first_layer_convex_hull(); + void update_filament_self_index_cache(); + // Deduplicates, per filament, the (extruder type x volume type) variants the grouping + // result routes it through; filaments the plan never routes get their default-map + // assignment so the slot resolution never depends on the (mutable) filament_map. config + // must carry extruder_type; returns false when it does not. Both the slice-time write-back + // and the apply-time reproduction call this with m_ori_full_print_config so the two + // expansions resolve identical slots. + bool collect_filament_variant_uses(const MultiNozzleUtils::LayeredNozzleGroupResult& group_result, + const DynamicPrintConfig& config, + std::unordered_map>& uses) const; // Islands of objects and their supports extruded at the 1st layer. Polygons first_layer_islands() const; @@ -1176,6 +1292,24 @@ private: std::vector> m_extruder_filament_info; + // Logical (extruder, nozzle) grouping result, set by ToolOrdering during reorder. + std::shared_ptr m_nozzle_group_result; + + // Sequential (by-object) selector plans, keyed by object; see sequential_dynamic_orderings(). + // Rebuilt (or cleared) on every process(). + std::map m_sequential_dynamic_orderings; + + // Used to cache filament parameter information + FilamentIndexMap m_filament_index_map; + // Used to cache printer and process parameter information + PrintIndexMap m_nozzle_index_map; + // Orca: filament ids already reported as missing a nozzle-group entry this slice. get_config_index() + // falls back per-filament/per-layer in the g-code hot path, so this dedupes its log to once per + // filament instead of flooding thousands of identical error lines. Cleared with the caches each slice. + std::set m_missing_nozzle_group_logged; + // save the config value of "filament_self_index" + std::vector m_filament_self_index; + // Following section will be consumed by the GCodeGenerator. ToolOrdering m_tool_ordering; WipeTowerData m_wipe_tower_data {m_tool_ordering}; diff --git a/src/libslic3r/PrintApply.cpp b/src/libslic3r/PrintApply.cpp index 0678f75277..0956cfe154 100644 --- a/src/libslic3r/PrintApply.cpp +++ b/src/libslic3r/PrintApply.cpp @@ -224,7 +224,11 @@ static t_config_option_keys print_config_diffs( const DynamicPrintConfig &new_full_config, DynamicPrintConfig &filament_overrides, int plate_index, - std::vector& filament_maps) + std::vector& filament_maps, + // Per-slot machine indices when the filament arrays hold the per-variant expansion of a + // selector result (one slot per variant a filament migrates through); the per-filament + // map cannot index the expanded override arrays. Null on the single-slot path. + const std::vector* dynamic_override_indices = nullptr) { const std::vector &extruder_retract_keys = print_config_def.extruder_retract_keys(); const std::string filament_prefix = "filament_"; @@ -240,7 +244,15 @@ static t_config_option_keys print_config_diffs( const ConfigOption *opt_new_filament = std::binary_search(extruder_retract_keys.begin(), extruder_retract_keys.end(), opt_key) ? new_full_config.option(filament_prefix + opt_key) : nullptr; if (opt_new_filament != nullptr) { - compute_filament_override_value(opt_key, opt_old, opt_new, opt_new_filament, new_full_config, print_diff, filament_overrides, filament_maps); + std::vector filament_map_indices; + if (dynamic_override_indices) + filament_map_indices = *dynamic_override_indices; + else { + filament_map_indices.assign(filament_maps.size(), 0); + for (int i = 0; i < filament_maps.size(); i++) + filament_map_indices[i] = filament_maps[i] - 1; + } + compute_filament_override_value(opt_key, opt_old, opt_new, opt_new_filament, new_full_config, print_diff, filament_overrides, filament_map_indices); } else if (*opt_new != *opt_old) { //BBS: add plate_index logic for wipe_tower_x/wipe_tower_y if (!opt_key.compare("wipe_tower_x") || !opt_key.compare("wipe_tower_y")) { @@ -724,7 +736,7 @@ PrintObjectRegions::BoundingBox find_modifier_volume_extents(const PrintObjectRe return out; } -PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders); +PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders, std::vector& variant_index); void print_region_ref_inc(PrintRegion &r) { ++ r.m_ref_cnt; } void print_region_ref_reset(PrintRegion &r) { r.m_ref_cnt = 0; } @@ -738,7 +750,8 @@ bool verify_update_print_object_regions( const PrintRegionConfig &default_region_config, size_t num_extruders, PrintObjectRegions &print_object_regions, - const std::function &callback_invalidate) + const std::function &callback_invalidate, + std::vector& variant_index) { // Sort by ModelVolume ID. model_volumes_sort_by_id(model_volumes); @@ -783,7 +796,7 @@ bool verify_update_print_object_regions( } else if (PrintObjectRegions::BoundingBox parent_bbox = find_modifier_volume_extents(layer_range, parent_region_id); parent_bbox.intersects(*bbox)) // Such parent region does not exist. If it is needed, then we need to reslice. // Only create new region for a modifier, which actually modifies config of it's parent. - if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, **it_model_volume, num_extruders); + if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, **it_model_volume, num_extruders, variant_index); config != parent_region.region->config()) // This modifier newly overrides a region, which it did not before. We need to reslice. return false; @@ -791,8 +804,8 @@ bool verify_update_print_object_regions( } } PrintRegionConfig cfg = region.parent == -1 ? - region_config_from_model_volume(default_region_config, layer_range.config, **it_model_volume, num_extruders) : - region_config_from_model_volume(layer_range.volume_regions[region.parent].region->config(), nullptr, **it_model_volume, num_extruders); + region_config_from_model_volume(default_region_config, layer_range.config, **it_model_volume, num_extruders, variant_index) : + region_config_from_model_volume(layer_range.volume_regions[region.parent].region->config(), nullptr, **it_model_volume, num_extruders, variant_index); if (cfg != region.region->config()) { // Region configuration changed. if (print_region_ref_cnt(*region.region) == 0) { @@ -964,6 +977,7 @@ static PrintObjectRegions* generate_print_object_regions( size_t num_extruders, const float xy_contour_compensation, const std::vector &painting_extruders, + std::vector &variant_index, const bool has_painted_fuzzy_skin) { // Reuse the old object or generate a new one. @@ -1022,7 +1036,7 @@ static PrintObjectRegions* generate_print_object_regions( // Add a model volume, assign an existing region or generate a new one. layer_range.volume_regions.push_back({ &volume, -1, - get_create_region(region_config_from_model_volume(default_region_config, layer_range.config, volume, num_extruders)), + get_create_region(region_config_from_model_volume(default_region_config, layer_range.config, volume, num_extruders, variant_index)), bbox }); } else if (volume.is_negative_volume()) { @@ -1039,7 +1053,7 @@ static PrintObjectRegions* generate_print_object_regions( if (parent_volume.is_model_part() || parent_volume.is_modifier()) if (PrintObjectRegions::BoundingBox parent_bbox = find_modifier_volume_extents(layer_range, parent_region_id); parent_bbox.intersects(*bbox)) { // Only create new region for a modifier, which actually modifies config of it's parent. - if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, volume, num_extruders); + if (PrintRegionConfig config = region_config_from_model_volume(parent_region.region->config(), nullptr, volume, num_extruders, variant_index); config != parent_region.region->config()) { added = true; layer_range.volume_regions.push_back({ &volume, parent_region_id, get_create_region(std::move(config)), bbox }); @@ -1162,25 +1176,58 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ } //apply extruder related values + std::vector print_variant_index; + std::vector> nozzle_volume_types; + int extruder_count = 1, extruder_volume_type_count = 1; + bool different_extruder = false; + // Filled only when the filament arrays are rebuilt from a persisted selector result below; + // print_config_diffs then keys the retract overrides per expanded slot. + std::vector dynamic_slot_indices; + + different_extruder = new_full_config.support_different_extruders(extruder_count); + extruder_volume_type_count = new_full_config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); if (!extruder_applied) { - // variant_2 must be processed first, because variant_1 will make `printer_extruder_id` and `printer_extruder_variant` half of the size that makes `get_index_for_extruder` no longer work properly - new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); - new_full_config.update_values_to_printer_extruders(new_full_config, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); - //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_count > 1) || different_extruder) { + // variant_2 must be processed first, because variant_1 will make `printer_extruder_id` and `printer_extruder_variant` half of the size that makes `get_index_for_extruder` no longer work properly + new_full_config.update_values_to_printer_extruders(new_full_config, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); + new_full_config.update_values_to_printer_extruders(new_full_config, extruder_count, extruder_volume_type_count, nozzle_volume_types, printer_options_with_variant_1, "printer_extruder_id", "printer_extruder_variant"); + //update print config related with variants + print_variant_index = new_full_config.update_values_to_printer_extruders(new_full_config, extruder_count, extruder_volume_type_count, nozzle_volume_types, print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + } + else + print_variant_index.resize(1, 0); 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"); + + std::set filament_keys = filament_options_with_variant; + filament_keys.insert("filament_self_index"); + // A persisted selector result with an actual migration means the last slice rebuilt the + // per-slot filament arrays from it (one slot per variant a filament prints through). + // Reproduce that exact expansion here so an unchanged config diffs empty — the expanded + // keys invalidate the wipe tower / g-code export, and the placeholder parser aliases + // the full config — instead of trimming back to one slot per filament. + auto group_result = std::dynamic_pointer_cast(this->get_nozzle_group_result()); + std::unordered_map> filament_variant_uses; + if (group_result && group_result->is_support_dynamic_nozzle_map() + && collect_filament_variant_uses(*group_result, m_ori_full_print_config, filament_variant_uses)) + new_full_config.update_filament_config_values_for_multiple_extruders(m_ori_full_print_config, filament_variant_uses, + extruder_count, extruder_volume_type_count, filament_keys, + "filament_self_index", "filament_extruder_variant", + &dynamic_slot_indices); + else if ((extruder_count > 1) || different_extruder) + new_full_config.update_values_to_printer_extruders_for_multiple_filaments(m_ori_full_print_config, extruder_count, extruder_volume_type_count, filament_keys, + "filament_self_index", "filament_extruder_variant"); + } + else { + //should not come here, we can not get the result of print_variant, for the values have been updated + //we just use the default values here + auto variant_opt = dynamic_cast(new_full_config.option("printer_extruder_variant")); + print_variant_index.resize(variant_opt->values.size()); + for (int e_index = 0; e_index < variant_opt->values.size(); e_index++) + { + print_variant_index[e_index] = e_index; + } } - // 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; - // } - // } auto opt_filament_map = new_full_config.option("filament_map"); std::vector filament_maps = opt_filament_map ? opt_filament_map->values : std::vector(); @@ -1188,7 +1235,15 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // Find modified keys of the various configs. Resolve overrides extruder retract values by filament profiles. DynamicPrintConfig filament_overrides; //BBS: add plate index - t_config_option_keys print_diff = print_config_diffs(m_config, new_full_config, filament_overrides, this->m_plate_index, filament_maps); + t_config_option_keys print_diff = print_config_diffs(m_config, new_full_config, filament_overrides, this->m_plate_index, filament_maps, + dynamic_slot_indices.empty() ? nullptr : &dynamic_slot_indices); + // Orca: filament_map_2 is engine-derived state, never a user input: the rebuild below + // recomputes it from filament_map/filament_volume_map/the variant slots on every apply + // (all of which are diffed and invalidation-listed on their own), and the grouping + // write-back overwrites it during process(). The incoming full config only ever carries + // the ConfigDef default, so diffing it would invalidate every print step on each apply + // for any multi-extruder printer and permanently invalidate fresh slice results. + print_diff.erase(std::remove(print_diff.begin(), print_diff.end(), "filament_map_2"), print_diff.end()); t_config_option_keys full_config_diff = full_print_config_diffs(m_full_print_config, new_full_config, this->m_plate_index); // Collect changes to object and region configs. t_config_option_keys object_diff = m_default_object_config.diff(new_full_config); @@ -1196,10 +1251,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ //BBS: process the filament_map related logic std::unordered_set print_diff_set(print_diff.begin(), print_diff.end()); - if (print_diff_set.find("filament_map_mode") == print_diff_set.end()) + if (!print_diff_set.empty() && print_diff_set.find("filament_map_mode") == print_diff_set.end()) { FilamentMapMode map_mode = new_full_config.option>("filament_map_mode", true)->value; - if (map_mode < fmmManual) { + if (is_auto_filament_map_mode(map_mode)) { if (print_diff_set.find("filament_map") != print_diff_set.end()) { print_diff_set.erase("filament_map"); //full_config_diff.erase("filament_map"); @@ -1208,9 +1263,29 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ old_opt->set(new_opt); m_config.filament_map = *new_opt; } + if (print_diff_set.find("filament_volume_map") != print_diff_set.end()) { + print_diff_set.erase("filament_volume_map"); + //full_config_diff.erase("filament_volume_map"); + ConfigOptionInts* old_opt = m_full_print_config.option("filament_volume_map", true); + ConfigOptionInts* new_opt = new_full_config.option("filament_volume_map", true); + old_opt->set(new_opt); + m_config.filament_volume_map = *new_opt; + } + if (print_diff_set.find("filament_nozzle_map") != print_diff_set.end()) { + print_diff_set.erase("filament_nozzle_map"); + //full_config_diff.erase("filament_nozzle_map"); + ConfigOptionInts* old_opt = m_full_print_config.option("filament_nozzle_map", true); + ConfigOptionInts* new_opt = new_full_config.option("filament_nozzle_map", true); + old_opt->set(new_opt); + m_config.filament_nozzle_map = *new_opt; + } } else { print_diff_set.erase("extruder_ams_count"); + if (map_mode == fmmManual) { + // filament_nozzle_map is an engine output, not a GUI input, in manual mode + print_diff_set.erase("filament_nozzle_map"); + } std::vector old_filament_map = m_config.filament_map.values; std::vector new_filament_map = new_full_config.option("filament_map", true)->values; @@ -1227,14 +1302,62 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ break; } } - if (same_map) + if (same_map) { print_diff_set.erase("filament_map"); + + // The extruder retract overrides are keyed by the (unchanged) filament map; + // recompute them and drop diffs whose recomputed value matches the current + // config, so a cosmetic reordering of unused filaments does not invalidate. + const auto& retract_keys = print_config_def.extruder_retract_keys(); + const std::string filament_prefix = "filament_"; + std::vector old_f_map_indices(old_filament_map.size(), 0); + for (size_t i = 0; i < old_filament_map.size(); i++) + old_f_map_indices[i] = old_filament_map[i] - 1; + + for (const auto& rk : retract_keys) { + if (print_diff_set.find(rk) == print_diff_set.end()) + continue; + const ConfigOption* opt_old = m_config.option(rk); + const ConfigOption* opt_new_m = new_full_config.option(rk); + const ConfigOption* opt_new_f = new_full_config.option(filament_prefix + rk); + if (opt_old && opt_new_m && opt_new_f) { + std::unique_ptr opt_recomputed(opt_new_m->clone()); + opt_recomputed->apply_override(opt_new_f, old_f_map_indices); + if (*opt_old == *opt_recomputed) + print_diff_set.erase(rk); + } + } + } } } if (print_diff_set.size() != print_diff.size()) print_diff.assign(print_diff_set.begin(), print_diff_set.end()); } + //filament_map_2 + // Orca: seed with 0-based extruder indices so the copy stays a valid slot map even when the + // variant options are absent below and the rebuild loop is skipped (unit tests, degenerate + // presets); the loop overwrites every entry when it runs. + m_config.filament_map_2.values = filament_maps; + for (auto& v : m_config.filament_map_2.values) + --v; + auto opt_extruder_type = dynamic_cast(new_full_config.option("extruder_type")); + auto opt_filament_volume_maps = dynamic_cast(new_full_config.option("filament_volume_map")); + auto opt_nozzle_volume_type = dynamic_cast(new_full_config.option("nozzle_volume_type")); + for (int index = 0; opt_extruder_type && opt_nozzle_volume_type && index < filament_maps.size(); index++) + { + ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(filament_maps[index] - 1)); + NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(filament_maps[index] - 1)); + // Orca: honour the per-filament volume map only when a producer sized it to the filament + // count; mis-sized maps (stale project values, CLI runs until the per-filament synthesis + // lands there) must not be indexed per filament (see + // update_values_to_printer_extruders_for_multiple_filaments for the same guard). + if ((extruder_volume_type_count > extruder_count) && opt_filament_volume_maps + && opt_filament_volume_maps->values.size() == filament_maps.size()) + nozzle_volume_type = (NozzleVolumeType)(opt_filament_volume_maps->values[index]); + m_config.filament_map_2.values[index] = new_full_config.get_index_for_extruder(filament_maps[index], "print_extruder_id", extruder_type, nozzle_volume_type, "print_extruder_variant"); + } + // Do not use the ApplyStatus as we will use the max function when updating apply_status. unsigned int apply_status = APPLY_STATUS_UNCHANGED; auto update_apply_status = [&apply_status](bool invalidated) @@ -1282,6 +1405,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ m_default_region_config.apply_only(new_full_config, region_diff, true); //m_full_print_config = std::move(new_full_config); m_full_print_config = new_full_config; + update_filament_self_index_cache(); if (num_extruders != m_config.filament_diameter.size()) { num_extruders = m_config.filament_diameter.size(); num_extruders_changed = true; @@ -1475,7 +1599,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ if (object_config_changed) model_object.config.assign_config(model_object_new.config); if (! object_diff.empty() || object_config_changed || num_extruders_changed ) { - PrintObjectConfig new_config = PrintObject::object_config_from_model_object(m_default_object_config, model_object, num_extruders ); + PrintObjectConfig new_config = PrintObject::object_config_from_model_object(m_default_object_config, model_object, num_extruders, print_variant_index); for (const PrintObjectStatus &print_object_status : print_object_status_db.get_range(model_object)) { t_config_option_keys diff = print_object_status.print_object->config().diff(new_config); if (! diff.empty()) { @@ -1541,10 +1665,10 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ // Generate a list of trafos and XY offsets for instances of a ModelObject // Producing the config for PrintObject on demand, caching it at print_object_last. const PrintObject *print_object_last = nullptr; - auto print_object_apply_config = [this, &print_object_last, model_object, num_extruders ](PrintObject *print_object) { + auto print_object_apply_config = [this, &print_object_last, model_object, num_extruders, &print_variant_index](PrintObject *print_object) { print_object->config_apply(print_object_last ? print_object_last->config() : - PrintObject::object_config_from_model_object(m_default_object_config, *model_object, num_extruders )); + PrintObject::object_config_from_model_object(m_default_object_config, *model_object, num_extruders, print_variant_index)); print_object_last = print_object; }; if (old.empty()) { @@ -1654,7 +1778,14 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ m_default_object_config.apply_only(new_full_config, new_changed_keys, true); // Handle changes to regions config defaults m_default_region_config.apply_only(new_full_config, new_changed_keys, true); + // Orca: keep the pre-expansion snapshot in sync with this late normalization pass. + // The engine map write-back rebuilds m_full_print_config from m_ori_full_print_config + // after slicing; a stale snapshot would resurrect the un-normalized values (e.g. + // enable_prime_tower on a single-filament print) in the dumped config and spuriously + // re-invalidate the g-code on the next apply. + m_ori_full_print_config.apply_only(new_full_config, new_changed_keys, true); m_full_print_config = std::move(new_full_config); + update_filament_self_index_cache(); } // All regions now have distinct settings. @@ -1715,7 +1846,8 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ for (auto it = it_print_object; it != it_print_object_end; ++it) if ((*it)->m_shared_regions != nullptr) update_apply_status((*it)->invalidate_state_by_config_options(old_config, new_config, diff_keys)); - })) { + }, + print_variant_index)) { // Regions are valid, just keep them. } else { // Regions were reshuffled. @@ -1737,6 +1869,7 @@ Print::ApplyStatus Print::apply(const Model &model, DynamicPrintConfig new_full_ num_extruders , print_object.is_mm_painted() ? 0.f : float(print_object.config().xy_contour_compensation.value), painting_extruders, + print_variant_index, print_object.is_fuzzy_skin_painted()); } for (auto it = it_print_object; it != it_print_object_end; ++it) diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index dda24e4e5b..0e02ea1ec3 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -79,10 +79,22 @@ const std::vector filament_extruder_override_keys = { "filament_wipe", // percents "filament_retract_before_wipe", + // Orca + "filament_retract_after_wipe", + // BBS "filament_long_retractions_when_cut", "filament_retraction_distances_when_cut" }; +// Some filament override parameters are generated from filament_extruder_override_keys, +// while filament_retract_length_nc is defined separately. Keep the generator list +// unchanged and use this helper for behavior checks that need the full override set. +bool is_filament_extruder_override_key(const std::string &opt_key) +{ + return std::find(filament_extruder_override_keys.begin(), filament_extruder_override_keys.end(), opt_key) != filament_extruder_override_keys.end() || + opt_key == "filament_retract_length_nc"; +} + size_t get_extruder_index(const GCodeConfig& config, unsigned int filament_id) { if (filament_id < config.filament_map.size()) { @@ -188,6 +200,12 @@ static t_config_enum_values s_keys_map_PowerLossRecoveryMode { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PowerLossRecoveryMode) +static t_config_enum_values s_keys_map_CenterOfSurfacePattern{ + {"each_surface", int(CenterOfSurfacePattern::Each_Surface)}, + {"each_model", int(CenterOfSurfacePattern::Each_Model)}, + {"each_assembly", int(CenterOfSurfacePattern::Each_Assembly)}}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(CenterOfSurfacePattern) + static t_config_enum_values s_keys_map_FuzzySkinType { { "none", int(FuzzySkinType::None) }, { "external", int(FuzzySkinType::External) }, @@ -221,6 +239,13 @@ static t_config_enum_values s_keys_map_FuzzySkinMode { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FuzzySkinMode) +static t_config_enum_values s_keys_map_TopSurfaceExpansionDirection { + { "inward_and_outward", int(TopSurfaceExpansionDirection::InwardAndOutward) }, + { "inward", int(TopSurfaceExpansionDirection::Inward) }, + { "outward", int(TopSurfaceExpansionDirection::Outward) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TopSurfaceExpansionDirection) + static t_config_enum_values s_keys_map_InfillPattern { { "monotonic", ipMonotonic }, { "monotonicline", ipMonotonicLine }, @@ -288,6 +313,14 @@ static t_config_enum_values s_keys_map_WallDirection{ }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(WallDirection) +//Orca +static t_config_enum_values s_keys_map_SurfaceFillOrder{ + { "default", int(SurfaceFillOrder::Default) }, + { "outward", int(SurfaceFillOrder::Outward) }, + { "inward", int(SurfaceFillOrder::Inward) }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SurfaceFillOrder) + //BBS static t_config_enum_values s_keys_map_PrintSequence { { "by layer", int(PrintSequence::ByLayer) }, @@ -490,6 +523,14 @@ static t_config_enum_values s_keys_map_NozzleType { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NozzleType) +static t_config_enum_values s_keys_map_FanDirection { + { "undefine", int(FanDirection::fdUndefine) }, + { "left", int(FanDirection::fdLeft) }, + { "right", int(FanDirection::fdRight) }, + { "both", int(FanDirection::fdBoth) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FanDirection) + static t_config_enum_values s_keys_map_PrinterStructure { {"undefine", int(PrinterStructure::psUndefine)}, {"corexy", int(PrinterStructure::psCoreXY)}, @@ -522,6 +563,12 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType{ }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType) +static t_config_enum_values s_keys_map_ToolChangeOrderingType { + { "default", int(ToolChangeOrderingType::Default) }, + { "cyclic", int(ToolChangeOrderingType::Cyclic) } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ToolChangeOrderingType) + static const t_config_enum_values s_keys_map_ZHopType = { { "Auto Lift", zhtAuto }, { "Normal Lift", zhtNormal }, @@ -569,17 +616,28 @@ CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ExtruderType) static const t_config_enum_values s_keys_map_NozzleVolumeType = { { "Standard", nvtStandard }, - { "High Flow", nvtHighFlow } + { "High Flow", nvtHighFlow }, + { "TPU High Flow", nvtTPUHighFlow }, + { "Hybrid", nvtHybrid } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(NozzleVolumeType) static const t_config_enum_values s_keys_map_FilamentMapMode = { { "Auto For Flush", fmmAutoForFlush }, { "Auto For Match", fmmAutoForMatch }, - { "Manual", fmmManual } + { "Manual", fmmManual }, + { "Nozzle Manual", fmmNozzleManual } }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FilamentMapMode) +// PrimeVolumeMode. Serialized string keys must stay stable; they round-trip through .3mf. +static const t_config_enum_values s_keys_map_PrimeVolumeMode = { + { "Default", pvmDefault }, + { "Saving", pvmSaving }, + { "Fast", pvmFast } +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PrimeVolumeMode) + //BBS std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type) @@ -591,7 +649,8 @@ std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolume //extruder_type = etDirectDrive; return variant_string; } - if (nozzle_volume_type > nvtMaxNozzleVolumeType) { + auto nozzle_volume_types = get_valid_nozzle_volume_type(); + if (nozzle_volume_types.count(nozzle_volume_type) == 0) { BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", unsupported NozzleVolumeType=%1%")%nozzle_volume_type; //extruder_type = etDirectDrive; return variant_string; @@ -602,6 +661,16 @@ std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolume return variant_string; } +int get_config_index_base(NozzleVolumeType volume_type, ExtruderType extruder_type, int variant_id_1based, const std::vector& variant_list, const std::vector& variant_ids_1based) +{ + assert(variant_list.size() == variant_ids_1based.size()); + std::string extruder_variant = get_extruder_variant_string(extruder_type, volume_type); + for (int index = 0; index < int(variant_list.size()); ++index) { + if (extruder_variant == variant_list[index] && variant_ids_1based[index] == variant_id_1based) { return index; } + } + return 0; +} + std::string get_nozzle_volume_type_string(NozzleVolumeType nozzle_volume_type) { if (nozzle_volume_type > nvtMaxNozzleVolumeType) { @@ -650,6 +719,89 @@ std::vector save_extruder_ams_count_to_string(const std::vector::get_enum_names(); + + auto trim = [](std::string &s) { + s.erase(s.find_last_not_of(" \t\r\n") + 1); + s.erase(0, s.find_first_not_of(" \t\r\n")); + }; + + for (auto ext_type : ext_types) { + size_t pos = variant_str.find(ext_type); + if (pos == std::string::npos) + continue; + + std::string result = variant_str; + result.erase(pos, ext_type.size()); + trim(result); + + auto iter = s_keys_map_NozzleVolumeType.find(result); + if (iter != s_keys_map_NozzleVolumeType.end()) + return NozzleVolumeType(iter->second); + } + + return nvtHybrid; +} + +// Parses the extruder_nozzle_stats option: one "|"-separated token list per +// extruder, each token +// "#". Empty string => no per-type stats for that extruder. +std::vector> get_extruder_nozzle_stats(const std::vector &strs) +{ + std::vector> extruder_nozzle_counts; + for (const std::string &str : strs) { + std::map nozzle_count_map; + if (str.empty()) { + extruder_nozzle_counts.emplace_back(nozzle_count_map); + continue; + } + std::vector nozzle_infos; + boost::algorithm::split(nozzle_infos, str, boost::algorithm::is_any_of("|")); + for (auto &nozzle_info : nozzle_infos) { + std::vector attr; + boost::algorithm::split(attr, nozzle_info, boost::algorithm::is_any_of("#")); + // Guard against malformed device/project data: skip tokens without a "#" + // shape or with an unknown volume-type key instead of throwing (.at) or reading attr[1] + // out of bounds. Corrupt tokens are dropped and logged; the rest still parse. + if (attr.size() < 2) { + BOOST_LOG_TRIVIAL(warning) << "get_extruder_nozzle_stats: skipping malformed token '" << nozzle_info << "'"; + continue; + } + auto it = s_keys_map_NozzleVolumeType.find(attr[0]); + if (it == s_keys_map_NozzleVolumeType.end()) { + BOOST_LOG_TRIVIAL(warning) << "get_extruder_nozzle_stats: skipping unknown nozzle volume type '" << attr[0] << "'"; + continue; + } + NozzleVolumeType volume_type = NozzleVolumeType(it->second); + int nozzle_count = std::atoi(attr[1].c_str()); + nozzle_count_map[volume_type] = nozzle_count; + } + extruder_nozzle_counts.emplace_back(nozzle_count_map); + } + return extruder_nozzle_counts; +} + +std::vector save_extruder_nozzle_stats_to_string(const std::vector> &extruder_nozzle_stats) +{ + std::vector extruder_nozzle_count_str; + for (size_t idx = 0; idx < extruder_nozzle_stats.size(); ++idx) { + std::ostringstream oss; + const auto &item = extruder_nozzle_stats[idx]; + for (auto it = item.begin(); it != item.end(); ++it) { + oss << get_nozzle_volume_type_string(it->first) << "#" << it->second; + if (std::next(it) != item.end()) + oss << "|"; + } + extruder_nozzle_count_str.emplace_back(oss.str()); + } + return extruder_nozzle_count_str; +} + static void assign_printer_technology_to_unknown(t_optiondef_map &options, PrinterTechnology printer_technology) { for (std::pair &kvp : options) @@ -1236,7 +1388,7 @@ void PrintConfigDef::init_fff_params() "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" - " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" + " - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n\n" "Use 180° for zero absolute angle."); def->sidetext = u8"°"; // degrees, don't need translation @@ -1253,7 +1405,7 @@ void PrintConfigDef::init_fff_params() "If left to zero, the bridging angle will be calculated automatically for each specific bridge.\n" "Otherwise the provided angle will be used according to:\n" " - The absolute coordinates\n" - " - The absolute coordinates + Model rotation: If Align infill direction to model is enabled\n" + " - The absolute coordinates + Model rotation: If Align directions to model is enabled\n" " - The optimal automatic angle + this value: If 'Relative Bridge Angle' is enabled\n\n" "Use 180° for zero absolute angle."); def->sidetext = u8"°"; // degrees, don't need translation @@ -1865,7 +2017,7 @@ void PrintConfigDef::init_fff_params() def = this->add("initial_layer_travel_acceleration", coFloatsOrPercents); def->label = L("First layer travel"); def->tooltip = L("Travel acceleration of first layer.\nThe percentage value is relative to Travel Acceleration."); - def->sidetext = L("mm/s² or %"); + def->sidetext = L(u8"mm/s² or %"); def->min = 0; def->mode = comAdvanced; def->ratio_over = "travel_acceleration"; @@ -1876,7 +2028,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Bridge"); def->category = L("Speed"); def->tooltip = L("Acceleration of bridges. If the value is expressed as a percentage (e.g. 50%), it will be calculated based on the outer wall acceleration."); - def->sidetext = L("mm/s² or %"); + def->sidetext = L(u8"mm/s² or %"); def->min = 0; def->mode = comAdvanced; def->ratio_over = "outer_wall_acceleration"; @@ -2117,6 +2269,47 @@ void PrintConfigDef::init_fff_params() def->max = 100; def->set_default_value(new ConfigOptionPercent(100)); + def = this->add("top_surface_expansion", coFloat); + def->label = L("Top surface expansion"); + def->category = L("Strength"); + def->tooltip = L("Expands the top surfaces by this distance to connect distinct top surfaces and fill gaps.\n" + "Useful for cases where the top surface is interrupted by a raised feature, such as text on a plane." + "Expanding it removes the holes beneath these features and creates a continuous path with a better finish for printing on top." + "The expansion is applied to the original top surface, before any other processing such as bridging or overhang detection."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("top_surface_expansion_margin", coFloat); + def->label = L("Top expansion wall margin"); + def->category = L("Strength"); + def->tooltip = L("Using “Top surface expansion” may cause a surface that did not previously touch the model's outer walls to now do so.\n" + "This can cause contraction marks (such as the hull line) on the outer walls.\n" + "By adding a small margin, this contraction will not occur directly on the walls, thereby preventing a visible mark."); + def->sidetext = L("mm"); + def->min = 0; + def->max = 10; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("top_surface_expansion_direction", coEnum); + def->label = L("Top expansion direction"); + def->category = L("Strength"); + def->tooltip = L("Direction in which the top surface expansion grows.\n" + " - Inward grows into the holes and gaps left by features rising from the middle of a top surface.\n" + " - Outward grows the outer edge of the surface, connecting surfaces separated by features that can divide a surface, such as a lattice pattern.\n" + " - Inward and Outward does both."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("inward_and_outward"); + def->enum_values.push_back("inward"); + def->enum_values.push_back("outward"); + def->enum_labels.push_back(L("Inward and Outward")); + def->enum_labels.push_back(L("Inward")); + def->enum_labels.push_back(L("Outward")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(TopSurfaceExpansionDirection::InwardAndOutward)); + def = this->add("bottom_surface_pattern", coEnum); def->label = L("Bottom surface pattern"); def->category = L("Strength"); @@ -2137,6 +2330,40 @@ void PrintConfigDef::init_fff_params() def->max = 100; def->set_default_value(new ConfigOptionPercent(100)); + auto def_top_fill_order = def = this->add("top_surface_fill_order", coEnum); + def->label = L("Top surface fill order"); + def->category = L("Strength"); + def->tooltip = L("Direction in which top surfaces are filled when using a center-based pattern " + "(Concentric, Archimedean Chords, Octagram Spiral).\n" + "Outward starts at the center of the surface, so any excess material is pushed " + "towards the edge where it is least visible. Inward starts at the edge and ends " + "with the tight curves at the center.\n" + "Default uses shortest-path ordering, which may run in either direction."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("default"); + def->enum_values.push_back("outward"); + def->enum_values.push_back("inward"); + def->enum_labels.push_back(L("Default")); + def->enum_labels.push_back(L("Outward")); + def->enum_labels.push_back(L("Inward")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(SurfaceFillOrder::Default)); + + def = this->add("bottom_surface_fill_order", coEnum); + def->label = L("Bottom surface fill order"); + def->category = L("Strength"); + def->tooltip = L("Direction in which bottom surfaces are filled when using a center-based pattern " + "(Concentric, Archimedean Chords, Octagram Spiral).\n" + "Inward starts each surface with the wider outer curves, which improves first layer " + "adhesion on build plates where the tight curves at the center may not stick. " + "Outward starts at the center, pushing any excess material towards the edge.\n" + "Default uses shortest-path ordering, which may run in either direction."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values = def_top_fill_order->enum_values; + def->enum_labels = def_top_fill_order->enum_labels; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(SurfaceFillOrder::Default)); + def = this->add("internal_solid_infill_pattern", coEnum); def->label = L("Internal solid infill pattern"); def->category = L("Strength"); @@ -2548,6 +2775,27 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionInts{1}); + // Multi-nozzle: per-filament map to the config slot identified by (extruder, nozzle_volume_type). + // Engine-internal per-filament slot map: recomputed at apply time from filament_map (plus the + // per-filament volume map when an extruder exposes several volume types) and used to key the + // retract-override fallback; never a user input and never part of the exported full config. + // Internal use only, no translation. + def = this->add("filament_map_2", coInts); + def->label = "Filament map plus for multi nozzle"; + def->tooltip = "Filament map to the index identified by extruder and nozzle_volume_type"; + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInts{1}); + + // Per-filament nozzle-volume-type override (multi-volume/Hybrid). Round-trips through .3mf + // plate metadata (filament_volume_maps) and steers per-filament slot resolution when an + // extruder exposes several volume types. Producers: the GUI full-config composition injects + // a filament-count-sized map (plate map, else per-extruder defaults) and the project config + // keeps it sized; expansion trusts the map only when its size matches the filament count + // (CLI runs may still carry the 1-element default). + def = this->add("filament_volume_map", coInts); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInts{(int)(NozzleVolumeType::nvtStandard)}); + def = this->add("physical_extruder_map",coInts); // internal use only, don't need translation def->label = "Map the logical extruder to physical extruder"; @@ -2563,14 +2811,24 @@ void PrintConfigDef::init_fff_params() def->enum_values.push_back("Auto For Flush"); def->enum_values.push_back("Auto For Match"); def->enum_values.push_back("Manual"); + def->enum_values.push_back("Nozzle Manual"); def->enum_values.push_back("Default"); def->enum_labels.push_back(L("Auto For Flush")); def->enum_labels.push_back(L("Auto For Match")); def->enum_labels.push_back(L("Manual")); + def->enum_labels.push_back(L("Nozzle Manual")); def->enum_labels.push_back(L("Default")); def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(fmmAutoForFlush)); + // Per-filament -> physical-nozzle assignment. Written back by the grouping engine after + // slicing (all non-sequential modes) and read back to the plate config; a user input only + // in fully-manual mode (fmmNozzleManual). Dumped in the g-code header for diagnostics. + // Internal use only, no translation. + def = this->add("filament_nozzle_map", coInts); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInts{1}); + def = this->add("filament_flush_temp", coInts); def->label = L("Flush temperature"); def->tooltip = L("Temperature when flushing filament. 0 indicates the upper bound of the recommended nozzle temperature range."); @@ -2581,6 +2839,19 @@ void PrintConfigDef::init_fff_params() def->sidetext = L(u8"\u2103" /* °C */); // degrees Celsius, CIS languages need translation def->set_default_value(new ConfigOptionIntsNullable{0}); + // Fast-purge flush temperature: used only when prime_volume_mode==Fast. + // Default 0 (fall back to the recommended-range upper bound, identical to filament_flush_temp), + // so the key is inert for the shipping fleet. Kept out of the g-code config block (banned_keys). + def = this->add("filament_flush_temp_fast", coInts); + def->label = L("Flush temperature"); + def->tooltip = L("Flush temperature used in fast purge mode."); + def->mode = comAdvanced; + def->nullable = true; + def->min = 0; + def->max = max_temp; + def->sidetext = L(u8"℃" /* °C */); // degrees Celsius, CIS languages need translation + def->set_default_value(new ConfigOptionIntsNullable{0}); + def = this->add("filament_flush_volumetric_speed", coFloats); def->label = L("Flush volumetric speed"); def->tooltip = L("Volumetric speed when flushing filament. 0 indicates the max volumetric speed."); @@ -2954,6 +3225,18 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionInts{3}); + // A single 32-bit int encodes the compatibility level of a filament across all extruders (up to 10). + // Every 3 bits represent one extruder: bits [3*i, 3*i+2] -> extruder i. + // Compatibility levels: 0 = printable, 1 = error, 2 = critical warning, 3 = warning (4-7 reserved). + // Default 0 (printable) keeps the key inert for filaments/printers that do not declare it. + def = this->add("filament_extruder_compatibility", coInts); + def->label = L("Filament-extruder compatibility"); + def->tooltip = L("A single 32-bit int encoding the compatibility level of a filament across all extruders (up to 10). " + "Every 3 bits represent one extruder (bits [3*i, 3*i+2] for extruder i). " + "0: printable, 1: error, 2: critical warning, 3: warning, 4-7: reserved."); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInts{0}); + // BBS def = this->add("temperature_vitrification", coInts); def->label = L("Softening temperature"); @@ -3035,12 +3318,13 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->max = 100; def->set_default_value(new ConfigOptionPercent(20)); - + def = this->add("align_infill_direction_to_model", coBool); - def->label = L("Align infill direction to model"); + def->label = L("Align directions to model"); def->category = L("Strength"); - def->tooltip = L("Aligns infill, bridge, ironing and surface fill directions to follow the model's orientation on the build plate.\n" - "When enabled, directions rotate with the model to maintain optimal strength characteristics."); + def->tooltip = L("Aligns infill, bridge, ironing, and top/bottom surface directions to follow the model's orientation on the build plate.\n" + "When enabled, these directions rotate together with the model so the printed features keep their intended orientation " + "relative to the part, preserving optimal strength and surface characteristics regardless of how the model is placed."); def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); @@ -3168,7 +3452,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Sparse infill"); def->category = L("Speed"); def->tooltip = L("Acceleration of sparse infill. If the value is expressed as a percentage (e.g. 100%), it will be calculated based on the default acceleration."); - def->sidetext = L("mm/s² or %"); + def->sidetext = L(u8"mm/s² or %"); def->min = 0; def->mode = comAdvanced; def->ratio_over = "default_acceleration"; @@ -3179,7 +3463,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Internal solid infill"); def->category = L("Speed"); def->tooltip = L("Acceleration of internal solid infill. If the value is expressed as a percentage (e.g. 100%), it will be calculated based on the default acceleration."); - def->sidetext = L("mm/s² or %"); + def->sidetext = L(u8"mm/s² or %"); def->min = 0; def->mode = comAdvanced; def->ratio_over = "default_acceleration"; @@ -3635,7 +3919,7 @@ void PrintConfigDef::init_fff_params() "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->sidetext = "%"; def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercent(50)); @@ -3782,6 +4066,21 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("fan_direction", coEnum); + def->label = L("Fan direction"); + def->tooltip = L("Cooling fan direction of the printer"); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("undefine"); + def->enum_values.push_back("left"); + def->enum_values.push_back("right"); + def->enum_values.push_back("both"); + def->enum_labels.push_back(L("Undefined")); + def->enum_labels.push_back(L("Left")); + def->enum_labels.push_back(L("Right")); + def->enum_labels.push_back(L("Both")); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionEnum(fdUndefine)); + def = this->add("fan_speedup_time", coFloat); // Label is set in Tab.cpp in the Line object. //def->label = L("Fan speed-up time"); @@ -3828,7 +4127,7 @@ void PrintConfigDef::init_fff_params() "value that the firmware would silently drop, and the fan never receives a value below the one " "you know it can actually spool at." "\nSet to 0 to deactivate."); - def->sidetext = L("%"); + def->sidetext = "%"; def->min = 0; def->max = 100; def->mode = comAdvanced; @@ -3857,6 +4156,17 @@ void PrintConfigDef::init_fff_params() def->mode=comDevelop; def->set_default_value(new ConfigOptionBool(true)); + // Printer capability flag: switches the accessory UI between air filtration and the cooling filter. + def = this->add("support_cooling_filter", coBool); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("cooling_filter_enabled", coBool); + def->label = L("Use cooling filter"); + def->tooltip = L("Enable this if printer support cooling filter"); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("gcode_flavor", coEnum); def->label = L("G-code flavor"); def->tooltip = L("What kind of G-code the printer is compatible with."); @@ -4659,6 +4969,39 @@ void PrintConfigDef::init_fff_params() def->mode = comDevelop; def->set_default_value(new ConfigOptionFloats{ 0., 0. }); + // Bedslinger mass/force limits. + // Consumed by GCode::mass_load_limited_machine_acceleration (curr_y_acceleration_limit) + // and the printed-mass check. Default 0 keeps them inactive for existing printers. + def = this->add("machine_max_force_Y", coFloat); + def->full_label = L("Maximum force of the Y axis"); + def->category = L("Machine limits"); + def->readonly = false; + def->tooltip = L("The allowed maximum output force of Y axis"); + def->sidetext = L("N"); + def->min = 0; + def->mode = comDevelop; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("machine_bed_mass_Y", coFloat); + def->full_label = L("Bed mass of the Y axis"); + def->category = L("Machine limits"); + def->readonly = false; + def->tooltip = L("The machine bed mass load of Y axis"); + def->sidetext = L("g"); + def->min = 0; + def->mode = comDevelop; + def->set_default_value(new ConfigOptionFloat(0)); + + def = this->add("machine_max_printed_mass", coFloat); + def->full_label = L("The allowed max printed mass"); + def->category = L("Machine limits"); + def->readonly = false; + def->tooltip = L("The allowed max printed mass on a plate"); + def->sidetext = L("g"); + def->min = 0; + def->mode = comDevelop; + def->set_default_value(new ConfigOptionFloat(0)); + // M204 P... [mm/sec^2] def = this->add("machine_max_acceleration_extruding", coFloats); def->full_label = L("Maximum acceleration for extruding"); @@ -4739,7 +5082,7 @@ void PrintConfigDef::init_fff_params() def = this->add("input_shaping_freq_x", coFloat); def->label = L("X"); def->tooltip = L("Resonant frequency for the X axis input shaper.\nZero will use the firmware frequency.\nTo disable input shaping, use the Disable type.\nRRF: X and Y values are equal."); - def->sidetext = "Hz"; + def->sidetext = L("Hz"); // Hertz, CIS languages need translation def->min = 0; def->max = 1000; def->mode = comExpert; @@ -4748,7 +5091,7 @@ void PrintConfigDef::init_fff_params() def = this->add("input_shaping_freq_y", coFloat); def->label = L("Y"); def->tooltip = L("Resonant frequency for the Y axis input shaper.\nZero will use the firmware frequency.\nTo disable input shaping, use the Disable type."); - def->sidetext = "Hz"; + def->sidetext = L("Hz"); // Hertz, CIS languages need translation def->min = 0; def->max = 1000; def->mode = comExpert; @@ -5248,6 +5591,15 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionPercents { 100 }); + // Orca: + def = this->add("retract_after_wipe", coPercents); + def->label = L("Retract amount after wipe"); + def->tooltip = L("The length of fast retraction after wipe, relative to retraction length.\n" + "The value will be clamped by 100% minus the retract amount before the wipe value."); + def->sidetext = "%"; + def->mode = comExpert; + def->set_default_value(new ConfigOptionPercents { 0 }); + def = this->add("retract_when_changing_layer", coBools); def->label = L("Retract on layer change"); def->tooltip = L("This forces a retraction on layer changes."); @@ -5404,10 +5756,15 @@ void PrintConfigDef::init_fff_params() def->label = "Nozzle Volume Type"; def->tooltip = "Nozzle volume type for extruders."; def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + // Order must match the NozzleVolumeType enum values (Standard=0, High Flow=1, Hybrid=2, TPU High Flow=3). def->enum_values.push_back(L("Standard")); def->enum_values.push_back(L("High Flow")); + def->enum_values.push_back(L("Hybrid")); + def->enum_values.push_back(L("TPU High Flow")); def->enum_labels.push_back(L("Standard")); def->enum_labels.push_back(L("High Flow")); + def->enum_labels.push_back(L("Hybrid")); + def->enum_labels.push_back(L("TPU High Flow")); def->mode = comSimple; def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); @@ -5418,8 +5775,12 @@ void PrintConfigDef::init_fff_params() def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); def->enum_values.push_back(L("Standard")); def->enum_values.push_back(L("High Flow")); + def->enum_values.push_back(L("Hybrid")); + def->enum_values.push_back(L("TPU High Flow")); def->enum_labels.push_back(L("Standard")); def->enum_labels.push_back(L("High Flow")); + def->enum_labels.push_back(L("Hybrid")); + def->enum_labels.push_back(L("TPU High Flow")); def->mode = comDevelop; def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); @@ -5436,6 +5797,43 @@ void PrintConfigDef::init_fff_params() def->tooltip = "AMS counts per extruder."; def->set_default_value(new ConfigOptionStrings { }); + // Multi-nozzle: per-extruder physical nozzle inventory by volume type, + // "#" tokens joined by "|". Internal use only, no translation. + def = this->add("extruder_nozzle_stats", coStrings); + def->label = "Extruder nozzle stats"; + def->tooltip = "Physical nozzle counts per extruder, keyed by nozzle volume type."; + def->set_default_value(new ConfigOptionStrings { }); + + // Multi-nozzle: number of physical nozzles per extruder. Forward-compat-only registration + // with no slicing consumer: the nozzle-assignment engine derives its per-extruder physical nozzle + // inventory from the richer `extruder_nozzle_stats` key, not from this scalar count, so nothing in + // src/ reads it. Kept registered so an H2C project/config that carries the key loads without an + // unknown-option substitution warning. Default {1} == today's single-nozzle-per-extruder assumption, + // so absent/default is a no-op for every shipping printer. Internal use only, no translation. + def = this->add("extruder_nozzle_count", coInts); + def->label = "extruder nozzle count"; + def->tooltip = "extruder nozzle count"; + def->mode = comDevelop; + def->set_default_value(new ConfigOptionInts{1}); + + // Per-nozzle volume type. Forward-compat-only registration with no slicing consumer — nothing in + // src/ reads it; the engine resolves per-nozzle volume types from `extruder_nozzle_stats` tokens + // instead. Kept registered so a project/config carrying it loads without an unknown-option + // substitution warning. Registers Standard/High Flow/TPU High Flow only (no Hybrid). + // Internal use only, no translation. + def = this->add("extruder_nozzle_volume_type", coEnums); + def->label = "Extruder nozzle volume type"; + def->tooltip = "Nozzle volume type per physical nozzle of an extruder."; + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("Standard"); + def->enum_values.push_back("High Flow"); + def->enum_values.push_back("TPU High Flow"); + def->enum_labels.push_back("Standard"); + def->enum_labels.push_back("High Flow"); + def->enum_labels.push_back("TPU High Flow"); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionEnumsGeneric{ NozzleVolumeType::nvtStandard }); + def = this->add("enable_filament_dynamic_map", coBool); def->label = L("Enable filament dynamic map"); def->tooltip = L("Enable dynamic filament mapping during print."); @@ -5534,6 +5932,19 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0. }); + // Per-(extruder,variant) deretraction speed at an extruder change. This value + // ships in multi-extruder machine profiles but has no slicer consumer — it is a device/firmware-facing + // profile key. Registered here (ConfigDef-only, no FullPrintConfig static member) so X2D/P2S profiles + // that already carry it — and the H2D/A2L leaves — validate as a known key; unread by the slicer. + // nullable so absent leaves stay nil (excluded from the g-code config block). + def = this->add("deretract_speed_extruder_change", coFloats); + def->label = L("Deretraction speed (extruder change)"); + def->tooltip = L("Speed for reloading filament into the nozzle when switching extruder."); + def->sidetext = L("mm/s"); // millimeters per second, CIS languages need translation + def->mode = comDevelop; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable { 0. }); + def = this->add("use_firmware_retraction", coBool); def->label = L("Use firmware retraction"); def->tooltip = L("This experimental setting uses G10 and G11 commands to have the firmware " @@ -5952,6 +6363,20 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionEnum(tlTraditional)); + // Farthest-point timelapse. Corexy-only refinement layered on top of the existing + // timelapse_type: when enabled the traditional-mode snapshot is + // taken at the extrusion point farthest from the camera (0,0) instead of traveling to a safe/chute + // position. Gated in GCode::process_layer by timelapse_type==tlTraditional && printer_structure!=psI3, + // so it is inert for i3 (A1/A2L) printers and whenever the toggle is off (default false → every + // existing printer's g-code is byte-identical). Only H2C/H2D machine profiles set it =1. + def = this->add("farthest_point_timelapse", coBool); + def->label = L("Farthest point timelapse"); + def->tooltip = L("When enabled, the timelapse snapshot is taken at the farthest point from camera " + "instead of traveling to the wipe tower or excess chute. " + "Only effective in traditional timelapse mode on non-I3 printers."); + def->mode = comSimple; + def->set_default_value(new ConfigOptionBool(false)); + def = this->add("standby_temperature_delta", coInt); def->label = L("Temperature variation"); // TRN PrintSettings : "Ooze prevention" > "Temperature variation" @@ -6076,6 +6501,22 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionBool(false)); + def = this->add("toolchange_ordering", coEnum); + def->label = L("Toolchange ordering"); + def->category = L("Advanced"); + def->tooltip = L( + "Determines the order of tool changes on each layer.\n" + "- Default: Starts with the last used extruder to minimize tool changes.\n" + "- Cyclic: Uses a fixed tool sequence each layer. This sacrifices speed for better surface quality, as the extra toolchanges allow layers more time to cool." + ); + def->mode = comAdvanced; + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.emplace_back("default"); + def->enum_values.emplace_back("cyclic"); + def->enum_labels.emplace_back(L("Default")); + def->enum_labels.emplace_back(L("Cyclic")); + def->set_default_value(new ConfigOptionEnum(ToolChangeOrderingType::Default)); + def = this->add("slice_closing_radius", coFloat); def->label = L("Slice gap closing radius"); def->category = L("Quality"); @@ -6684,7 +7125,7 @@ void PrintConfigDef::init_fff_params() def->label = L("Minimal"); def->tooltip = L("This is the chamber temperature at which printing should start, while the chamber continues heating " "toward the \"Target\" chamber temperature. For example, set the Target to 60 and the Minimal to 50 to " - "begin printing once the chamber reaches 50°C, without waiting for the full 60°C.\n\n" + "begin printing once the chamber reaches 50℃, without waiting for the full 60℃.\n\n" "It sets a G-code variable named chamber_minimal_temperature, which can be passed to your print start macro " "or a heat soak macro, like this: PRINT_START (other variables) CHAMBER_MIN_TEMP=[chamber_minimal_temperature].\n\n" "Unlike the \"Target\" chamber temperature, this option does not emit any M141/M191 commands; it only exposes " @@ -6799,6 +7240,36 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->set_default_value(new ConfigOptionFloat(0.6)); + def = this->add("separated_infills", coBool); + def->label = L("Separated infills"); + def->category = L("Strength"); + def->tooltip = L("Centers the internal infill of each part on itself, as if it were sliced on its own, instead of on the " + "whole assembly. Parts that touch or overlap are treated as one body and share a center; separate parts " + "(or distinct 3D objects) each get their own.\n" + "Useful when an assembly groups several objects that should each keep a consistent, self-centered infill.\n" + "Affects line and grid patterns and rotation-template infills.\n" + "Patterns locked to global coordinates (Gyroid, Honeycomb, TPMS, ...) are unaffected."); + def->mode = comExpert; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("center_of_surface_pattern", coEnum); + def->label = L("Center surface pattern on"); + def->category = L("Strength"); + def->tooltip = L("Chooses where the centering point of centered top/bottom surface patterns (Archimedean Chords, " + "Octagram Spiral) is placed.\n" + " - Each Surface: centers the pattern on every individual surface region, so each island is symmetric on its own.\n" + " - Each Model: centers the pattern on each connected body. Parts that touch or overlap share one center; " + "parts detached from the rest each get their own.\n" + " - Each Assembly: uses a single shared center for the whole object or assembly."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("each_surface"); + def->enum_values.push_back("each_model"); + def->enum_values.push_back("each_assembly"); + def->enum_labels.push_back(L("Each Surface")); + def->enum_labels.push_back(L("Each Model")); + def->enum_labels.push_back(L("Each Assembly")); + def->mode = comExpert; + def->set_default_value(new ConfigOptionEnum(CenterOfSurfacePattern::Each_Surface)); def = this->add("travel_speed", coFloats); def->label = L("Travel"); @@ -6875,6 +7346,14 @@ void PrintConfigDef::init_fff_params() //def->sidetext = ""; def->set_default_value(new ConfigOptionFloats{0.3}); + // Fast-purge mode: the flush multiplier used when prime_volume_mode==Fast. + // Only consumed on the pvmFast branch (default prime_volume_mode==Default reads flush_multiplier), + // so this key is inert for the shipping fleet. Kept out of the g-code config block (banned_keys). + def = this->add("flush_multiplier_fast", coFloats); + def->label = L("Flush multiplier (Fast mode)"); + def->tooltip = L("The flush multiplier used in fast purge mode."); + def->set_default_value(new ConfigOptionFloats{1.2}); + // BBS def = this->add("prime_volume", coFloat); def->label = L("Prime volume"); @@ -6884,6 +7363,22 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionFloat(45.)); + // Dual-extruder purge control: Default reproduces current behaviour + // (per-extruder flush_multiplier + filament_prime_volume); Saving reduces the prime volume, + // Fast selects flush_multiplier_fast + filament_flush_temp_fast. Default pvmDefault = inert. + def = this->add("prime_volume_mode", coEnum); + def->label = L("Prime volume mode"); + def->tooltip = L("Selects how the wipe-tower prime and flush volumes are computed on multi-extruder printers."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("Default"); + def->enum_values.push_back("Saving"); + def->enum_values.push_back("Fast"); + def->enum_labels.push_back(L("Default")); + def->enum_labels.push_back(L("Saving")); + def->enum_labels.push_back(L("Fast")); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionEnum(pvmDefault)); + def = this->add("wipe_tower_x", coFloats); //def->label = L("Position X"); //def->tooltip = L("X coordinate of the left front corner of a wipe tower."); @@ -7307,6 +7802,30 @@ void PrintConfigDef::init_fff_params() def->min = 0; def->set_default_value(new ConfigOptionPercent(85)); + def = this->add("filament_dev_ams_drying_ams_limitations", coStrings); + def->set_default_value(new ConfigOptionStrings{""}); + + def = this->add("filament_dev_ams_drying_temperature", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_ams_drying_time", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_ams_drying_heat_distortion_temperature", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_chamber_drying_bed_temperature", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_chamber_drying_time", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_drying_softening_temperature", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("filament_dev_drying_cooling_temperature", coFloats); + def->set_default_value(new ConfigOptionFloats{0}); + // Declare retract values for filament profile, overriding the printer's extruder profile. for (auto& opt_key : filament_extruder_override_keys) { const std::string filament_prefix = "filament_"; @@ -7340,6 +7859,163 @@ void PrintConfigDef::init_fff_params() } } + // ---- Multi-nozzle + pre-heat + nozzle-change (nc) config keys ---- + // These back 6-nozzle cluster grouping, the pre-heat/pre-cool time model and wipe-tower + // nozzle-change handling. Defaults are no-ops for existing single-nozzle printers (all new + // readers gate on extruder_max_nozzle_count > 1). + def = this->add("machine_hotend_change_time", coFloat); + def->label = L("Hotend change time"); + def->tooltip = L("Time to change hotend."); + def->sidetext = L("s"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.0)); + + // Printer-owned toggle selecting the time-aware grouping objective (flush + change/print + // time) over the flush-only objective. Default false == today's flush-only grouping, so + // absent/default is inert. Consumed by the grouping solver (SpeedInfo). + // Orca: pinned to comDevelop (rather than the default comSimple) to match the sibling multi-nozzle + // dev keys and keep it out of user selectors. + def = this->add("group_algo_with_time", coBool); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("machine_prepare_compensation_time", coFloat); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionFloat(260)); + + def = this->add("enable_pre_heating", coBool); + def->set_default_value(new ConfigOptionBool(false)); + + // Pre-heat injector context key. handle_hotend_as_extruder is read defensively by the injector; + // registered here (comDevelop, default off) as a known inert key. + def = this->add("handle_hotend_as_extruder", coBool); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionBool(false)); + + // filament_max_temperature_drop_when_ec: inert (default {0}, passed into the injector context but + // never consumed). Registered inert-only (comDevelop); not wired into any estimator read, and not + // added to any per-variant expansion list. + def = this->add("filament_max_temperature_drop_when_ec", coFloats); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionFloats{0}); + + def = this->add("hotend_cooling_rate", coFloats); + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{2}); + + def = this->add("hotend_heating_rate", coFloats); + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{2}); + + def = this->add("filament_change_length_nc", coFloats); + def->label = L("Hotend change"); + def->tooltip = L("When changing the hotend, it is recommended to extrude a certain length of filament from the original nozzle. This helps minimize nozzle oozing."); + def->sidetext = L("mm"); + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloats{10}); + + def = this->add("filament_ramming_travel_time", coFloats); + def->label = L("Extruder change"); + def->tooltip = L("To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after " + "the ramming is complete. The setting define the travel time."); + def->mode = comAdvanced; + def->sidetext = "s"; + def->min = 0; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{0}); + + def = this->add("filament_pre_cooling_temperature", coInts); + def->label = L("Extruder change"); + def->tooltip = L("To prevent oozing, the nozzle temperature will be cooled during ramming. Therefore, the ramming time must be greater than the cooldown time. 0 means disabled."); + def->mode = comAdvanced; + def->sidetext = "°C"; + def->min = 0; + def->nullable = true; + def->set_default_value(new ConfigOptionIntsNullable{0}); + + def = this->add("filament_ramming_volumetric_speed", coFloats); + def->label = L("Extruder change"); + def->tooltip = L("The maximum volumetric speed for ramming before extruder change, where -1 means using the maximum volumetric speed."); + def->sidetext = L("mm³/s"); + def->min = -1; + def->max = 200; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{-1}); + + def = this->add("filament_ramming_travel_time_nc", coFloats); + def->label = L("Hotend change"); + def->tooltip = L("To prevent oozing, the nozzle will perform a reverse travel movement for a certain period after " + "the ramming is complete. The setting define the travel time."); + def->mode = comAdvanced; + def->sidetext = "s"; + def->min = 0; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{0}); + + def = this->add("filament_pre_cooling_temperature_nc", coInts); + def->label = L("Hotend change"); + def->tooltip = L( + "To prevent oozing, the nozzle temperature will be cooled during ramming. Note: only a cooldown command and fan activation are triggered, reaching the target temperature is not guaranteed. 0 means disabled."); + def->mode = comAdvanced; + def->sidetext = "°C"; + def->min = 0; + def->nullable = true; + def->set_default_value(new ConfigOptionIntsNullable{0}); + + def = this->add("filament_ramming_volumetric_speed_nc", coFloats); + def->label = L("Hotend change"); + def->tooltip = L("The maximum volumetric speed for ramming before a hotend change, where -1 means using the maximum volumetric speed."); + def->sidetext = L("mm³/s"); + def->min = -1; + def->max = 200; + def->mode = comAdvanced; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{-1}); + + def = this->add("filament_retract_length_nc", coFloats); + def->label = L("length when change hotend"); + def->tooltip = L("When this retraction value is modified, it will be used as the amount of filament retracted " + "inside the hotend before changing hotends."); + def->sidetext = L("mm"); + def->mode = comDevelop; + def->nullable = true; + def->min = 0; + def->max = 18; + def->set_default_value(new ConfigOptionFloatsNullable { 10. }); + + def = this->add("extruder_max_nozzle_count", coInts); + def->mode = comDevelop; + def->nullable = true; + def->set_default_value(new ConfigOptionIntsNullable{ 1 }); + + // Printer flag gating the fast-purge mode selector in the Multi-Filament + // UI. comDevelop, default false; profiles of printers that support fast purge + // enable it, which shows the purge-mode selector for those printers. + def = this->add("support_fast_purge_mode", coBool); + def->label = L("Support fast purge mode"); + def->tooltip = L("Whether this printer supports fast purge mode with optimized temperature and multiplier."); + def->mode = comDevelop; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("filament_prime_volume_nc", coFloats); + def->label = L("Hotend change"); + def->tooltip = L("The volume of material required to prime the extruder for a hotend change on the tower."); + def->sidetext = L("mm³"); + def->min = 1.0; + def->mode = comSimple; + def->set_default_value(new ConfigOptionFloats{60.}); + + def = this->add("filament_preheat_temperature_delta", coFloats); + def->label = L("Preheat temperature delta"); + def->tooltip = L("Temperature delta applied during pre-heating before tool change."); + def->sidetext = "°C"; + def->mode = comDevelop; + def->nullable = true; + def->set_default_value(new ConfigOptionFloatsNullable{0}); + def = this->add("detect_narrow_internal_solid_infill", coBool); def->label = L("Detect narrow internal solid infills"); def->category = L("Strength"); @@ -7354,17 +8030,44 @@ void PrintConfigDef::init_extruder_option_keys() { // ConfigOptionFloats, ConfigOptionPercents, ConfigOptionBools, ConfigOptionStrings m_extruder_option_keys = { - "extruder_type", "nozzle_diameter", "default_nozzle_volume_type", "min_layer_height", "max_layer_height", "extruder_offset", - "extruder_printable_height", "nozzle_volume", "nozzle_type", "nozzle_flush_dataset", - "retraction_length", "z_hop", "z_hop_types", "travel_slope", "retract_lift_above", "retract_lift_below", "retract_lift_enforce", "retraction_speed", "deretraction_speed", - "retract_before_wipe", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance", - "retract_when_changing_layer", "retract_length_toolchange", "retract_restart_extra_toolchange", "extruder_colour", - "default_filament_profile","retraction_distances_when_cut","long_retractions_when_cut" + "default_filament_profile", + "default_nozzle_volume_type", + "deretraction_speed", + "extruder_colour", + "extruder_offset", + "extruder_printable_height", + "extruder_type", + "long_retractions_when_cut", + "max_layer_height", + "min_layer_height", + "nozzle_diameter", + "nozzle_flush_dataset", + "nozzle_type", + "nozzle_volume", + "retract_after_wipe", + "retract_before_wipe", + "retract_length_toolchange", + "retract_lift_above", + "retract_lift_below", + "retract_lift_enforce", + "retract_restart_extra", + "retract_restart_extra_toolchange", + "retract_when_changing_layer", + "retraction_distances_when_cut", + "retraction_length", + "retraction_minimum_travel", + "retraction_speed", + "travel_slope", + "wipe", + "wipe_distance", + "z_hop", + "z_hop_types" }; m_extruder_retract_keys = { "deretraction_speed", "long_retractions_when_cut", + "retract_after_wipe", "retract_before_wipe", "retract_lift_above", "retract_lift_below", @@ -7387,16 +8090,40 @@ void PrintConfigDef::init_extruder_option_keys() void PrintConfigDef::init_filament_option_keys() { m_filament_option_keys = { - "filament_diameter", "min_layer_height", "max_layer_height","volumetric_speed_coefficients", - "retraction_length", "z_hop", "z_hop_types", "retract_lift_above", "retract_lift_below", "retract_lift_enforce", "retraction_speed", "deretraction_speed", - "retract_before_wipe", "retract_restart_extra", "retraction_minimum_travel", "wipe", "wipe_distance", - "retract_when_changing_layer", "retract_length_toolchange", "retract_restart_extra_toolchange", "filament_colour", - "default_filament_profile","retraction_distances_when_cut","long_retractions_when_cut"/*,"filament_seam_gap"*/ + "default_filament_profile", + "deretraction_speed", + "filament_colour", + "filament_diameter", + "filament_retract_length_nc", + // "filament_seam_gap", + "long_retractions_when_cut", + "max_layer_height", + "min_layer_height", + "retract_after_wipe", + "retract_before_wipe", + "retract_length_toolchange", + "retract_lift_above", + "retract_lift_below", + "retract_lift_enforce", + "retract_restart_extra", + "retract_restart_extra_toolchange", + "retract_when_changing_layer", + "retraction_distances_when_cut", + "retraction_length", + "retraction_minimum_travel", + "retraction_speed", + "volumetric_speed_coefficients", + "wipe", + "wipe_distance", + "z_hop", + "z_hop_types", }; m_filament_retract_keys = { "deretraction_speed", + "filament_retract_length_nc", "long_retractions_when_cut", + "retract_after_wipe", "retract_before_wipe", "retract_lift_above", "retract_lift_below", @@ -8294,6 +9021,7 @@ void PrintConfigDef::handle_legacy(t_config_option_key &opt_key, std::string &va "internal_bridge_support_thickness", "top_area_threshold", "reduce_wall_solid_infill","filament_load_time","filament_unload_time", "smooth_coefficient", "overhang_totally_speed", "silent_mode", "overhang_speed_classic", "filament_prime_volume", + "anisotropic_surfaces", // superseded by top_surface_fill_order / bottom_surface_fill_order }; if (ignore.find(opt_key) != ignore.end()) { @@ -8414,6 +9142,15 @@ std::set print_options_with_variant = { std::set filament_options_with_variant = { "filament_flow_ratio", "filament_max_volumetric_speed", + // Per-variant ramming / pre-cooling / nozzle-change filament overrides + "filament_ramming_volumetric_speed", + "filament_pre_cooling_temperature", + "filament_ramming_travel_time", + "filament_ramming_volumetric_speed_nc", + "filament_pre_cooling_temperature_nc", + "filament_ramming_travel_time_nc", + "filament_retract_length_nc", + "filament_preheat_temperature_delta", //"filament_extruder_id", "filament_extruder_variant", "filament_retraction_length", @@ -8431,6 +9168,9 @@ std::set filament_options_with_variant = { //BBS "filament_wipe_distance", "filament_retract_before_wipe", + // Orca + "filament_retract_after_wipe", + //BBS "filament_long_retractions_when_cut", "filament_retraction_distances_when_cut", "long_retractions_when_ec", @@ -8461,7 +9201,8 @@ std::set printer_extruder_options = { "extruder_printable_area", "extruder_printable_height", "min_layer_height", - "max_layer_height" + "max_layer_height", + "extruder_max_nozzle_count" // Per-extruder max (sub-)nozzle count }; std::set printer_options_with_variant_1 = { @@ -8480,6 +9221,8 @@ std::set printer_options_with_variant_1 = { "wipe", "wipe_distance", "retract_before_wipe", + // Orca: + "retract_after_wipe", "retract_length_toolchange", "retract_restart_extra", "retract_restart_extra_toolchange", @@ -8489,6 +9232,9 @@ std::set printer_options_with_variant_1 = { "nozzle_type", "printer_extruder_id", "printer_extruder_variant", + // Per-variant hotend heat-up / cool-down rates (pre-heat time model) + "hotend_cooling_rate", + "hotend_heating_rate", "nozzle_flush_dataset" }; @@ -8514,6 +9260,17 @@ std::set printer_options_with_variant_2 = { std::set empty_options; +std::set filament_dev_options = { + "filament_dev_ams_drying_ams_limitations", + "filament_dev_ams_drying_temperature", + "filament_dev_ams_drying_time", + "filament_dev_ams_drying_heat_distortion_temperature", + "filament_dev_chamber_drying_bed_temperature", + "filament_dev_chamber_drying_time", + "filament_dev_drying_softening_temperature", + "filament_dev_drying_cooling_temperature" +}; + DynamicPrintConfig DynamicPrintConfig::full_print_config() { return DynamicPrintConfig((const PrintRegionConfig&)FullPrintConfig::defaults()); @@ -9071,6 +9828,9 @@ int DynamicPrintConfig::get_index_for_extruder(int extruder_or_filament_id, std: if (variant_opt != nullptr) { int v_size = variant_opt->values.size(); const bool has_complete_id_map = id_opt && int(id_opt->values.size()) >= v_size; + // nvtHybrid not supported in presets, switch to nvtStandard to match the preset values + if (nozzle_volume_type == nvtHybrid) + nozzle_volume_type = nvtStandard; std::string extruder_variant = get_extruder_variant_string(extruder_type, nozzle_volume_type); for (int index = 0; index < v_size; index++) { @@ -9484,7 +10244,7 @@ int DynamicPrintConfig::update_values_from_multi_to_multi_2(const std::vector::max(); for(auto idx : indices){ - if(opt && !opt->is_nil(idx)){ + if(opt && idx < opt->values.size() && !opt->is_nil(idx)){ has_value = true; target_value = std::min(target_value, src_values[idx]); } @@ -9671,184 +10431,229 @@ DynamicPrintConfig::get_filament_type() const return std::string(); } -void DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride, unsigned int extruder_id) +int DynamicPrintConfig::get_extruder_nozzle_volume_count(int extruder_count, std::vector>& nozzle_volume_types) const { - int extruder_count; - bool different_extruder = printer_config.support_different_extruders(extruder_count); - if ((extruder_count > 1) || different_extruder) - { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: different extruders processing")%__LINE__; - //apply process settings - //auto opt_nozzle_diameters = this->option("nozzle_diameter"); - //int extruder_count = opt_nozzle_diameters->size(); - auto opt_extruder_type = dynamic_cast(printer_config.option("extruder_type")); - auto opt_nozzle_volume_type = dynamic_cast(printer_config.option("nozzle_volume_type")); - if (!opt_extruder_type || !opt_nozzle_volume_type) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: extruder_type or nozzle_volume_type option not found, skipping")%__LINE__; - return; - } - std::vector variant_index; - - if (extruder_id > 0 && extruder_id <= static_cast (extruder_count)) { - variant_index.resize(1); - ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(extruder_id - 1)); - NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(extruder_id - 1)); - - //variant index - variant_index[0] = get_index_for_extruder(extruder_id, id_name, extruder_type, nozzle_volume_type, variant_name); - - if (variant_index[0] < 0) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, for filament") - % __LINE__ % s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type]; - assert(false); - } - - extruder_count = 1; - } - else { - variant_index.resize(extruder_count); - - for (int e_index = 0; e_index < extruder_count; e_index++) - { - ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(e_index)); - NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(e_index)); - - //variant index - variant_index[e_index] = get_index_for_extruder(e_index+1, id_name, extruder_type, nozzle_volume_type, variant_name); - if (variant_index[e_index] < 0) { - // Orca: This is expected during transient UI states (e.g. popup windows), - // fall back to 0 silently. - variant_index[e_index] = 0; - } - } - } - - const ConfigDef *config_def = this->def(); - if (!config_def) { - BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__; - return; - } - for (auto& key: key_set) + int count = extruder_count; + auto opt_extruder_nozzle_stats = dynamic_cast(this->option("extruder_nozzle_stats")); + nozzle_volume_types.resize(extruder_count, std::vector{}); + if (opt_extruder_nozzle_stats && (int(opt_extruder_nozzle_stats->values.size()) == extruder_count)) { + std::vector> extruder_nozzle_counts = get_extruder_nozzle_stats(opt_extruder_nozzle_stats->values); + count = 0; + for (int i = 0; i < extruder_count; i++) { - const ConfigOptionDef *optdef = config_def->get(key); - if (!optdef) { - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key; - continue; - } - switch (optdef->type) { - case coStrings: - { - ConfigOptionStrings * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coInts: - { - ConfigOptionInts * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coFloats: - { - ConfigOptionFloats * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coPercents: - { - ConfigOptionPercents * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coFloatsOrPercents: - { - ConfigOptionFloatsOrPercents * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coBools: - { - ConfigOptionBools * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - case coEnums: - { - ConfigOptionEnumsGeneric * opt = this->option(key); - std::vector new_values; - - new_values.resize(extruder_count * stride); - for (int e_index = 0; e_index < extruder_count; e_index++) - { - for (unsigned int i = 0; i < stride; i++) - new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); - } - opt->values = new_values; - break; - } - default: - BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key; - break; - } + count += extruder_nozzle_counts[i].size(); + // std::map iteration order gives the canonical slot order: ascending NozzleVolumeType + for (auto& iter : extruder_nozzle_counts[i]) + nozzle_volume_types[i].push_back(iter.first); } } + return count; } -void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name) +std::vector DynamicPrintConfig::update_values_to_printer_extruders(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::vector>& nv_types, + std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride, unsigned int extruder_id, NozzleVolumeType filament_nvt) { - int extruder_count; - bool different_extruder = printer_config.support_different_extruders(extruder_count); - if ((extruder_count > 1) || different_extruder) + std::vector variant_index; + int variant_count = extruder_count; + + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: extruder_count %2%, extruder_nozzle_volume_count %3%")%__LINE__ %extruder_count %extruder_nozzle_volume_count; + + auto opt_extruder_type = dynamic_cast(printer_config.option("extruder_type")); + auto opt_nozzle_volume_type = dynamic_cast(printer_config.option("nozzle_volume_type")); + if (!opt_extruder_type || !opt_nozzle_volume_type) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: extruder_type or nozzle_volume_type option not found, skipping")%__LINE__; + return variant_index; + } + + if (extruder_id > 0 && extruder_id <= static_cast (extruder_count)) { + variant_index.resize(1); + ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(extruder_id - 1)); + NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(extruder_id - 1)); + + if (nozzle_volume_type == nvtHybrid) { + // a mixed-nozzle extruder has no preset column of its own: the filament's concrete + // volume type selects the slot + nozzle_volume_type = filament_nvt; + } + else if (nozzle_volume_type != filament_nvt) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ + << boost::format(", Line %1%: nozzle_volume_type is %2%, not equal to filament_nvt %3%") % __LINE__ % nozzle_volume_type % filament_nvt; + } + + //variant index + variant_index[0] = get_index_for_extruder(extruder_id, id_name, extruder_type, nozzle_volume_type, variant_name); + + if (variant_index[0] < 0) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, for filament") + % __LINE__ % s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type]; + } + + variant_count = 1; + } + else { + // Orca: emit the slots first, then size variant_count from what was actually + // emitted. extruder_nozzle_volume_count only equals the emitted total when every + // extruder carries per-type stats; an extruder with an empty stats entry combined + // with a Hybrid extruder would otherwise overrun a table pre-sized from that count. + for (int e_index = 0; e_index < extruder_count; e_index++) + { + ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(e_index)); + NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(e_index)); + + // Orca: latch the decision before the inner loop reassigns nozzle_volume_type; + // re-testing the reassigned value would make every slot after the first reuse + // the first slot's volume type. + const bool per_type_slots = extruder_nozzle_volume_count > extruder_count || nozzle_volume_type == nvtHybrid; + const int nvt_count = per_type_slots ? int(nv_types[e_index].size()) : 1; + for (int nvt_index = 0; nvt_index < nvt_count; nvt_index++) + { + if (per_type_slots) + nozzle_volume_type = nv_types[e_index][nvt_index]; + //variant index + int slot_index = get_index_for_extruder(e_index+1, id_name, extruder_type, nozzle_volume_type, variant_name); + if (slot_index < 0) { + // Orca: This is expected during transient UI states (e.g. popup windows), + // fall back to 0 silently. + slot_index = 0; + } + variant_index.push_back(slot_index); + } + } + variant_count = int(variant_index.size()); + } + + const ConfigDef *config_def = this->def(); + if (!config_def) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__; + return variant_index; + } + for (auto& key: key_set) + { + const ConfigOptionDef *optdef = config_def->get(key); + if (!optdef) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key; + continue; + } + switch (optdef->type) { + case coStrings: + { + ConfigOptionStrings * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coInts: + { + ConfigOptionInts * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coFloats: + { + ConfigOptionFloats * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coPercents: + { + ConfigOptionPercents * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coFloatsOrPercents: + { + ConfigOptionFloatsOrPercents * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coBools: + { + ConfigOptionBools * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + case coEnums: + { + ConfigOptionEnumsGeneric * opt = this->option(key); + if (!opt) continue; + std::vector new_values; + + new_values.resize(variant_count * stride); + for (int e_index = 0; e_index < variant_count; e_index++) + { + for (unsigned int i = 0; i < stride; i++) + new_values[e_index*stride + i] = opt->get_at(variant_index[e_index]*stride + i); + } + opt->values = new_values; + break; + } + default: + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key; + break; + } + } + + return variant_index; +} + +void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::set& key_set, std::string id_name, std::string variant_name) +{ + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: extruder_count %2%, extruder_nozzle_volume_count %3%")%__LINE__ %extruder_count %extruder_nozzle_volume_count; + { - BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: extruder_count=%2%, different_extruder=%3%")%__LINE__ %extruder_count %different_extruder; auto opt_filament_map = printer_config.option("filament_map"); if (!opt_filament_map) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: filament_map option not found, skipping")%__LINE__; @@ -9857,14 +10662,22 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen std::vector filament_maps = opt_filament_map->values; size_t filament_count = filament_maps.size(); //apply process settings - //auto opt_nozzle_diameters = this->option("nozzle_diameter"); - //int extruder_count = opt_nozzle_diameters->size(); auto opt_extruder_type = dynamic_cast(printer_config.option("extruder_type")); auto opt_nozzle_volume_type = dynamic_cast(printer_config.option("nozzle_volume_type")); if (!opt_extruder_type || !opt_nozzle_volume_type) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: extruder_type or nozzle_volume_type option not found, skipping")%__LINE__; return; } + + auto opt_filament_volume_maps = dynamic_cast(printer_config.option("filament_volume_map")); + std::vector filament_volume_maps; + // Orca: honour the per-filament volume map only when a producer sized it to the + // filament count. The full-config producers (PresetBundle injection, engine + // write-back) always size it; mis-sized maps (stale project values, CLI runs until + // the per-filament synthesis lands there) must not distort slot resolution nor be + // indexed out of bounds. + if (opt_filament_volume_maps && opt_filament_volume_maps->values.size() == filament_count) + filament_volume_maps = opt_filament_volume_maps->values; auto opt_ids = id_name.empty()? nullptr: dynamic_cast(this->option(id_name)); std::vector variant_index; @@ -9875,6 +10688,10 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(filament_maps[f_index] - 1)); NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(filament_maps[f_index] - 1)); + if ((extruder_nozzle_volume_count > extruder_count || nozzle_volume_type == nvtHybrid) && (!filament_volume_maps.empty())) { + nozzle_volume_type = (NozzleVolumeType)(filament_volume_maps[f_index]); + } + //variant index variant_index[f_index] = get_index_for_extruder(f_index+1, id_name, extruder_type, nozzle_volume_type, variant_name); if (variant_index[f_index] < 0) { @@ -9899,8 +10716,11 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__; return; } + bool has_id_key = !id_name.empty() && key_set.count(id_name) > 0; for (auto& key: key_set) { + if (has_id_key && key == id_name) + continue; const ConfigOptionDef *optdef = config_def->get(key); if (!optdef) { BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key; @@ -10060,6 +10880,155 @@ void DynamicPrintConfig::update_values_to_printer_extruders_for_multiple_filamen break; } } + // Orca: also require a non-empty id list; get_at on an empty vector is undefined. + if (has_id_key && opt_ids && !opt_ids->values.empty()) { + // remap the id list itself last: the lookups above still need the original ids + std::vector new_values; + new_values.resize(filament_count); + for (int f_index = 0; f_index < filament_count; f_index++) { + new_values[f_index] = opt_ids->get_at(variant_index[f_index]); + } + const_cast(opt_ids)->values = new_values; + } + } +} + +// Regathers a vector option's values through per-slot source indices (one input index per +// output slot). Out-of-range indices keep the first value, matching get_at's fallback. +template +static void gather_option_values(const std::string &key, OptType *opt, const std::vector &slot_param_indices) +{ + if (!opt || opt->values.empty()) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: option %2% not found or empty, skipping")%__LINE__%key; + return; + } + std::vector new_values; + new_values.reserve(slot_param_indices.size()); + for (int idx : slot_param_indices) { + if (idx < 0 || static_cast(idx) >= opt->values.size()) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: option %2% slot index %3% out of range, keeping first value")%__LINE__%key%idx; + new_values.emplace_back(opt->values.front()); + } + else + new_values.emplace_back(opt->values[idx]); + } + opt->values = std::move(new_values); +} + +void DynamicPrintConfig::update_filament_config_values_for_multiple_extruders(DynamicPrintConfig& printer_config, + const std::unordered_map>& filament_variant_uses, + int extruder_count, int extruder_nozzle_volume_count, + std::set& key_set, std::string id_name, std::string variant_name, + std::vector* slot_machine_indices) +{ + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(", Line %1%: extruder_count %2%, extruder_nozzle_volume_count %3%")%__LINE__ %extruder_count %extruder_nozzle_volume_count; + + auto opt_filament_map = printer_config.option("filament_map"); + if (!opt_filament_map) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: filament_map option not found, skipping")%__LINE__; + return; + } + std::vector filament_maps = opt_filament_map->values; + size_t filament_count = filament_maps.size(); + auto opt_extruder_type = dynamic_cast(printer_config.option("extruder_type")); + auto opt_nozzle_volume_type = dynamic_cast(printer_config.option("nozzle_volume_type")); + if (!opt_extruder_type || !opt_nozzle_volume_type) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: extruder_type or nozzle_volume_type option not found, skipping")%__LINE__; + return; + } + + auto opt_filament_volume_maps = dynamic_cast(printer_config.option("filament_volume_map")); + std::vector filament_volume_maps; + // Orca: same sizing guard as the single-slot rebuild above — honour the per-filament volume + // map only when a producer sized it to the filament count. + if (opt_filament_volume_maps && opt_filament_volume_maps->values.size() == filament_count) + filament_volume_maps = opt_filament_volume_maps->values; + auto opt_ids = id_name.empty() ? nullptr : dynamic_cast(this->option(id_name)); + + std::vector slot_param_indices; + slot_param_indices.reserve(filament_count * 2); + if (slot_machine_indices) { + slot_machine_indices->clear(); + slot_machine_indices->reserve(filament_count * 2); + } + + auto resolve_slot = [&](int f_index, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, int extruder_id_1based) { + int param_index = get_index_for_extruder(f_index + 1, id_name, extruder_type, nozzle_volume_type, variant_name); + if (param_index < 0) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: could not found extruder_type %2%, nozzle_volume_type %3%, filament_index %4%, extruder index %5%") + %__LINE__ %s_keys_names_ExtruderType[extruder_type] % s_keys_names_NozzleVolumeType[nozzle_volume_type] % (f_index+1) %extruder_id_1based; + assert(false); + //for some updates happens in a invalid state(caused by popup window) + //we need to avoid crash + param_index = 0; + if (opt_ids) { + for (int i = 0; i < opt_ids->values.size(); i++) + if (opt_ids->values[i] == (f_index + 1)) { + param_index = i; + break; + } + } + } + slot_param_indices.push_back(param_index); + if (slot_machine_indices) { + // Orca: key each output slot to the machine slot of its own variant (the same + // derivation the per-filament slot map uses), so the retract-override nil fallback + // stays aligned when a filament occupies more than one slot. + int machine_index = printer_config.get_index_for_extruder(extruder_id_1based, "print_extruder_id", extruder_type, nozzle_volume_type, "print_extruder_variant"); + slot_machine_indices->push_back(std::max(machine_index, 0)); + } + }; + + for (int f_index = 0; f_index < static_cast(filament_count); f_index++) { + auto uses_it = filament_variant_uses.find(f_index); + if (uses_it != filament_variant_uses.end() && !uses_it->second.empty()) { + for (const FilamentVariantUse &use : uses_it->second) + resolve_slot(f_index, use.extruder_type, use.nozzle_volume_type, use.extruder_id + 1); + } + else { + ExtruderType extruder_type = (ExtruderType)(opt_extruder_type->get_at(filament_maps[f_index] - 1)); + NozzleVolumeType nozzle_volume_type = (NozzleVolumeType)(opt_nozzle_volume_type->get_at(filament_maps[f_index] - 1)); + if ((extruder_nozzle_volume_count > extruder_count || nozzle_volume_type == nvtHybrid) && !filament_volume_maps.empty()) + nozzle_volume_type = (NozzleVolumeType)(filament_volume_maps[f_index]); + resolve_slot(f_index, extruder_type, nozzle_volume_type, filament_maps[f_index]); + } + } + + const ConfigDef *config_def = this->def(); + if (!config_def) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << boost::format(", Line %1%: can not find config define")%__LINE__; + return; + } + bool has_id_key = !id_name.empty() && key_set.count(id_name) > 0; + for (auto &key : key_set) { + if (has_id_key && key == id_name) + continue; + const ConfigOptionDef *optdef = config_def->get(key); + if (!optdef) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: can not find opt define for %2%")%__LINE__%key; + continue; + } + switch (optdef->type) { + case coStrings: gather_option_values(key, this->option(key), slot_param_indices); break; + case coInts: gather_option_values(key, this->option(key), slot_param_indices); break; + case coFloats: gather_option_values(key, this->option(key), slot_param_indices); break; + case coPercents: gather_option_values(key, this->option(key), slot_param_indices); break; + case coFloatsOrPercents: gather_option_values(key, this->option(key), slot_param_indices); break; + case coBools: gather_option_values(key, this->option(key), slot_param_indices); break; + case coEnums: gather_option_values(key, this->option(key), slot_param_indices); break; + default: + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(", Line %1%: unsupported option type for %2%")%__LINE__%key; + break; + } + } + // Orca: also require a non-empty id list; get_at on an empty vector is undefined. + if (has_id_key && opt_ids && !opt_ids->values.empty()) { + // remap the id list itself last: the slot resolution above still needs the original ids + std::vector new_values; + new_values.reserve(slot_param_indices.size()); + for (int idx : slot_param_indices) + new_values.push_back(opt_ids->get_at(idx)); + const_cast(opt_ids)->values = std::move(new_values); } } @@ -10338,7 +11307,7 @@ void DynamicPrintConfig::update_diff_values_to_child_config(DynamicPrintConfig& } void compute_filament_override_value(const std::string& opt_key, const ConfigOption *opt_old_machine, const ConfigOption *opt_new_machine, const ConfigOption *opt_new_filament, const DynamicPrintConfig& new_full_config, - t_config_option_keys& diff_keys, DynamicPrintConfig& filament_overrides, std::vector& f_maps) + t_config_option_keys& diff_keys, DynamicPrintConfig& filament_overrides, std::vector& f_map_indices) { bool is_nil = opt_new_filament->is_nil(); @@ -10360,7 +11329,7 @@ void compute_filament_override_value(const std::string& opt_key, const ConfigOpt } auto opt_copy = opt_new_machine->clone(); - opt_copy->apply_override(opt_new_filament, f_maps); + opt_copy->apply_override(opt_new_filament, f_map_indices); bool changed = *opt_old_machine != *opt_copy; if (changed) { @@ -10372,6 +11341,28 @@ void compute_filament_override_value(const std::string& opt_key, const ConfigOpt } +void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector variant_index, std::set& key_set1, int stride) +{ + if (variant_index.size() > 0) { + const t_config_option_keys &keys = dest_config.keys(); + for (auto& opt : keys) { + ConfigOption *opt_src = config.option(opt); + const ConfigOption *opt_dest = dest_config.option(opt); + if (opt_src && opt_dest && (*opt_src != *opt_dest)) { + if (opt_dest->is_scalar() || (key_set1.find(opt) == key_set1.end())) + opt_src->set(opt_dest); + else { + ConfigOptionVectorBase* opt_vec_src = static_cast(opt_src); + const ConfigOptionVectorBase* opt_vec_dest = static_cast(opt_dest); + opt_vec_src->set_to_index(opt_vec_dest, variant_index, stride); + } + } + } + } + else + config.apply(dest_config, true); +} + //BBS: pass map to recording all invalid valies //FIXME localize this function. std::map validate(const FullPrintConfig &cfg, bool under_cli) diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 3b8b809c78..7b611dec9f 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -46,6 +46,14 @@ enum GCodeFlavor : unsigned char { gcfNoExtrusion }; +// How a filament is used across the model. Part of the multi-nozzle grouping data; not yet +// read by the shipping slicer — the nozzle-centric FilamentGroup engine consumes it. +enum FilamentUsageType { + SupportOnly, + ModelOnly, + Hybrid +}; + enum class FuzzySkinType { None, @@ -62,6 +70,19 @@ enum class FuzzySkinMode { Combined, }; +// ORCA: direction in which top_surface_expansion grows the top surfaces. +enum class TopSurfaceExpansionDirection { + InwardAndOutward, + Inward, + Outward, +}; + +enum class CenterOfSurfacePattern { + Each_Surface, + Each_Model, + Each_Assembly, +}; + enum class NoiseType { Classic, Perlin, @@ -97,6 +118,34 @@ enum InfillPattern : int { ipCount, }; +// Orca: Infill patterns whose alignment origin follows the fill bounding box, so the +// "separated_infills" option can re-center them per connected body. Patterns evaluated in +// absolute/global coordinates (Gyroid, TPMS, Honeycomb, CrossHatch, ...) or that are shape-relative +// (Concentric) ignore that bounding box and are therefore excluded. +inline bool is_separable_infill_pattern(InfillPattern pattern) +{ + switch (pattern) { + case ipRectilinear: + case ipAlignedRectilinear: + case ipZigZag: + case ipCrossZag: + case ipLockedZag: + case ipGrid: + case ipTriangles: + case ipStars: // tri-hexagon + case ipCubic: + case ipQuarterCubic: + case ipLateralHoneycomb: + case ipLateralLattice: + case ipHilbertCurve: + case ipArchimedeanChords: + case ipOctagramSpiral: + return true; + default: + return false; + } +} + enum class IroningType { NoIroning, TopSurfaces, @@ -144,6 +193,15 @@ enum class WallDirection Count, }; +// Orca: print order of surface fill loops/fragments for center-based fill patterns +// (Concentric, Archimedean Chords, Octagram Spiral). +enum class SurfaceFillOrder { + Default, + Outward, + Inward, + Count, +}; + //BBS enum class PrintSequence { ByLayer, @@ -300,6 +358,12 @@ enum class PerimeterGeneratorType Arachne }; +enum class ToolChangeOrderingType +{ + Default, + Cyclic, +}; + // BBS enum OverhangFanThreshold { Overhang_threshold_none = 0, @@ -335,6 +399,13 @@ enum LayerSeq { flsCustomize }; +enum FanDirection { + fdUndefine = 0, + fdLeft, + fdRight, + fdBoth +}; + static std::unordered_mapNozzleTypeEumnToStr = { {NozzleType::ntUndefine, "undefine"}, {NozzleType::ntHardenedSteel, "hardened_steel"}, @@ -418,24 +489,49 @@ enum ExtruderType { enum NozzleVolumeType { nvtStandard = 0, nvtHighFlow, - nvtMaxNozzleVolumeType = nvtHighFlow + nvtHybrid, // extruder holds a mix of Standard and High Flow sub-nozzles; selectable only for extruders + // with more than one sub-nozzle (extruder_max_nozzle_count > 1); matched as Standard for + // preset lookup and never emitted in profile variant strings + nvtTPUHighFlow, // physical variant, used on H2D/H2DP 0.4 nozzles only + // Integer values are serialized as raw ints in 3mf plate metadata and device MQTT, so they MUST stay stable. + nvtMaxNozzleVolumeType = nvtTPUHighFlow }; enum FilamentMapMode { fmmAutoForFlush, fmmAutoForMatch, fmmManual, + fmmNozzleManual, // Fully-manual filament->physical-nozzle mapping (filament_nozzle_map). Kept ordered right after fmmManual so every `< fmmManual` "is-auto" check stays correct. fmmDefault }; +// All auto modes are ordered before fmmManual (see the enum ordering note above). +inline bool is_auto_filament_map_mode(FilamentMapMode mode) { + return mode < fmmManual; +} + +// Dual-extruder purge control. Default reproduces the current +// per-extruder flush_multiplier + filament_prime_volume behaviour, so absent/default is inert. +// Saving -> reduce prime volume to 15 mm3; Fast -> use flush_multiplier_fast + filament_flush_temp_fast. +enum PrimeVolumeMode { + pvmDefault = 0, + pvmSaving, + pvmFast +}; + extern std::string get_extruder_variant_string(ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type); +// Base slot lookup: scans a variant list (paired with its 1-based extruder/filament ids) for the +// entry matching the given extruder/volume type and id. Returns 0 when no entry matches. +extern int get_config_index_base(NozzleVolumeType volume_type, ExtruderType extruder_type, int variant_id_1based, const std::vector& variant_list, const std::vector& variant_ids_1based); + static std::set get_valid_nozzle_volume_type() { std::set type; for (int i = 0; i <= nvtMaxNozzleVolumeType; ++i) { auto t = static_cast(i); - // TODO: Orca: Support hybrid - //if (t == nvtHybrid) continue; + // Hybrid is not a physical nozzle variant: presets never define it, so it must not + // produce a variant string. + if (t == nvtHybrid) continue; type.insert(t); } return type; @@ -521,11 +617,20 @@ static std::string get_bed_temp_1st_layer_key(const BedType type) } extern const std::vector filament_extruder_override_keys; +// Full override-key check incl. filament_retract_length_nc (defined outside the generator list). +extern bool is_filament_extruder_override_key(const std::string &opt_key); // for parse extruder_ams_count extern std::vector> get_extruder_ams_count(const std::vector &strs); extern std::vector save_extruder_ams_count_to_string(const std::vector> &extruder_ams_count); +// maps a full extruder variant string (e.g. "Direct Drive High Flow") to its NozzleVolumeType; nvtHybrid if unparsable +extern NozzleVolumeType convert_to_nvt_type(const std::string& variant_str); + +// for parse extruder_nozzle_stats (per-extruder physical nozzle inventory by volume type) +extern std::vector> get_extruder_nozzle_stats(const std::vector &strs); +extern std::vector save_extruder_nozzle_stats_to_string(const std::vector> &extruder_nozzle_stats); + #define CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NAME) \ template<> const t_config_enum_names& ConfigOptionEnum::get_enum_names(); \ template<> const t_config_enum_values& ConfigOptionEnum::get_enum_values(); @@ -534,6 +639,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrinterTechnology) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeFlavor) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinMode) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TopSurfaceExpansionDirection) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WipeTowerType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NoiseType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InfillPattern) @@ -561,7 +667,9 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WipeTowerWallType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ToolChangeOrderingType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PowerLossRecoveryMode) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SurfaceFillOrder) #undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS @@ -613,6 +721,23 @@ class StaticPrintConfig; // Minimum object distance for arrangement, based on printer technology. double min_object_distance(const ConfigBase &cfg); +// One (extruder type x nozzle volume type) parameter variant a filament prints through, plus a +// representative physical extruder observed using it. Ordering (and set-dedup identity) covers +// the variant pair only, so the same variant reached through two extruders keeps one config slot. +struct FilamentVariantUse +{ + ExtruderType extruder_type{etDirectDrive}; + NozzleVolumeType nozzle_volume_type{nvtStandard}; + int extruder_id{0}; // 0-based, first extruder seen using this variant + + bool operator<(const FilamentVariantUse &other) const + { + if (extruder_type != other.extruder_type) + return extruder_type < other.extruder_type; + return nozzle_volume_type < other.nozzle_volume_type; + } +}; + // Slic3r dynamic configuration, used to override the configuration // per object, per modification volume or per printing material. // The dynamic configuration is also used to store user modifications of the print global parameters, @@ -670,9 +795,26 @@ public: //BBS bool is_using_different_extruders(); bool support_different_extruders(int& extruder_count) const; + // Counts the config slots of a printer: one per (extruder x nozzle volume type) as described by + // extruder_nozzle_stats, or simply one per extruder when the stats are absent/mismatched. + // Fills nozzle_volume_types with each extruder's volume types in ascending enum order. + int get_extruder_nozzle_volume_count(int extruder_count, std::vector>& nozzle_volume_types) const; int get_index_for_extruder(int extruder_or_filament_id, std::string id_name, ExtruderType extruder_type, NozzleVolumeType nozzle_volume_type, std::string variant_name, unsigned int stride = 1) const; - void update_values_to_printer_extruders(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0); - void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, std::set& key_set, std::string id_name, std::string variant_name); + std::vector update_values_to_printer_extruders(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::vector>& nv_types, + std::set& key_set, std::string id_name, std::string variant_name, unsigned int stride = 1, unsigned int extruder_id = 0, NozzleVolumeType filament_nvt = nvtStandard); + void update_values_to_printer_extruders_for_multiple_filaments(DynamicPrintConfig& printer_config, int extruder_count, int extruder_nozzle_volume_count, std::set& key_set, std::string id_name, std::string variant_name); + // Rebuilds the per-slot filament arrays from a per-layer grouping outcome: a filament that + // prints through several (extruder x nozzle volume type) variants keeps one slot per variant + // (unlike the single-slot rebuild above), so layer-aware consumers can resolve the slot the + // current layer actually prints with. Filaments absent from filament_variant_uses keep a + // single slot resolved from filament_map / filament_volume_map. When slot_machine_indices is + // non-null it receives one machine-variant slot index per output slot (the nil-value fallback + // keying for the extruder retract overrides; a per-filament map cannot index expanded arrays). + void update_filament_config_values_for_multiple_extruders(DynamicPrintConfig& printer_config, + const std::unordered_map>& filament_variant_uses, + int extruder_count, int extruder_nozzle_volume_count, + std::set& key_set, std::string id_name, std::string variant_name, + std::vector* slot_machine_indices = nullptr); void update_non_diff_values_to_base_config(DynamicPrintConfig& new_config, const t_config_option_keys& keys, const std::set& different_keys, std::string extruder_id_name, std::string extruder_variant_name, std::set& key_set1, std::set& key_set2); @@ -698,8 +840,11 @@ extern std::set printer_options_with_variant_1; extern std::set printer_options_with_variant_2; extern std::set empty_options; +extern std::set filament_dev_options; + +extern void update_static_print_config_from_dynamic(ConfigBase& config, const DynamicPrintConfig& dest_config, std::vector variant_index, std::set& key_set1, int stride = 1); extern void compute_filament_override_value(const std::string& opt_key, const ConfigOption *opt_old_machine, const ConfigOption *opt_new_machine, const ConfigOption *opt_new_filament, const DynamicPrintConfig& new_full_config, - t_config_option_keys& diff_keys, DynamicPrintConfig& filament_overrides, std::vector& f_maps); + t_config_option_keys& diff_keys, DynamicPrintConfig& filament_overrides, std::vector& f_map_indices); void handle_legacy_sla(DynamicPrintConfig &config); @@ -1102,6 +1247,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionPercent, bottom_surface_density)) ((ConfigOptionEnum, top_surface_pattern)) ((ConfigOptionEnum, bottom_surface_pattern)) + ((ConfigOptionEnum, top_surface_fill_order)) + ((ConfigOptionEnum, bottom_surface_fill_order)) ((ConfigOptionEnum, internal_solid_infill_pattern)) ((ConfigOptionFloatOrPercent, outer_wall_line_width)) ((ConfigOptionFloatsNullable, outer_wall_speed)) @@ -1122,6 +1269,8 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, lightning_prune_angle)) ((ConfigOptionFloat, lightning_straightening_angle)) ((ConfigOptionBool, align_infill_direction_to_model)) + ((ConfigOptionEnum, center_of_surface_pattern)) + ((ConfigOptionBool, separated_infills)) ((ConfigOptionString, extra_solid_infills)) ((ConfigOptionEnum, fuzzy_skin)) ((ConfigOptionFloat, fuzzy_skin_thickness)) @@ -1187,6 +1336,9 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloatOrPercent, top_surface_line_width)) ((ConfigOptionInt, top_shell_layers)) ((ConfigOptionFloat, top_shell_thickness)) + ((ConfigOptionFloat, top_surface_expansion)) + ((ConfigOptionFloat, top_surface_expansion_margin)) + ((ConfigOptionEnum, top_surface_expansion_direction)) ((ConfigOptionFloatsNullable, top_surface_speed)) //BBS ((ConfigOptionBoolsNullable, enable_overhang_speed)) @@ -1297,6 +1449,12 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloats, machine_min_travel_rate)) // M205 S... [mm/sec] ((ConfigOptionFloats, machine_min_extruding_rate)) + // Bedslinger mass/force model: drive the per-layer Y-axis + // acceleration limit (curr_y_acceleration_limit) and the printed-mass check. + // Default 0 => inactive for every existing printer (mass model reads them as disabled). + ((ConfigOptionFloat, machine_max_force_Y)) + ((ConfigOptionFloat, machine_bed_mass_Y)) + ((ConfigOptionFloat, machine_max_printed_mass)) //resonance avoidance ported from qidi slicer ((ConfigOptionBool, resonance_avoidance)) @@ -1351,6 +1509,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionStrings, filament_vendor)) ((ConfigOptionBools, filament_is_support)) ((ConfigOptionInts, filament_printable)) + ((ConfigOptionInts, filament_extruder_compatibility)) ((ConfigOptionFloats, filament_change_length)) ((ConfigOptionFloats, filament_cost)) ((ConfigOptionStrings, default_filament_colour)) @@ -1359,14 +1518,20 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionInts, required_nozzle_HRC)) ((ConfigOptionEnum, filament_map_mode)) ((ConfigOptionInts, filament_map)) + ((ConfigOptionInts, filament_volume_map)) + ((ConfigOptionInts, filament_nozzle_map)) + ((ConfigOptionInts, filament_map_2)) //used for multi nozzle, map filament to the index identified by extruder+nozzle_volume_type //((ConfigOptionInts, filament_extruder_id)) ((ConfigOptionStrings, filament_extruder_variant)) + ((ConfigOptionInts, filament_self_index)) ((ConfigOptionBool, support_object_skip_flush)) ((ConfigOptionEnum, bed_temperature_formula)) ((ConfigOptionInts, physical_extruder_map)) ((ConfigOptionIntsNullable, nozzle_flush_dataset)) ((ConfigOptionFloatsNullable, filament_flush_volumetric_speed)) ((ConfigOptionIntsNullable, filament_flush_temp)) + // Fast-purge flush temperature; consumed only when prime_volume_mode==pvmFast. + ((ConfigOptionIntsNullable, filament_flush_temp_fast)) // BBS ((ConfigOptionBool, scan_first_layer)) ((ConfigOptionEnum, enable_power_loss_recovery)) @@ -1390,6 +1555,9 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionPercents, retract_before_wipe)) + // Orca + ((ConfigOptionPercents, retract_after_wipe)) + ((ConfigOptionFloats, retraction_length)) ((ConfigOptionFloats, retract_length_toolchange)) ((ConfigOptionInt, enable_long_retraction_when_cut)) @@ -1413,6 +1581,7 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionBool, single_extruder_multi_material)) ((ConfigOptionBool, manual_filament_change)) ((ConfigOptionBool, single_extruder_multi_material_priming)) + ((ConfigOptionEnum, toolchange_ordering)) ((ConfigOptionBool, wipe_tower_no_sparse_layers)) ((ConfigOptionString, change_filament_gcode)) ((ConfigOptionString, change_extrusion_role_gcode)) @@ -1427,12 +1596,16 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionEnumsGenericNullable,nozzle_type)) ((ConfigOptionInt, nozzle_hrc)) ((ConfigOptionBool, auxiliary_fan)) + ((ConfigOptionEnum, fan_direction)) ((ConfigOptionBool, support_air_filtration)) + ((ConfigOptionBool, support_cooling_filter)) + ((ConfigOptionBool, cooling_filter_enabled)) ((ConfigOptionEnum,printer_structure)) ((ConfigOptionBool, support_chamber_temp_control)) ((ConfigOptionEnumsGeneric, extruder_type)) ((ConfigOptionEnumsGeneric, nozzle_volume_type)) ((ConfigOptionStrings, extruder_ams_count)) + ((ConfigOptionStrings, extruder_nozzle_stats)) ((ConfigOptionInts, printer_extruder_id)) ((ConfigOptionInt, master_extruder_id)) ((ConfigOptionStrings, printer_extruder_variant)) @@ -1490,6 +1663,36 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionStrings, small_area_infill_flow_compensation_model)) ((ConfigOptionBool, has_scarf_joint_seam)) + + // Multi-nozzle + pre-heating + nozzle-change (nc) keys. Defaults are no-ops for existing + // single-nozzle printers; new slicing paths gate on extruder_max_nozzle_count > 1. + ((ConfigOptionFloat, machine_hotend_change_time)) + ((ConfigOptionFloat, machine_prepare_compensation_time)) + ((ConfigOptionBool, enable_pre_heating)) + ((ConfigOptionFloatsNullable, hotend_cooling_rate)) + ((ConfigOptionFloatsNullable, hotend_heating_rate)) + ((ConfigOptionFloats, filament_change_length_nc)) + ((ConfigOptionFloatsNullable, filament_ramming_travel_time)) + ((ConfigOptionIntsNullable, filament_pre_cooling_temperature)) + ((ConfigOptionFloatsNullable, filament_ramming_volumetric_speed)) + ((ConfigOptionFloatsNullable, filament_ramming_travel_time_nc)) + ((ConfigOptionIntsNullable, filament_pre_cooling_temperature_nc)) + ((ConfigOptionFloatsNullable, filament_ramming_volumetric_speed_nc)) + ((ConfigOptionFloatsNullable, filament_retract_length_nc)) + ((ConfigOptionIntsNullable, extruder_max_nozzle_count)) + // Printer flag: whether the printer offers the fast-purge mode selector. + // Default false; no shipping profile sets it, so the fast-purge UI stays hidden. + ((ConfigOptionBool, support_fast_purge_mode)) + + //ams chamber + ((ConfigOptionStrings, filament_dev_ams_drying_ams_limitations)) + ((ConfigOptionFloats, filament_dev_ams_drying_temperature)) + ((ConfigOptionFloats, filament_dev_ams_drying_time)) + ((ConfigOptionFloats, filament_dev_ams_drying_heat_distortion_temperature)) + ((ConfigOptionFloats, filament_dev_chamber_drying_bed_temperature)) + ((ConfigOptionFloats, filament_dev_chamber_drying_time)) + ((ConfigOptionFloats, filament_dev_drying_softening_temperature)) + ((ConfigOptionFloats, filament_dev_drying_cooling_temperature)) ) // This object is mapped to Perl as Slic3r::Config::Print. @@ -1636,7 +1839,15 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( // BBS: wipe tower is only used for priming ((ConfigOptionFloat, prime_volume)) + // Nozzle-change (nc) prime volume + pre-heat delta + ((ConfigOptionFloats, filament_prime_volume_nc)) + ((ConfigOptionFloatsNullable, filament_preheat_temperature_delta)) ((ConfigOptionFloats, flush_multiplier)) + // Fast-purge mode. Kept out of the g-code config block (banned_keys in + // GCode::append_full_config) so registering them leaves the shipping fleet's g-code byte-identical; + // consumed only on the prime_volume_mode==pvmFast / pvmSaving branch (default pvmDefault = inert). + ((ConfigOptionEnum, prime_volume_mode)) + ((ConfigOptionFloats, flush_multiplier_fast)) ((ConfigOptionFloat, z_offset)) // BBS: project filaments ((ConfigOptionFloats, filament_colour_new)) @@ -1644,6 +1855,8 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloatsNullable, nozzle_volume)) ((ConfigOptionPoints, start_end_points)) ((ConfigOptionEnum, timelapse_type)) + // Corexy farthest-point timelapse (default false → inert for existing printers) + ((ConfigOptionBool, farthest_point_timelapse)) ((ConfigOptionString, thumbnails)) // BBS: move from PrintObjectConfig ((ConfigOptionBool, independent_support_layer_height)) diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 13d7297f93..0d31f6c04c 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -4,6 +4,7 @@ #include "Print.hpp" #include "BoundingBox.hpp" #include "ClipperUtils.hpp" +#include "Clipper2Utils.hpp" #include "ElephantFootCompensation.hpp" #include "Geometry.hpp" #include "I18N.hpp" @@ -97,7 +98,7 @@ PrintObject::PrintObject(Print* print, ModelObject* model_object, const Transfor // snug height and an approximate bounding box in XY. BoundingBoxf3 bbox = model_object->raw_bounding_box(); Vec3d bbox_center = bbox.center(); - + // We may need to rotate the bbox / bbox_center from the original instance to the current instance. double z_diff = Geometry::rotation_diff_z(model_object->instances.front()->get_rotation(), instances.front().model_instance->get_rotation()); if (std::abs(z_diff) > EPSILON) { @@ -704,6 +705,72 @@ void PrintObject::infill() if (this->set_started(posInfill)) { m_print->set_status(35, L("Generating infill toolpath")); + + // Orca: precompute the object's 3D connected bodies for separated infills / per-model + // centering. Two islands belong to the same body when their slices overlap on adjacent + // layers; islands that only overlap in top-down projection but never touch (e.g. interleaved + // chain links) stay separate, matching "split to objects". Each layer island then records + // the full bounding box of its body, so its infill is centered on that body as if it were + // sliced alone. Done once here, before the parallel fill, and only when a region needs it. + bool needs_separated_components = false; + for (size_t i = 0; i < this->num_printing_regions(); ++ i) { + const PrintRegionConfig &rc = this->printing_region(i).config(); + if (rc.separated_infills || rc.center_of_surface_pattern == CenterOfSurfacePattern::Each_Model) { + needs_separated_components = true; + break; + } + } + // Fast path: the feature only changes anything when the object is made of more than one + // connected body. Detect that cheaply the same way as "Split to objects" — more than one + // model part, or a single part whose mesh is splittable (is_splittable() is cached). A single + // body already shares the object center, i.e. the default, so skip the connectivity pass. + if (needs_separated_components) { + int parts = 0; + const ModelVolume *first_part = nullptr; + for (const ModelVolume *v : this->model_object()->volumes) + if (v->is_model_part()) { ++ parts; first_part = v; } + if (parts <= 1 && ! (first_part != nullptr && first_part->is_splittable())) + needs_separated_components = false; + } + for (Layer *layer : m_layers) + layer->lslices_separated_component_bboxes.clear(); + if (needs_separated_components) { + const size_t nl = m_layers.size(); + std::vector offset(nl + 1, 0); // flat index of the first island of each layer + for (size_t i = 0; i < nl; ++ i) + offset[i + 1] = offset[i] + m_layers[i]->lslices.size(); + const size_t nreg = offset[nl]; + // Union-find over every (layer, island). + std::vector parent(nreg); + for (size_t i = 0; i < nreg; ++ i) parent[i] = i; + auto find = [&parent](size_t x) { + while (parent[x] != x) { parent[x] = parent[parent[x]]; x = parent[x]; } + return x; + }; + auto unite = [&](size_t a, size_t b) { a = find(a); b = find(b); if (a != b) parent[a] = b; }; + // Join islands that overlap between two consecutive layers. + for (size_t i = 0; i + 1 < nl; ++ i) { + const Layer *la = m_layers[i], *lb = m_layers[i + 1]; + for (size_t a = 0; a < la->lslices.size(); ++ a) + for (size_t b = 0; b < lb->lslices.size(); ++ b) + if (la->lslices_bboxes[a].overlap(lb->lslices_bboxes[b]) && + ! intersection_ex(la->lslices[a], lb->lslices[b]).empty()) + unite(offset[i] + a, offset[i + 1] + b); + } + // Full bounding box of each body, indexed by its union-find root. + std::vector body_bbox(nreg); + for (size_t i = 0; i < nl; ++ i) + for (size_t a = 0; a < m_layers[i]->lslices.size(); ++ a) + body_bbox[find(offset[i] + a)].merge(m_layers[i]->lslices_bboxes[a]); + // Store the body bbox for every island. + for (size_t i = 0; i < nl; ++ i) { + Layer *layer = m_layers[i]; + layer->lslices_separated_component_bboxes.resize(layer->lslices.size()); + for (size_t a = 0; a < layer->lslices.size(); ++ a) + layer->lslices_separated_component_bboxes[a] = body_bbox[find(offset[i] + a)]; + } + } + const auto& adaptive_fill_octree = this->m_adaptive_fill_octrees.first; const auto& support_fill_octree = this->m_adaptive_fill_octrees.second; @@ -1297,6 +1364,9 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "infill_combination_max_layer_height" || opt_key == "bottom_shell_thickness" || opt_key == "top_shell_thickness" + || opt_key == "top_surface_expansion" + || opt_key == "top_surface_expansion_margin" + || opt_key == "top_surface_expansion_direction" || opt_key == "minimum_sparse_infill_area" || opt_key == "sparse_infill_filament_id" || opt_key == "internal_solid_filament_id" @@ -1323,6 +1393,8 @@ bool PrintObject::invalidate_state_by_config_options( } else if ( opt_key == "top_surface_pattern" || opt_key == "bottom_surface_pattern" + || opt_key == "top_surface_fill_order" + || opt_key == "bottom_surface_fill_order" || opt_key == "internal_solid_infill_pattern" || opt_key == "external_fill_link_max_length" || opt_key == "infill_anchor" @@ -1330,6 +1402,8 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "top_surface_line_width" || opt_key == "top_surface_density" || opt_key == "bottom_surface_density" + || opt_key == "center_of_surface_pattern" + || opt_key == "separated_infills" || opt_key == "initial_layer_line_width" || opt_key == "small_area_infill_flow_compensation" || opt_key == "lateral_lattice_angle_1" @@ -1686,6 +1760,69 @@ void PrintObject::detect_surfaces_type() } } + // ORCA: Expand the top surfaces outward by top_surface_expansion in every direction. This + // enlarges the top solid infill and, in particular, grows it over the covered material left + // by features rising from the middle of a top surface (filling holes and joining tops so the + // features rest on it). The expansion stays inside the section it belongs to: each connected + // solid island has its own outer wall, so the top is grown within each island separately and + // clipped to it - growing one island's top across the gap into another island (which may have + // no top surface, leaving a partially filled layer) is never allowed. The top infill sits + // inside the perimeters, so the margin is measured from the walls: the island is inset by the + // band the walls consume (outer wall + inner walls) plus the configured margin, making that + // value the real clearance between the expanded top and the walls (avoiding a hull line). The + // original top is unioned back in, so where it already sits within that band it is kept as-is. + // Never claims a bottom surface. + const double top_expansion = layerm->region().config().top_surface_expansion.value; + if (top_expansion > 0. && ! top.empty()) { + const double d = scale_(top_expansion); + const auto jt = Clipper2Lib::JoinType::Miter; + const ExPolygons T = union_ex(to_expolygons(top)); + const int wall_loops = layerm->region().config().wall_loops.value; + const double wall_band = wall_loops <= 0 ? 0. : + double(layerm->flow(frExternalPerimeter).scaled_width()) + + double(layerm->flow(frPerimeter).scaled_width()) * double(wall_loops - 1); + const double margin = scale_(layerm->region().config().top_surface_expansion_margin.value); + // minimum real top to act on: ignore anything thinner than ~2 top-infill lines + const float min_top = float(layerm->flow(frTopSolidInfill).scaled_width()); + const auto direction = layerm->region().config().top_surface_expansion_direction.value; + + ExPolygons grown; + for (const ExPolygon &island : union_ex(layerm_slices_surfaces)) { + // The top infill only exists inside the perimeters, so seed and measure from the infill + // region (the island minus the wall band), not the raw slice. A section whose only + // exposed top lies in the wall band - i.e. a layer where the top is just the walls + // themselves - has no infill here and is skipped, instead of being flooded inward by + // the expansion. Thin slivers inside the infill region are dropped by the opening too. + const ExPolygons infill_region = wall_band > 0. ? offset_ex(island, -float(wall_band)) : ExPolygons{ island }; + const ExPolygons island_top = intersection_ex(T, infill_region); + if (opening_ex(island_top, min_top).empty()) + continue; // no real top infill in this section - never expand into it + + // grow by d, then keep only the part allowed by the configured direction: inward fills + // the holes/gaps left by features (clip the growth back to the top's own filled outline, + // which leaves the outer edge fixed), outward grows the outer edge toward the walls (drop + // the growth that fell into the original holes), and inward+outward keeps both. + ExPolygons expanded = offset_ex_2(island_top, d, jt); + if (direction != TopSurfaceExpansionDirection::InwardAndOutward) { + ExPolygons outline; // the top with its holes filled (same outer edge) + outline.reserve(island_top.size()); + for (const ExPolygon &ex : island_top) + outline.emplace_back(ex.contour); + outline = union_ex(outline); + expanded = direction == TopSurfaceExpansionDirection::Inward ? + intersection_ex(expanded, outline) : // only growth into the holes + diff_ex(expanded, diff_ex(outline, island_top)); // only growth past the outer edge + } + // hold the expansion clear of the walls by the configured margin + const ExPolygons allowed = margin > 0. ? offset_ex(infill_region, -float(margin)) : infill_region; + append(grown, intersection_ex(expanded, allowed)); + } + + ExPolygons new_top = diff_ex(union_ex(T, grown), to_expolygons(bottom)); + top.clear(); + surfaces_append(top, std::move(new_top), stTop); + } + #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { static int iRun = 0; @@ -2182,7 +2319,7 @@ void PrintObject::discover_vertical_shells() #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ Flow solid_infill_flow = layerm->flow(frSolidInfill); - coord_t infill_line_spacing = solid_infill_flow.scaled_spacing(); + coord_t infill_line_spacing = solid_infill_flow.scaled_spacing(); // Find a union of perimeters below / above this surface to guarantee a minimum shell thickness. Polygons shell; Polygons holes; @@ -2224,7 +2361,7 @@ void PrintObject::discover_vertical_shells() shell = std::move(shells2); else if (! shells2.empty()) { polygons_append(shell, shells2); - // Running the union_ using the Clipper library piece by piece is cheaper + // Running the union_ using the Clipper library piece by piece is cheaper // than running the union_ all at once. shell = union_(shell); } @@ -2291,12 +2428,12 @@ void PrintObject::discover_vertical_shells() Slic3r::SVG svg(debug_out_path("discover_vertical_shells-perimeters-before-union-%d.svg", debug_idx), get_extents(shell)); svg.draw(shell); svg.draw_outline(shell, "black", scale_(0.05)); - svg.Close(); + svg.Close(); } #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ #if 0 // shell = union_(shell, true); - shell = union_(shell, false); + shell = union_(shell, false); #endif #ifdef SLIC3R_DEBUG_SLICE_PROCESSING shell_ex = union_safety_offset_ex(shell); @@ -2600,7 +2737,7 @@ void PrintObject::bridge_over_infill() } } - // LIGHTNING INFILL SECTION - If lightning infill is used somewhere, we check the areas that are going to be bridges, and those that rely on the + // LIGHTNING INFILL SECTION - If lightning infill is used somewhere, we check the areas that are going to be bridges, and those that rely on the // lightning infill under them get expanded. This somewhat helps to ensure that most of the extrusions are anchored to the lightning infill at the ends. // It requires modifying this instance of print object in a specific way, so that we do not invalidate the pointers in our surfaces_by_layer structure. if (has_lightning_infill) { @@ -3575,13 +3712,13 @@ static void clamp_feature_filament_to_valid(ConfigOptionInt &opt, size_t num_ext opt.value = 1; } -PrintObjectConfig PrintObject::object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders) +PrintObjectConfig PrintObject::object_config_from_model_object(const PrintObjectConfig &default_object_config, const ModelObject &object, size_t num_extruders, std::vector& variant_index) { PrintObjectConfig config = default_object_config; { DynamicPrintConfig src_normalized(object.config.get()); src_normalized.normalize_fdm(); - config.apply(src_normalized, true); + update_static_print_config_from_dynamic(config, src_normalized, variant_index, print_options_with_variant, 1); } // Clamp invalid extruders to the default extruder (with index 1). clamp_exturder_to_default(config.support_filament, num_extruders); @@ -3609,7 +3746,7 @@ struct FeatureFilamentOverrideMask bool inner_wall_filament_id = false; }; -static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPrintConfig &in, FeatureFilamentOverrideMask &feature_overrides) +static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPrintConfig &in, FeatureFilamentOverrideMask &feature_overrides, std::vector& variant_index) { // 1) Explicit feature filament values take precedence over base extruder fallback. auto *opt_extruder = in.opt(key_extruder); @@ -3650,8 +3787,18 @@ static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPr else if (it->first == "inner_wall_filament_id") feature_overrides.inner_wall_filament_id = false; } - } else - my_opt->set(it->second.get()); + } else { + if (*my_opt != *(it->second)) { + if (my_opt->is_scalar() || variant_index.empty() || (print_options_with_variant.find(it->first) == print_options_with_variant.end())) + my_opt->set(it->second.get()); + //my_opt->set(it->second.get()); + else { + ConfigOptionVectorBase* opt_vec_src = static_cast(my_opt); + const ConfigOptionVectorBase* opt_vec_dest = static_cast(it->second.get()); + opt_vec_src->set_to_index(opt_vec_dest, variant_index, 1); + } + } + } } // 3) Apply base extruder only to features that were not explicitly overridden. @@ -3671,7 +3818,7 @@ static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPr } } -PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders) +PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &default_or_parent_region_config, const DynamicPrintConfig *layer_range_config, const ModelVolume &volume, size_t num_extruders, std::vector& variant_index) { PrintRegionConfig config = default_or_parent_region_config; FeatureFilamentOverrideMask feature_overrides; @@ -3689,17 +3836,17 @@ PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &defau if (volume.is_model_part()) { // default_or_parent_region_config contains the Print's PrintRegionConfig. // Override with ModelObject's PrintRegionConfig values. - apply_to_print_region_config(config, volume.get_object()->config.get(), feature_overrides); + apply_to_print_region_config(config, volume.get_object()->config.get(), feature_overrides, variant_index); } else { // default_or_parent_region_config contains parent PrintRegion config, which already contains ModelVolume's config. } - apply_to_print_region_config(config, volume.config.get(), feature_overrides); + apply_to_print_region_config(config, volume.config.get(), feature_overrides, variant_index); if (! volume.material_id().empty()) - apply_to_print_region_config(config, volume.material()->config.get(), feature_overrides); + apply_to_print_region_config(config, volume.material()->config.get(), feature_overrides, variant_index); if (layer_range_config != nullptr) { // Not applicable to modifiers. assert(volume.is_model_part()); - apply_to_print_region_config(config, *layer_range_config, feature_overrides); + apply_to_print_region_config(config, *layer_range_config, feature_overrides, variant_index); } // Resolve feature defaults and clamp invalid extruders to index 1. clamp_feature_filament_to_valid(config.sparse_infill_filament_id, num_extruders); @@ -3749,7 +3896,7 @@ void PrintObject::update_slicing_parameters() } // Orca: XYZ shrinkage compensation has introduced the const Vec3d &object_shrinkage_compensation parameter to the function below -SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation) +SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full_config, const ModelObject &model_object, float object_max_z, const Vec3d &object_shrinkage_compensation, std::vector variant_index) { PrintConfig print_config; PrintObjectConfig object_config; @@ -3759,14 +3906,14 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full default_region_config.apply(full_config, true); // BBS size_t filament_extruders = print_config.filament_diameter.size(); - object_config = object_config_from_model_object(object_config, model_object, filament_extruders); + object_config = object_config_from_model_object(object_config, model_object, filament_extruders, variant_index); std::vector object_extruders; for (const ModelVolume* model_volume : model_object.volumes) if (model_volume->is_model_part()) { PrintRegion::collect_object_printing_extruders( print_config, - region_config_from_model_volume(default_region_config, nullptr, *model_volume, filament_extruders), + region_config_from_model_volume(default_region_config, nullptr, *model_volume, filament_extruders, variant_index), object_config.brim_type != btNoBrim && object_config.brim_width > 0., object_extruders); for (const std::pair &range_and_config : model_object.layer_config_ranges) @@ -3778,7 +3925,7 @@ SlicingParameters PrintObject::slicing_parameters(const DynamicPrintConfig &full range_and_config.second.has("bottom_surface_filament_id")) PrintRegion::collect_object_printing_extruders( print_config, - region_config_from_model_volume(default_region_config, &range_and_config.second.get(), *model_volume, filament_extruders), + region_config_from_model_volume(default_region_config, &range_and_config.second.get(), *model_volume, filament_extruders, variant_index), object_config.brim_type != btNoBrim && object_config.brim_width > 0., object_extruders); } diff --git a/src/libslic3r/Support/SupportSpotsGenerator.hpp b/src/libslic3r/Support/SupportSpotsGenerator.hpp index 22e85c021e..615158dabb 100644 --- a/src/libslic3r/Support/SupportSpotsGenerator.hpp +++ b/src/libslic3r/Support/SupportSpotsGenerator.hpp @@ -22,7 +22,7 @@ struct Params : /*max_acceleration(max_acceleration), */raft_layers_count(raft_layers_count), brim_type(brim_type), brim_width(brim_width) { if (filament_types.size() > 1) { - BOOST_LOG_TRIVIAL(warning) + BOOST_LOG_TRIVIAL(debug) << "SupportSpotsGenerator does not currently handle different materials properly, only first will be used"; } if (filament_types.empty() || filament_types[0].empty()) { diff --git a/src/libslic3r/Utils.hpp b/src/libslic3r/Utils.hpp index a76857dc4b..62b2eeb78e 100644 --- a/src/libslic3r/Utils.hpp +++ b/src/libslic3r/Utils.hpp @@ -102,6 +102,9 @@ const std::string& var_dir(); // Return a full resource path for a file_name. std::string var(const std::string &file_name); +// Snap a nozzle diameter to the closest supported value and format it as a string (e.g. 0.4 -> "0.4"). +std::string format_diameter_to_str(double diameter, int precision = 1); + // Set a path with various static definition data (for example the initial config bundles). void set_resources_dir(const std::string &path); // Return a full path to the resources directory. diff --git a/src/libslic3r/calib.hpp b/src/libslic3r/calib.hpp index f69ad3e1a3..fc8e0cddc0 100644 --- a/src/libslic3r/calib.hpp +++ b/src/libslic3r/calib.hpp @@ -83,6 +83,8 @@ public: NozzleVolumeType nozzle_volume_type; BedType bed_type; float nozzle_diameter; + int nozzle_pos_id{-1}; + std::string nozzle_sn; std::string filament_id; std::string setting_id; std::string name; @@ -93,6 +95,8 @@ public: this->extruder_id = other.extruder_id; this->nozzle_volume_type = other.nozzle_volume_type; this->nozzle_diameter = other.nozzle_diameter; + this->nozzle_pos_id = other.nozzle_pos_id; + this->nozzle_sn = other.nozzle_sn; this->filament_id = other.filament_id; this->setting_id = other.setting_id; this->name = other.name; @@ -123,7 +127,9 @@ public: int ams_id = 0; int slot_id = 0; int cali_idx = -1; + int nozzle_pos_id = -1; //-1 means no nozzle pos float nozzle_diameter; + std::string nozzle_sn; std::string filament_id; std::string setting_id; std::string name; @@ -140,7 +146,9 @@ struct PACalibIndexInfo int ams_id = 0; int slot_id = 0; int cali_idx = -1; // -1 means default + int nozzle_pos_id = -1; //-1 means no nozzle pos float nozzle_diameter; + std::string nozzle_sn; std::string filament_id; }; @@ -148,7 +156,9 @@ struct PACalibExtruderInfo { int extruder_id = 0; NozzleVolumeType nozzle_volume_type; + int nozzle_pos_id = -1; //-1 means no nozzle pos float nozzle_diameter; + std::string nozzle_sn; std::string filament_id = ""; bool use_extruder_id{true}; bool use_nozzle_volume_type{true}; diff --git a/src/libslic3r/miniz_extension.cpp b/src/libslic3r/miniz_extension.cpp index 424e76462c..53a4a8e9de 100644 --- a/src/libslic3r/miniz_extension.cpp +++ b/src/libslic3r/miniz_extension.cpp @@ -1,6 +1,8 @@ #include +#include #include "miniz_extension.hpp" +#include "Utils.hpp" #if defined(_MSC_VER) || defined(__MINGW64__) #include "boost/nowide/cstdio.hpp" @@ -15,6 +17,33 @@ namespace Slic3r { namespace { +std::string decode_zip_unicode_path_extra_field(const std::string& extra, const std::string& path) +{ + size_t offset = 0; + const mz_uint32 path_crc = mz_crc32(0, reinterpret_cast(path.data()), path.size()); + + while (offset + 4 <= extra.size()) { + const unsigned char* field = reinterpret_cast(extra.data() + offset); + const std::uint16_t len = field[2] | (static_cast(field[3]) << 8); + if (offset + 4 + len > extra.size()) + break; + + if (field[0] == 0x75 && field[1] == 0x70 && len >= 5 && field[4] == 0x01) { + const mz_uint32 stored_crc = + static_cast(field[5]) | + (static_cast(field[6]) << 8) | + (static_cast(field[7]) << 16) | + (static_cast(field[8]) << 24); + if (stored_crc == path_crc) + return std::string(extra.data() + offset + 9, extra.data() + offset + 4 + len); + } + + offset += 4 + len; + } + + return Slic3r::decode_path(path.c_str()); +} + bool open_zip(mz_zip_archive *zip, const char *fname, bool isread) { if (!zip) return false; @@ -76,6 +105,16 @@ bool open_zip_writer(mz_zip_archive *zip, const std::string &fname) bool close_zip_reader(mz_zip_archive *zip) { return close_zip(zip, true); } bool close_zip_writer(mz_zip_archive *zip) { return close_zip(zip, false); } +std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat) +{ + if (stat.m_is_utf8) + return stat.m_filename; + + std::string extra(1024, 0); + const size_t extra_size = mz_zip_reader_get_extra(zip, stat.m_file_index, extra.data(), extra.size()); + return decode_zip_unicode_path_extra_field(extra.substr(0, extra_size > 0 ? extra_size - 1 : 0), stat.m_filename); +} + MZ_Archive::MZ_Archive() { mz_zip_zero_struct(&arch); diff --git a/src/libslic3r/miniz_extension.hpp b/src/libslic3r/miniz_extension.hpp index 006226bf24..1a1c96689f 100644 --- a/src/libslic3r/miniz_extension.hpp +++ b/src/libslic3r/miniz_extension.hpp @@ -10,6 +10,7 @@ bool open_zip_reader(mz_zip_archive *zip, const std::string &fname_utf8); bool open_zip_writer(mz_zip_archive *zip, const std::string &fname_utf8); bool close_zip_reader(mz_zip_archive *zip); bool close_zip_writer(mz_zip_archive *zip); +std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat); class MZ_Archive { public: diff --git a/src/libslic3r/utils.cpp b/src/libslic3r/utils.cpp index 131369d212..5f429f076a 100644 --- a/src/libslic3r/utils.cpp +++ b/src/libslic3r/utils.cpp @@ -8,6 +8,10 @@ #include #include #include +#include +#include +#include +#include #include "format.hpp" #include "Platform.hpp" @@ -1497,6 +1501,15 @@ std::string format_memsize(size_t bytes, unsigned int decimals) } } +std::string format_diameter_to_str(double diameter, int precision) +{ + double candidates[] = {0.2, 0.4, 0.6, 0.8}; + double best = *std::min_element(std::begin(candidates), std::end(candidates), [diameter](double a, double b) { return std::abs(a - diameter) < std::abs(b - diameter); }); + std::ostringstream oss; + oss << std::fixed << std::setprecision(precision) << best; + return oss.str(); +} + // Returns platform-specific string to be used as log output or parsed in SysInfoDialog. // The latter parses the string with (semi)colons as separators, it should look about as // "desc1: value1; desc2: value2" or similar (spaces should not matter). diff --git a/src/slic3r/CMakeLists.txt b/src/slic3r/CMakeLists.txt index 38bd235ff2..688035c6db 100644 --- a/src/slic3r/CMakeLists.txt +++ b/src/slic3r/CMakeLists.txt @@ -28,6 +28,8 @@ set(SLIC3R_GUI_SOURCES GUI/AMSMaterialsSetting.hpp GUI/AMSSetting.cpp GUI/AMSSetting.hpp + GUI/AMSDryControl.cpp + GUI/AMSDryControl.hpp GUI/AmsWidgets.cpp GUI/AmsWidgets.hpp GUI/Auxiliary.cpp @@ -417,6 +419,8 @@ set(SLIC3R_GUI_SOURCES GUI/Project.hpp GUI/PublishDialog.cpp GUI/PublishDialog.hpp + GUI/PurgeModeDialog.cpp + GUI/PurgeModeDialog.hpp GUI/RammingChart.cpp GUI/RammingChart.hpp GUI/RecenterDialog.cpp @@ -504,6 +508,8 @@ set(SLIC3R_GUI_SOURCES GUI/Widgets/AMSControl.hpp GUI/Widgets/AMSItem.cpp GUI/Widgets/AMSItem.hpp + GUI/Widgets/MultiNozzleSync.cpp + GUI/Widgets/MultiNozzleSync.hpp GUI/Widgets/AxisCtrlButton.cpp GUI/Widgets/AxisCtrlButton.hpp GUI/SafetyOptionsDialog.hpp diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index ec7deeb82a..335dd6b825 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -495,7 +495,29 @@ void GLVolume::render_with_outline(const GUI::Size& cnv_size) simple_render(shader, model_objects, colors); return; } - + // 0th. render pass, render the model using stencil buffer + glsafe(::glEnable(GL_STENCIL_TEST)); + glsafe(::glStencilMask(0xFF)); + glsafe(::glStencilOp(GL_KEEP, GL_REPLACE, GL_REPLACE)); + glsafe(::glClearStencil(0)); + glsafe(::glClear(GL_STENCIL_BUFFER_BIT)); + glsafe(::glStencilFunc(GL_ALWAYS, 0xFF, 0xFF)); + if (tverts_range == std::make_pair(0, -1)) + model.render(shader); + else + model.render(this->tverts_range, shader); + glsafe(::glStencilFunc(GL_NOTEQUAL, 0xFF, 0xFF)); + glsafe(::glStencilMask(0x00)); + shader->set_uniform("is_outline", true); + shader->set_uniform("screen_size", Vec2f{cnv_size.get_width(), cnv_size.get_height()}); + if (tverts_range == std::make_pair(0, -1)) + model.render(shader); + else + model.render(this->tverts_range, shader); + shader->set_uniform("is_outline", false); + glsafe(::glStencilMask(0xFF)); + glsafe(::glDisable(GL_STENCIL_TEST)); + // render the outline using depth buffer and discard the pixels that are not on the outline // 1st. render pass, render the model into a separate render target that has only depth buffer GLuint depth_fbo = 0; GLuint depth_tex = 0; @@ -1024,7 +1046,8 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, const Transform3d& projection_matrix, const GUI::Size& cnv_size, std::function filter_func, - bool partly_inside_enable) const + bool partly_inside_enable, + std::vector * printable_heights) const { GLVolumeWithIdAndZList to_render = volumes_to_render(volumes, type, view_matrix, filter_func); if (to_render.empty()) @@ -1108,7 +1131,24 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, //use -1 ad a invalid type shader->set_uniform("print_volume.type", -1); } - + + // Per-extruder printable-height shading. The flag is set to + // 2.0 only for multi-extruder printers (two per-extruder heights); otherwise it is forced to 0.0 + // on every render so no stale flag survives a multi->single-extruder plate switch, keeping the + // shared gouraud shader pixel-identical for single-extruder printers. When active the height + // branch reads print_volume.xy_data (the bed rect), so set it explicitly here. + std::array extruder_printable_heights = {0.0f, 0.0f, 0.0f}; + if (printable_heights != nullptr && printable_heights->size() > 1) { + extruder_printable_heights[0] = 2.0f; + extruder_printable_heights[1] = static_cast((*printable_heights)[0]); + extruder_printable_heights[2] = static_cast((*printable_heights)[1]); + shader->set_uniform("extruder_printable_heights", extruder_printable_heights); + shader->set_uniform("print_volume.xy_data", m_print_volume.data); + } + else { + shader->set_uniform("extruder_printable_heights", extruder_printable_heights); + } + shader->set_uniform("volume_world_matrix", volume.first->world_matrix()); shader->set_uniform("slope.actived", m_slope.isGlobalActive && !volume.first->is_modifier && !volume.first->is_wipe_tower); shader->set_uniform("slope.volume_world_normal_matrix", static_cast(volume.first->world_matrix().matrix().block(0, 0, 3, 3).inverse().transpose().cast())); diff --git a/src/slic3r/GUI/3DScene.hpp b/src/slic3r/GUI/3DScene.hpp index 76d10620d9..1217d32182 100644 --- a/src/slic3r/GUI/3DScene.hpp +++ b/src/slic3r/GUI/3DScene.hpp @@ -497,7 +497,10 @@ public: const Transform3d& projection_matrix, const GUI::Size& cnv_size, std::function filter_func = std::function(), - bool partly_inside_enable =true + bool partly_inside_enable =true, + // Per-extruder printable heights (extruder_printable_height); null / size<=1 + // leaves the shader's extruder_printable_heights flag at 0.0 (single-extruder = inert). + std::vector * printable_heights = nullptr ) const; // Clear the geometry diff --git a/src/slic3r/GUI/AMSDryControl.cpp b/src/slic3r/GUI/AMSDryControl.cpp new file mode 100644 index 0000000000..9efe7faa87 --- /dev/null +++ b/src/slic3r/GUI/AMSDryControl.cpp @@ -0,0 +1,1864 @@ +#include "AMSDryControl.hpp" +#include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "GUI_App.hpp" +#include "I18N.hpp" + +#include "slic3r/GUI/DeviceCore/DevExtruderSystem.h" + +#include "slic3r/GUI/DeviceCore/DevManager.h" + +#include "slic3r/GUI/MsgDialog.hpp" + +#include "slic3r/GUI/Widgets/AnimaController.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" +#include "slic3r/GUI/Widgets/ComboBox.hpp" +#include "slic3r/GUI/Widgets/ProgressBar.hpp" +#include "slic3r/GUI/DeviceCore/DevUtilBackend.h" + +#include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Preset.hpp" + +#include + +namespace Slic3r { namespace GUI { + +const int AMS_DRY_STATUS_IMAGE_SIZE = 96; + +static std::string get_humidity_level_img_path(int humidity_percent) +{ + const int num_levels = 5; + int hum_level; + + if (humidity_percent <= 100 / num_levels) { + hum_level = 5; + } else if (humidity_percent <= 100 / num_levels * 2) { + hum_level = 4; + } else if (humidity_percent <= 100 / num_levels * 3) { + hum_level = 3; + } else if (humidity_percent <= 100 / num_levels * 4) { + hum_level = 2; + } else { + hum_level = 1; + } + + if (wxGetApp().dark_mode()) { + return "hum_level" + std::to_string(hum_level) + "_no_num_dark"; + } else { + return "hum_level" + std::to_string(hum_level) + "_no_num_light"; + } + +} + +static std::string get_dry_status_img_path(DevAmsType type, DevAms::DryStatus status, DevAms::DrySubStatus sub_status) +{ + std::string img_name = "dev_ams_dry_ctr_"; + switch (type) { + case DevAmsType::N3S: + img_name += "n3s"; + break; + case DevAmsType::N3F: + img_name += "n3f"; + break; + default: + return ""; + } + + img_name += "_"; + switch (status) { + case DevAms::DryStatus::Error: + img_name += "error"; + return img_name; + } + + switch (sub_status) { + case DevAms::DrySubStatus::Heating: + img_name += "heating"; + return img_name; + case DevAms::DrySubStatus::Dehumidify: + img_name += "dehumidifying"; + return img_name; + } + + return ""; +} + +FilamentItemPanel::FilamentItemPanel(wxWindow* parent, const wxString& text, const std::string& icon_name, wxWindowID id) + : wxPanel(parent, id) + , m_icon_name(icon_name) +{ + SetBackgroundColour(wxColour("#F0F0F1")); // Light gray background + SetMinSize(wxSize(FromDIP(64), FromDIP(106))); // Width: 64, Height: 106 + SetSize(wxSize(FromDIP(64), FromDIP(106))); // Fixed size + + // Create sizer for vertical layout + wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); + + // Top section with text - moved to be closer to center + wxBoxSizer* top_sizer = new wxBoxSizer(wxVERTICAL); + top_sizer->AddStretchSpacer(5); + + m_text_label = new Label(this, text); + m_text_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour(*wxBLACK))); + m_text_label->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#F0F0F1"))); + m_text_label->SetFont(Label::Body_12); + m_text_label->Wrap(FromDIP(40)); + top_sizer->Add(m_text_label, 0, wxALIGN_CENTER_HORIZONTAL); + + top_sizer->AddStretchSpacer(1); // Increased bottom spacer to push text down + sizer->Add(top_sizer, 1, wxEXPAND); + + // Bottom section with icon - vertically centered in bottom half + wxBoxSizer* bottom_sizer = new wxBoxSizer(wxVERTICAL); + bottom_sizer->AddStretchSpacer(1); + + m_icon_bitmap = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap); + m_icon_bitmap->SetBackgroundColour(StateColor::darkModeColorFor(wxColour("#F0F0F1"))); + m_icon_bitmap->SetMinSize(wxSize(FromDIP(24), FromDIP(24))); + m_icon_bitmap->SetMaxSize(wxSize(FromDIP(24), FromDIP(24))); + bottom_sizer->Add(m_icon_bitmap, 0, wxALIGN_CENTER_HORIZONTAL); + + bottom_sizer->AddStretchSpacer(1); + sizer->Add(bottom_sizer, 1, wxEXPAND); + + SetSizer(sizer); + + // Bind events + Bind(wxEVT_PAINT, &FilamentItemPanel::OnPaint, this); + Bind(wxEVT_SIZE, &FilamentItemPanel::OnSize, this); + + SetIcon(icon_name); + wxGetApp().UpdateDarkUI(this); +} + +void FilamentItemPanel::SetText(const wxString& text) +{ + m_text_label->SetLabel(text); + Layout(); +} + +void FilamentItemPanel::SetIcon(const std::string& icon_name) +{ + m_icon_name = icon_name; + if (!icon_name.empty()) { + try { + m_icon = ScalableBitmap(this, icon_name, 20); + m_icon.msw_rescale(); + m_icon_bitmap->SetBitmap(m_icon.bmp()); + } catch (Exception&) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": failed to load filament icon"; + m_icon_bitmap->SetBitmap(wxNullBitmap); + } + } else { + m_icon_bitmap->SetBitmap(wxNullBitmap); + } + m_icon_bitmap->Refresh(); +} + +void FilamentItemPanel::msw_rescale() +{ + if (m_icon_bitmap && !m_icon_name.empty()) { + m_icon.msw_rescale(); + m_icon_bitmap->SetBitmap(m_icon.bmp()); + m_icon_bitmap->Refresh(); + } + Layout(); +} + +void FilamentItemPanel::OnPaint(wxPaintEvent& event) +{ + wxPaintDC dc(this); + wxSize size = GetSize(); + + // bool is_dark_mode = wxGetApp().dark_mode(); + wxColour backgroundColor = StateColor::darkModeColorFor(wxColour("#F0F0F1")); + wxColour borderColor = StateColor::darkModeColorFor(wxColour("#DBDBDB")); + + // Draw white background rectangle with rounded corners inside the thick vertical lines + dc.SetBrush(wxBrush(backgroundColor)); + dc.SetPen(wxPen(backgroundColor)); + dc.DrawRectangle(FromDIP(6), FromDIP(12), size.GetWidth() - FromDIP(12), size.GetHeight() - 2 * FromDIP(12)); + + // Draw much thicker vertical rounded rectangles on left and right (3 times thicker) + dc.SetBrush(wxBrush(wxColour(borderColor))); + dc.SetPen(wxPen(wxColour(borderColor))); + dc.DrawRoundedRectangle(FromDIP(0), FromDIP(0), FromDIP(6), size.GetHeight(), FromDIP(6)); // Left rounded rectangle + dc.DrawRoundedRectangle(size.GetWidth() - FromDIP(6), FromDIP(0), FromDIP(6), size.GetHeight(), FromDIP(6)); // Right rounded rectangle + + // Draw thin horizontal rounded rectangles on top and bottom (moved closer to center by half the distance) + dc.SetBrush(wxBrush(wxColour(borderColor))); + dc.SetPen(wxPen(wxColour(borderColor))); + dc.DrawRoundedRectangle(FromDIP(6), FromDIP(12), size.GetWidth() - FromDIP(12), FromDIP(3), FromDIP(1)); // Top rounded rectangle + dc.DrawRoundedRectangle(FromDIP(6), size.GetHeight() - FromDIP(13), size.GetWidth() - FromDIP(12), FromDIP(3), FromDIP(1)); // Bottom rounded rectangle +} + +void FilamentItemPanel::OnSize(wxSizeEvent& event) +{ + Refresh(); + event.Skip(); +} + +// class AMSFilamentPanel + +AMSFilamentPanel::AMSFilamentPanel(wxWindow* parent, const wxString& ams_name, wxWindowID id) + : wxPanel(parent, id) +{ + SetBackgroundColour(wxColour("#DBDBDB")); + + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + + // Filament items section + m_filament_container = new wxPanel(this); + m_filament_container->SetBackgroundColour(wxColour("#F0F0F1")); + m_filament_sizer = new wxBoxSizer(wxHORIZONTAL); + m_filament_container->SetSizer(m_filament_sizer); + + // AMS name section + m_ams_name_label = new Label(this, ams_name); + m_ams_name_label->SetForegroundColour(wxColour("#858585")); + m_ams_name_label->SetFont(Label::Body_14); + m_ams_name_label->SetBackgroundColour(wxColour("#DBDBDB")); + + main_sizer->Add(m_filament_container, 1, wxEXPAND | wxALL, 0); + main_sizer->Add(m_ams_name_label, 0, wxALIGN_LEFT | wxALL, FromDIP(5)); + + SetSizer(main_sizer); + wxGetApp().UpdateDarkUI(this); +} + +void AMSFilamentPanel::AddFilamentItem(FilamentItemPanel* panel) +{ + if (panel) { + panel->Reparent(m_filament_container); + m_filament_sizer->Add(panel, 0, wxALL, FromDIP(5)); + m_filament_items.push_back(panel); + Layout(); + } +} + +void AMSFilamentPanel::AddFilamentItem(const wxString& text, const std::string& icon_name) +{ + FilamentItemPanel* item = new FilamentItemPanel(m_filament_container, text, icon_name); + m_filament_items.push_back(item); + m_filament_sizer->Add(item, 0, wxALL, FromDIP(5)); + Layout(); +} + +void AMSFilamentPanel::SetAmsName(const wxString& ams_name) +{ + m_ams_name_label->SetLabel(ams_name); + Layout(); +} + +void AMSFilamentPanel::Clear() +{ + m_filament_sizer->Clear(true); + m_filament_items.clear(); +} + +void AMSFilamentPanel::msw_rescale() +{ + for (auto item : m_filament_items) { + item->msw_rescale(); + } + Layout(); +} + + +AMSDryCtrWin::AMSDryCtrWin(wxWindow *parent) + :DPIDialog(parent, wxID_ANY, _L("AMS Dryness Control"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) +{ + create(); +} + +AMSDryCtrWin::~AMSDryCtrWin() +{ + if (m_progress_timer) { + delete m_progress_timer; + } +} + + +wxScrolledWindow* AMSDryCtrWin::create_preview_scrolled_window(wxWindow* parent) +{ + wxScrolledWindow* panel = new wxScrolledWindow(parent, wxID_ANY); + panel->SetScrollRate(10, 0); + panel->SetSize(AMS_ITEMS_PANEL_SIZE); + panel->SetMinSize(AMS_ITEMS_PANEL_SIZE); + panel->SetBackgroundColour(AMS_CONTROL_DEF_BLOCK_BK_COLOUR); + + return panel; +} + +wxBoxSizer* AMSDryCtrWin::create_humidity_status_section(wxPanel* parent) +{ + wxBoxSizer* image_sizer = new wxBoxSizer(wxVERTICAL); + + m_humidity_img = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap); + image_sizer->Add(m_humidity_img, 1, wxALIGN_CENTER_HORIZONTAL, 0); + + m_humidity_img->SetBitmap(wxNullBitmap); + + // Create a horizontal sizer for description and icon + wxBoxSizer* desc_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_image_description_icon = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap); + m_image_description_icon->SetBackgroundColour(*wxWHITE); + m_image_description_icon->SetMinSize(wxSize(FromDIP(20), FromDIP(20))); + m_image_description_icon->SetMaxSize(wxSize(FromDIP(20), FromDIP(20))); + m_image_description_icon->Show(false); + desc_sizer->Add(m_image_description_icon, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(5)); + + m_image_description = new Label(parent, _L("Idle")); + m_image_description->SetFont(Label::Head_14); + m_image_description->SetForegroundColour(*wxBLACK); + m_image_description->SetBackgroundColour(*wxWHITE); + desc_sizer->Add(m_image_description, 0, wxALIGN_CENTER_VERTICAL); + + image_sizer->Add(desc_sizer, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + + return image_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_description_item(wxPanel* parent, const wxString& title, Label*& dataLabel) +{ + wxBoxSizer* item_sizer = new wxBoxSizer(wxVERTICAL); + + Label* titleLabel = new Label(parent, title); + titleLabel->SetForegroundColour(*wxBLACK); + titleLabel->SetFont(Label::Body_16); + + dataLabel = new Label(parent, wxT("--")); + dataLabel->SetForegroundColour(*wxBLACK); + dataLabel->SetFont(Label::Body_14); + + item_sizer->AddStretchSpacer(); + item_sizer->Add(titleLabel, 0, wxALIGN_CENTER | wxALL, FromDIP(2)); + item_sizer->Add(dataLabel, 0, wxALIGN_CENTER | wxALL, FromDIP(2)); + item_sizer->AddStretchSpacer(); + + return item_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_status_descriptions_section(wxPanel* parent) +{ + wxBoxSizer* desc_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* hum_desc_sizer = create_description_item(parent, _L("Humidity"), m_humidity_data_label); + desc_sizer->Add(hum_desc_sizer, 1, wxEXPAND, FromDIP(1)); + + wxStaticLine* vert_separator = new wxStaticLine(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL); + desc_sizer->Add(vert_separator, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5)); + + wxBoxSizer* temp_desc_sizer = create_description_item(parent, _L("Temperature"), m_temperature_data_label); + desc_sizer->Add(temp_desc_sizer, 1, wxEXPAND, FromDIP(1)); + + m_time_descrition_container = new wxBoxSizer(wxHORIZONTAL); + wxStaticLine* vert_separator2 = new wxStaticLine(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_VERTICAL); + m_time_descrition_container->Add(vert_separator2, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5)); + + wxBoxSizer* time_desc_sizer = create_description_item(parent, _L("Left Time"), m_time_data_label); + m_time_descrition_container->Add(time_desc_sizer, 1, wxEXPAND, FromDIP(1)); + + desc_sizer->Add(m_time_descrition_container, 1, wxEXPAND, 0); + // m_time_descrition_container->Show(false); + + return desc_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_left_panel(wxPanel* parent) +{ + wxBoxSizer* left_sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* image_section = create_humidity_status_section(parent); + left_sizer->Add(image_section, 1, wxEXPAND | wxALL, FromDIP(5)); + + wxBoxSizer* descriptions_section = create_status_descriptions_section(parent); + left_sizer->Add(descriptions_section, 0, wxEXPAND | wxALL, FromDIP(20)); + + return left_sizer; +} + +Button* AMSDryCtrWin::create_button(wxPanel* parent, const wxString& title, + const wxColour& background_color, const wxColour& border_color, const wxColour& text_color) +{ + Button* button = new Button(parent, title); + + // Create state colors for background + StateColor bg_color( + std::pair(AMS_CONTROL_DISABLE_COLOUR, StateColor::Disabled), + std::pair(background_color.ChangeLightness(80), StateColor::Pressed), + std::pair(background_color.ChangeLightness(120), StateColor::Hovered), + std::pair(background_color, StateColor::Normal) + ); + + // Create state colors for border + StateColor bd_color( + std::pair(AMS_CONTROL_WHITE_COLOUR, StateColor::Disabled), + std::pair(border_color, StateColor::Enabled) + ); + + button->SetBackgroundColor(bg_color); + button->SetBorderColor(bd_color); + button->SetTextColor(text_color); + button->SetFont(Label::Body_14); + + // Auto-size button based on text content with padding + wxSize best_size = button->GetBestSize(); + int padding_width = FromDIP(4); + int padding_height = FromDIP(2); + wxSize final_size(best_size.GetWidth() + padding_width, best_size.GetHeight() + padding_height); + button->SetMinSize(final_size); + + return button; +} + +wxBoxSizer* AMSDryCtrWin::create_normal_state_panel(wxPanel* parent) +{ + wxBoxSizer* normal_state_sizer = new wxBoxSizer(wxVERTICAL); + + Label* description_label = new Label(parent, _L("Filament Drying Settings")); + description_label->SetForegroundColour(*wxBLACK); + description_label->SetFont(Label::Head_14); + normal_state_sizer->Add(description_label, 0, wxALL, FromDIP(5)); + + // Part 2: ComboBox for material selection + wxBoxSizer* combo_sizer = new wxBoxSizer(wxHORIZONTAL); + m_trays_combo = new ComboBox(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(-1, FromDIP(26)), 0, nullptr, wxCB_READONLY); + m_trays_combo->SetFont(Label::Body_14); + + combo_sizer->Add(m_trays_combo, 1, wxEXPAND); + normal_state_sizer->Add(combo_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); + + m_trays_combo->Bind(wxEVT_COMBOBOX, &AMSDryCtrWin::OnFilamentSelectionChanged, this); + + // part 3 time and temperature + // Temperature part + wxBoxSizer* temp_sizer = new wxBoxSizer(wxHORIZONTAL); + m_temperature_input = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(80), -1)); + m_temperature_input->SetMaxLength(3); // Limit to 3 digits + + m_temperature_input->Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { + int keycode = event.GetKeyCode(); + if (keycode >= '0' && keycode <= '9') { + event.Skip(); + } else if (keycode == WXK_BACK || keycode == WXK_DELETE || keycode == WXK_LEFT || keycode == WXK_RIGHT) { + event.Skip(); + } + }); + + m_temperature_input->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { + m_next_button->Disable(); + m_start_button->Disable(); + }); + + m_temperature_input->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); + m_temperature_input->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + Label* temp_unit_label = new Label(parent, wxString::FromUTF8("℃")); + temp_unit_label->SetForegroundColour(*wxBLACK); + temp_sizer->Add(m_temperature_input, 1, wxRIGHT, FromDIP(1)); + temp_sizer->Add(temp_unit_label, 0, wxALIGN_CENTER_VERTICAL); + + // Time part + wxBoxSizer* time_sizer = new wxBoxSizer(wxHORIZONTAL); + m_time_input = new wxTextCtrl(parent, wxID_ANY, "", wxDefaultPosition, wxSize(FromDIP(100), -1)); + m_time_input->SetMaxLength(3); // Limit to 3 digits + + m_time_input->Bind(wxEVT_CHAR, [this](wxKeyEvent& event) { + int keycode = event.GetKeyCode(); + if (keycode >= '0' && keycode <= '9') { + event.Skip(); + } else if (keycode == WXK_BACK || keycode == WXK_DELETE || keycode == WXK_LEFT || keycode == WXK_RIGHT) { + event.Skip(); + } + }); + + m_time_input->Bind(wxEVT_TEXT, [this](wxCommandEvent&) { + m_next_button->Disable(); + m_start_button->Disable(); + }); + + m_time_input->SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); + m_time_input->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + Label* time_unit_label = new Label(parent, "H"); + time_unit_label->SetForegroundColour(*wxBLACK); + time_sizer->Add(m_time_input, 1, wxRIGHT, FromDIP(1)); + time_sizer->Add(time_unit_label, 0, wxALIGN_CENTER_VERTICAL); + + wxBoxSizer* input_sizer = new wxBoxSizer(wxHORIZONTAL); + input_sizer->Add(temp_sizer, 1, wxRIGHT, FromDIP(10)); + input_sizer->Add(time_sizer, 1, 0); + normal_state_sizer->Add(input_sizer, 0, wxEXPAND | wxALL, FromDIP(5)); + + // Part 4: Abnormal description/message area + m_normal_description = new Label(parent, ""); + m_normal_description->SetForegroundColour(wxColour("#F09A17")); + m_normal_description->SetFont(Label::Body_12); + normal_state_sizer->Add(m_normal_description, 0, wxALL, FromDIP(5)); + + // Part 5: Start button + m_next_button = create_button( + parent, + _L("Start"), + AMS_CONTROL_BRAND_COLOUR, // Background color - green + AMS_CONTROL_BRAND_COLOUR, // Border color - green + wxColour("#FFFFFE") // Text color - white + ); + + m_next_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent& event) { + m_main_simplebook->SetSelection(1); + }); + + normal_state_sizer->Add(m_next_button, 0, wxALL, FromDIP(5)); + m_next_button->Disable(); + + m_stop_button = create_button( + parent, + _L("Stop"), + wxColour(255, 0, 0), // Background color - red + wxColour(255, 0, 0), // Border color - red + wxColour("#FFFFFE") // Text color - white + ); + + m_stop_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent& event) { + auto fila_system = get_fila_system(); + if (!fila_system) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::start_sending_drying_command: Invalid FilaSystem Pointer"; + return; + } + + fila_system->CtrlAmsStopDrying(std::stoi(m_ams_info.m_ams_id)); + // Temporarily show stopping state, then restore after 2 seconds + if (m_stop_button) { + m_stop_button->SetLabel(_L("Stopping")); + update_button_size(m_stop_button); // Adjust button size for longer text + m_stop_button->Disable(); + m_stop_button->Layout(); + m_stop_button->GetParent()->Layout(); // Relayout parent container + m_stop_button->Refresh(); + + m_stop_button_restore_deadline.reset(); + m_stop_button_restore_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(2); + } + }); + + m_stop_button->Show(false); + normal_state_sizer->Add(m_stop_button, 0, wxALL, FromDIP(5)); + + return normal_state_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_cannot_dry_panel(wxPanel* parent) +{ + wxBoxSizer* abnormal_sizer = new wxBoxSizer(wxVERTICAL); + + Label* description_label = new Label(parent, _L("Unable to dry temporarily due to ...")); + description_label->SetForegroundColour(*wxBLACK); + description_label->SetFont(Label::Head_16); + description_label->Wrap(FromDIP(300)); + abnormal_sizer->Add(description_label, 0, wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + // Add a description label for the abnormal state + m_cannot_dry_description_label = new Label(parent, ("")); + m_cannot_dry_description_label->SetForegroundColour(*wxBLACK); + m_cannot_dry_description_label->SetFont(Label::Body_14); + m_cannot_dry_description_label->Wrap(FromDIP(250)); // Wrap text to fit within panel + + abnormal_sizer->Add(m_cannot_dry_description_label, 0, wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + // Unload button shown only when ConsumableAtAmsOutlet reason is active + m_unload_button = create_button( + parent, + _L("Unload"), + AMS_CONTROL_BRAND_COLOUR, // Background color - light gray + AMS_CONTROL_BRAND_COLOUR, // Border color - gray + *wxWHITE // Text color - white + ); + + m_unload_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent& event) { + auto fila_system = get_fila_system(); + if (!fila_system) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::unload_button: Invalid FilaSystem Pointer"; + return; + } + + MachineObject* obj = fila_system->GetOwner(); + if (!obj) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::unload_button: Invalid MachineObject Pointer"; + return; + } + + obj->command_ams_change_filament(false, m_ams_info.m_ams_id, "255"); + + m_unload_button->Disable(); + m_unload_button_restore_deadline.reset(); + m_unload_button_restore_deadline = std::chrono::steady_clock::now() + std::chrono::seconds(5); + }); + + m_unload_button->Show(false); + abnormal_sizer->Add(m_unload_button, 0, wxALL, FromDIP(5)); + + return abnormal_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_drying_error_panel(wxPanel* parent) +{ + wxBoxSizer* err_sizer = new wxBoxSizer(wxVERTICAL); + Label* description_label = new Label(parent, _L("Drying Error")); + description_label->SetForegroundColour(*wxRED); + description_label->SetFont(Label::Body_14); // Wrap text to fit within panel + err_sizer->Add(description_label, 0, wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + Label* additional_description_label = new Label(parent, _L("Please check the Assistant for troubleshooting")); + additional_description_label->SetForegroundColour(*wxBLACK); + additional_description_label->SetFont(Label::Body_14); // Wrap text to fit within panel + err_sizer->Add(additional_description_label, 0, wxALIGN_CENTER_VERTICAL, FromDIP(10)); + + return err_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_right_panel(wxPanel* parent) +{ + wxBoxSizer* right_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_normal_state_sizer = create_normal_state_panel(parent); + m_cannot_dry_sizer = create_cannot_dry_panel(parent); + m_dry_error_sizer = create_drying_error_panel(parent); + + right_sizer->Add(m_normal_state_sizer, 1, wxEXPAND); + right_sizer->Add(m_cannot_dry_sizer, 1, wxEXPAND); + + m_cannot_dry_sizer->Show(false); + m_dry_error_sizer->Show(false); + + return right_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_main_content_section(wxPanel* parent) +{ + wxBoxSizer* content_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* left_panel = create_left_panel(parent); + content_sizer->Add(left_panel, 2, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5)); + left_panel->SetMinSize(wxSize(FromDIP(250), -1)); + + wxBoxSizer* right_panel = create_right_panel(parent); + content_sizer->Add(right_panel, 1, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5)); + right_panel->SetMinSize(wxSize(FromDIP(250), -1)); + + return content_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_main_page_sizer(wxPanel* parent) +{ + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + + wxBoxSizer* content_section = create_main_content_section(parent); + main_sizer->Add(content_section, 1, wxEXPAND | wxALL, FromDIP(5)); + + return main_sizer; +} + +wxBoxSizer* AMSDryCtrWin::create_guide_info_filament(wxPanel* parent) +{ + wxBoxSizer* filament_section = new wxBoxSizer(wxHORIZONTAL); + + m_ams_filament_panel = new AMSFilamentPanel(parent, ""); + + filament_section->Add(m_ams_filament_panel, 0, wxEXPAND | wxALL | wxALIGN_CENTER_HORIZONTAL, FromDIP(5)); + + return filament_section; +} + +wxBoxSizer* AMSDryCtrWin::create_guide_info_section(wxPanel* parent) +{ + wxBoxSizer* info_section = new wxBoxSizer(wxVERTICAL); + + // Part 1: Title + m_guide_title_label = new Label(parent, _L("Please remove and store the filament (as shown).")); + m_guide_title_label->SetForegroundColour(*wxBLACK); + m_guide_title_label->SetFont(Label::Head_18); + info_section->Add(m_guide_title_label, 0, wxEXPAND | wxALL, FromDIP(5)); + + // Part 2: Description + m_guide_description_label = new Label(parent, _L("The AMS can rotate the filament which is properly stored, providing better drying results.")); + m_guide_description_label->SetForegroundColour(*wxBLACK); + m_guide_description_label->SetFont(Label::Body_14); + m_guide_description_label->Wrap(FromDIP(300)); // Wrap text to fit within panel + info_section->Add(m_guide_description_label, 0, wxEXPAND | wxALL, FromDIP(5)); + + // Part 3: filament panel + wxBoxSizer* fila_section = create_guide_info_filament(parent); + info_section->Add(fila_section, 0, wxEXPAND | wxALL, FromDIP(5)); + + // Part 4: Circular toggle with description + wxBoxSizer* toggle_section = new wxBoxSizer(wxHORIZONTAL); + + m_rotate_spool_toggle = new wxCheckBox(parent, wxID_ANY, ""); + m_rotate_spool_toggle->SetValue(false); + + m_rotate_spool_toggle->Bind(wxEVT_CHECKBOX, [this](wxCommandEvent& event) { + bool is_checked = event.IsChecked(); + // Add toggle behavior logic here + }); + + toggle_section->Add(m_rotate_spool_toggle, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10)); + + // Toggle description + Label* toggle_description = new Label(parent, _L("Rotate spool when drying"), LB_AUTO_WRAP); + toggle_description->SetForegroundColour(*wxBLACK); + toggle_description->SetFont(Label::Body_12); + toggle_section->Add(toggle_description, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND, 0); + + info_section->Add(toggle_section, 0, wxEXPAND | wxALL, FromDIP(5)); + + return info_section; +} + +wxBoxSizer* AMSDryCtrWin::create_guide_right_section(wxPanel* parent) +{ + wxBoxSizer* right_section = new wxBoxSizer(wxVERTICAL); + + // Upper part: Image section + m_image_placeholder = new wxStaticBitmap(parent, wxID_ANY, wxNullBitmap); + m_guide_image = ScalableBitmap(parent, "dev_ams_dry_ctr_filament_in_chamber", 256); + m_image_placeholder->SetBitmap(m_guide_image.bmp()); + + wxBoxSizer* image_container = new wxBoxSizer(wxHORIZONTAL); + image_container->AddStretchSpacer(1); + image_container->Add(m_image_placeholder, 0, wxALL, FromDIP(5)); + + right_section->Add(image_container, 0, wxEXPAND | wxALL, FromDIP(5)); + + wxBoxSizer* buttons_container = new wxBoxSizer(wxHORIZONTAL); + buttons_container->AddStretchSpacer(1); + + m_back_button = create_button( + parent, + wxString::FromUTF8(_CTX_utf8(L_CONTEXT("Back", "amsdrying"), "amsdrying")), + wxColour("#F8F8F8"), // Background color - light gray + wxColour("#D0D0D0"), // Border color - gray + *wxBLACK // Text color - black + ); + + m_back_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent& event) { + m_main_simplebook->SetSelection(0); + }); + + buttons_container->Add(m_back_button, 0, wxALL, FromDIP(5)); + + m_start_button = create_button( + parent, + _L("Start"), + AMS_CONTROL_BRAND_COLOUR, // Background color - green + AMS_CONTROL_BRAND_COLOUR, // Border color - green + wxColour("#FFFFFE") // Text color - white + ); + + m_start_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent& event) { + m_main_simplebook->SetSelection(2); + m_progress_gauge->SetValue(0); + + m_progress_timer->Start(70); + m_progress_value = 0; + start_sending_drying_command(); + }); + + buttons_container->Add(m_start_button, 0, wxALL, FromDIP(5)); + + right_section->Add(buttons_container, 0, wxEXPAND | wxALL, FromDIP(5)); + + return right_section; +} + +wxBoxSizer* AMSDryCtrWin::create_guide_page_sizer(wxPanel* parent) +{ + wxBoxSizer* guide_sizer = new wxBoxSizer(wxHORIZONTAL); + + wxBoxSizer* info_section = create_guide_info_section(parent); + guide_sizer->Add(info_section, 1, wxEXPAND | wxALL, FromDIP(10)); + + wxBoxSizer* right_section = create_guide_right_section(parent); + guide_sizer->Add(right_section, 0, wxEXPAND | wxALL, FromDIP(10)); + + return guide_sizer; +} + +void AMSDryCtrWin::start_sending_drying_command() +{ + auto fila_system = get_fila_system(); + if (!fila_system) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::start_sending_drying_command: Invalid FilaSystem Pointer"; + return; + } + + if (m_temperature_input->GetValue().IsEmpty() || m_time_input->GetValue().IsEmpty()) { + // Show error message to user + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::start_sending_drying_command: Time or temperature is empty"; + return; + } + + long temperature, time; + if (!m_temperature_input->GetValue().ToLong(&temperature) || + !m_time_input->GetValue().ToLong(&time)) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::start_sending_drying_command: Failed to convert temperature or time"; + return; + } + + int tray_index; + tray_index = m_trays_combo->GetSelection(); + if (m_tray_ids.empty() || tray_index < 0 || tray_index >= m_tray_ids.size()) { + BOOST_LOG_TRIVIAL(warning) << "AMSDryCtrWin::start_sending_drying_command: Invalid tray_index " << tray_index + << ", m_tray_ids.size=" << m_tray_ids.size(); + return; + } + + int cooling_temp = 50; + std::optional preset = DevUtilBackend::GetFilamentDryingPreset(m_tray_ids[tray_index].filament_id); + if (preset.has_value()) { + cooling_temp = static_cast(preset.value().filament_dev_drying_softening_temperature); + } + + fila_system->CtrlAmsStartDryingHour(std::stoi(m_ams_info.m_ams_id), m_tray_ids[tray_index].filament_type, + temperature, time, m_rotate_spool_toggle->GetValue(), cooling_temp, false); + + m_dry_setting.m_filament_names[m_ams_info.m_ams_id] = m_tray_ids[tray_index].filament_name; + m_dry_setting.m_filament_type[m_ams_info.m_ams_id] = m_tray_ids[tray_index].filament_type; + m_dry_setting.m_dry_temp[m_ams_info.m_ams_id] = temperature; + m_dry_setting.m_dry_time[m_ams_info.m_ams_id] = time; +} + +void AMSDryCtrWin::OnProgressTimer(wxTimerEvent& event) +{ + m_progress_value += 1; + + if (m_progress_value <= 100) + m_progress_gauge->SetValue(m_progress_value); + + if (m_progress_value == 1) { // First tick, reset message index + m_progress_message_index = 0; + if (!m_progress_text.empty()) { + m_progress_title->SetLabel(m_progress_text[0]); + } + } + else if (m_progress_value % 15 == 0) { // Approximately every second + m_progress_message_index++; + if (m_progress_message_index < m_progress_text.size()) { + m_progress_title->SetLabel(m_progress_text[m_progress_message_index]); + m_progress_title->Refresh(); + } + } + + if (m_progress_value >= 100 && !is_dry_ctr_idle()) { + m_progress_value = 0; + m_progress_timer->Stop(); + m_main_simplebook->SetSelection(0); + } +} + +void AMSDryCtrWin::restore_stop_button_if_deadline_passed() +{ + if (m_stop_button_restore_deadline.has_value()) { + if (std::chrono::steady_clock::now() >= m_stop_button_restore_deadline.value()) { + if (m_stop_button) { + m_stop_button->SetLabel(_L("Stop")); + update_button_size(m_stop_button); // Adjust button size back to original + m_stop_button->Enable(); + m_stop_button->Layout(); + m_stop_button->GetParent()->Layout(); + m_stop_button->Refresh(); + } + m_stop_button_restore_deadline.reset(); + } + } +} + +void AMSDryCtrWin::restore_unload_button_if_deadline_passed() +{ + if (m_unload_button_restore_deadline.has_value()) { + if (std::chrono::steady_clock::now() >= m_unload_button_restore_deadline.value()) { + if (m_unload_button) { + m_unload_button->Enable(); + } + m_unload_button_restore_deadline.reset(); + } + } +} + +void AMSDryCtrWin::update_button_size(Button* button) +{ + if (!button) return; + + // Reset MinSize first to avoid accumulation of size + button->SetMinSize(wxSize(-1, -1)); + + // Recalculate button size based on current text and DPI settings + wxSize best_size = button->GetBestSize(); + int padding_width = FromDIP(4); + int padding_height = FromDIP(2); + wxSize final_size(best_size.GetWidth() + padding_width, best_size.GetHeight() + padding_height); + button->SetMinSize(final_size); +} + +void AMSDryCtrWin::OnShow(wxShowEvent& event) +{ + if (event.IsShown()) { + wxGetApp().UpdateDlgDarkUI(this); + msw_rescale(); + } + event.Skip(); +} + +void AMSDryCtrWin::OnClose(wxCloseEvent& event) +{ + if (m_progress_timer && m_progress_timer->IsRunning()) { + m_progress_timer->Stop(); + } + + if (m_progress_gauge) { + m_progress_gauge->SetValue(0); + } + + m_progress_value = 0; + m_progress_message_index = 0; + + if (m_main_simplebook) { + m_main_simplebook->SetSelection(0); + } + + if (m_progress_title && !m_progress_text.empty()) { + m_progress_title->SetLabel(m_progress_text[0]); + } + + // Clean up and restore stop button state + if (m_stop_button) { + m_stop_button->SetLabel(_L("Stop")); + update_button_size(m_stop_button); // Adjust button size back to original + m_stop_button->Enable(); + m_stop_button->Layout(); + m_stop_button->GetParent()->Layout(); + m_stop_button->Refresh(); + } + m_stop_button_restore_deadline.reset(); + + // Clean up unload button state + if (m_unload_button) { + m_unload_button->Enable(); + } + m_unload_button_restore_deadline.reset(); + + event.Skip(); +} + +wxBoxSizer* AMSDryCtrWin::create_progress_page_sizer(wxPanel* parent) +{ + wxBoxSizer* progress_sizer = new wxBoxSizer(wxVERTICAL); + + m_progress_title = new Label(parent, m_progress_text[0]); + m_progress_title->SetForegroundColour(*wxBLACK); + m_progress_title->SetFont(Label::Body_16); + + progress_sizer->Add(0, 0, 1, wxEXPAND, 0); // Spacer + progress_sizer->Add(m_progress_title, 0, wxALIGN_CENTER | wxALL, FromDIP(30)); + + m_progress_gauge = new ProgressBar(parent, wxID_ANY, 100, wxDefaultPosition, wxSize(FromDIP(300), FromDIP(8))); + m_progress_gauge->SetValue(0); + m_progress_gauge->SetHeight(FromDIP(8)); + + progress_sizer->Add(m_progress_gauge, 0, wxALIGN_CENTER | wxALL, FromDIP(10)); + progress_sizer->Add(0, 0, 1, wxEXPAND, 0); + + return progress_sizer; +} + +void AMSDryCtrWin::create() +{ + // set title icon + SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); + this->SetDoubleBuffered(true); + std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); + SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); + + SetSize(wxSize(FromDIP(700), FromDIP(500))); + SetMinSize(wxSize(FromDIP(700), FromDIP(500))); + SetMaxSize(wxSize(FromDIP(700), FromDIP(500))); + + m_main_simplebook = new wxSimplebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize); + + // Create main page + m_original_page = new wxPanel(m_main_simplebook, wxID_ANY); + m_original_page->SetBackgroundColour(*wxWHITE); + wxBoxSizer* main_sizer = create_main_page_sizer(m_original_page); + m_original_page->SetSizer(main_sizer); + + m_main_simplebook->AddPage(m_original_page, "Main Page"); + + m_guide_page = new wxPanel(m_main_simplebook, wxID_ANY); + m_guide_page->SetBackgroundColour(*wxWHITE); + wxBoxSizer* guide_sizer = create_guide_page_sizer(m_guide_page); + m_guide_page->SetSizer(guide_sizer); + m_main_simplebook->AddPage(m_guide_page, "Guide Page"); + + // Create progress page + m_progress_page = new wxPanel(m_main_simplebook, wxID_ANY); + m_progress_page->SetBackgroundColour(*wxWHITE); + wxBoxSizer* progress_sizer = create_progress_page_sizer(m_progress_page); + m_progress_page->SetSizer(progress_sizer); + m_main_simplebook->AddPage(m_progress_page, "Progress Page"); + + m_progress_timer = new wxTimer(this, wxID_ANY); + Bind(wxEVT_TIMER, &AMSDryCtrWin::OnProgressTimer, this, m_progress_timer->GetId()); + + Bind(wxEVT_CLOSE_WINDOW, &AMSDryCtrWin::OnClose, this); + + wxBoxSizer* top_level_sizer = new wxBoxSizer(wxVERTICAL); + top_level_sizer->Add(m_main_simplebook, 1, wxEXPAND | wxALL, FromDIP(10)); + + Bind(wxEVT_SHOW, &AMSDryCtrWin::OnShow, this); + + SetSizer(top_level_sizer); + Layout(); + Refresh(); + wxGetApp().UpdateDlgDarkUI(this); +} + +void AMSDryCtrWin::on_dpi_changed(const wxRect &suggested_rect) +{ + msw_rescale(); +} + +void AMSDryCtrWin::msw_rescale() +{ + if (!IsShown()) { + return; + } + + if (m_ams_filament_panel) {m_ams_filament_panel->msw_rescale();} + if (m_trays_combo) {m_trays_combo->Rescale(); m_trays_combo->Layout(); m_trays_combo->SetFont(Label::Body_14), m_trays_combo->Refresh();} + if (m_humidity_img && m_humidity_image.bmp().IsOk()) {m_humidity_image.msw_rescale(); m_humidity_img->SetBitmap(m_humidity_image.bmp());} + if (m_image_placeholder && m_guide_image.bmp().IsOk()) {m_guide_image.msw_rescale();m_image_placeholder->SetBitmap(m_guide_image.bmp());} + if (m_image_description_icon && m_description_icon_bitmap.bmp().IsOk()) {m_description_icon_bitmap.msw_rescale(); m_image_description_icon->SetBitmap(m_description_icon_bitmap.bmp());} + + // Rescale and update button sizes based on text content + if (m_next_button) { + m_next_button->Rescale(); + update_button_size(m_next_button); + m_next_button->Layout(); + m_next_button->Refresh(); + } + if (m_stop_button) { + m_stop_button->Rescale(); + update_button_size(m_stop_button); + m_stop_button->Layout(); + m_stop_button->Refresh(); + } + if (m_start_button) { + m_start_button->Rescale(); + update_button_size(m_start_button); + m_start_button->Layout(); + m_start_button->Refresh(); + } + if (m_back_button) { + m_back_button->Rescale(); + update_button_size(m_back_button); + m_back_button->Layout(); + m_back_button->Refresh(); + } + if (m_unload_button) { + m_unload_button->Rescale(); + update_button_size(m_unload_button); + m_unload_button->Layout(); + m_unload_button->Refresh(); + } + + if (m_guide_page) {m_guide_page->Layout();} + if (m_original_page) {m_original_page->Layout();} + + Fit(); + Layout(); + Refresh(); +} + +void AMSDryCtrWin::set_ams_id(const std::string& ams_id) +{ + m_ams_info.m_ams_id = ams_id; + m_is_ams_changed = true; +} + +void AMSDryCtrWin::update_img_description(DevAms::DryStatus status, DevAms::DrySubStatus sub_status) +{ + if (status == DevAms::DryStatus::Off || status == DevAms::DryStatus::Cooling) { + m_image_description->SetLabel(_L("Idle")); + m_image_description_icon->Show(false); + return; + } + + // Determine label text for non-idle states + wxString label_text; + if (status == DevAms::DryStatus::Error) { + label_text = _L("Drying"); + } else if (sub_status == DevAms::DrySubStatus::Heating) { + label_text = _L("Drying-Heating"); + } else if (sub_status == DevAms::DrySubStatus::Dehumidify) { + label_text = _L("Drying-Dehumidifying"); + } else { + m_image_description_icon->Show(false); + return; + } + + m_image_description->SetLabel(label_text); + + try { + m_description_icon_bitmap = ScalableBitmap(this, "dev_ams_dry_ctr_heating_icon", 20); + m_description_icon_bitmap.msw_rescale(); + m_image_description_icon->SetBitmap(m_description_icon_bitmap.bmp()); + m_image_description_icon->Show(true); + } catch (Exception&) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Error loading drying icon"; + m_image_description_icon->Show(false); + } +} + +int AMSDryCtrWin::update_image(DevAmsType model, DevAms::DryStatus status, DevAms::DrySubStatus sub_status, int humidity_percent) +{ + if (model == m_ams_info.m_model && status == m_ams_info.m_dry_status + && sub_status == m_ams_info.m_dry_sub_status && humidity_percent == m_ams_info.m_humidity_percent) { + return 0; + } + + std::string img_path; + + if (status == DevAms::DryStatus::Off && sub_status == DevAms::DrySubStatus::Off) { + img_path = get_humidity_level_img_path(humidity_percent); + } else { + img_path = get_dry_status_img_path(model, status, sub_status); + } + + if (img_path.empty()) { + return 0; + } + + m_humidity_image = ScalableBitmap(this, img_path, AMS_DRY_STATUS_IMAGE_SIZE); + m_humidity_img->SetBitmap(m_humidity_image.bmp()); + + update_img_description(status, sub_status); + + return 1; +} + +bool AMSDryCtrWin::check_values_changed(DevAms* dev_ams) +{ + bool changed = false; + + if (m_ams_info.m_model != dev_ams->GetAmsType()) { + m_ams_info.m_model = dev_ams->GetAmsType(); + changed = true; + } + + if (dev_ams->GetDryStatus().has_value() && m_ams_info.m_dry_status != dev_ams->GetDryStatus()) { + m_ams_info.m_dry_status = dev_ams->GetDryStatus().value(); + changed = true; + } + + if (dev_ams->GetDrySubStatus().has_value() && m_ams_info.m_dry_sub_status != dev_ams->GetDrySubStatus()) { + m_ams_info.m_dry_sub_status = dev_ams->GetDrySubStatus().value(); + changed = true; + } + + if (m_ams_info.m_humidity_percent != dev_ams->GetHumidityPercent()) { + m_ams_info.m_humidity_percent = dev_ams->GetHumidityPercent(); + changed = true; + } + + return changed; +} + +void AMSDryCtrWin::update_normal_description(DevAms* dev_ams) +{ + if (m_tray_ids.empty() || m_trays_combo->GetSelection() >= m_tray_ids.size()) { return; } + + FilamentBaseInfo info = m_tray_ids[m_trays_combo->GetSelection()]; + wxString warning_text; + bool can_enable_button = true; + long temp_val = 0, time_val = 0; + m_temperature_input->GetValue().ToLong(&temp_val); + m_time_input->GetValue().ToLong(&time_val); + std::optional preset = DevUtilBackend::GetFilamentDryingPreset(info.filament_id); + auto total_dry = preset.has_value() ? preset.value().ams_limitations : std::unordered_set(); + + struct AmsTempLimit { DevAmsType type; int min_temp; int max_temp; const char* name; }; + static const AmsTempLimit ams_limits[] = { + { DevAmsType::N3F, 45, 65, "AMS2" }, + { DevAmsType::N3S, 45, 85, "AMS-S" } + }; + + for (const auto& lim : ams_limits) { + if (dev_ams->GetAmsType() == lim.type) { + if (temp_val > lim.max_temp) { + wxString msg = wxString(lim.name) + _L(" maximum drying temperature is ") + wxString::Format(wxT("%d"), lim.max_temp) + wxString::FromUTF8("°C."); + warning_text += msg + "\n"; + can_enable_button = false; + } else if (temp_val < lim.min_temp) { + wxString msg = wxString(lim.name) + _L(" minimum drying temperature is ") + wxString::Format(wxT("%d"), lim.min_temp) + wxString::FromUTF8("°C."); + warning_text += msg + "\n"; + can_enable_button = false; + } + if (total_dry.find(lim.type) == total_dry.end()) { + warning_text += _L("This filament may not be completely dried.") + "\n\n"; + } + break; + } + } + + if (m_printer_status.m_is_printing && temp_val > m_ams_info.m_recommand_dry_temp) { + warning_text += _L("This AMS is currently printing. To ensure print quality, the drying temperature cannot exceed the recommended drying temperature.") + "\n"; + can_enable_button = false; + } else if (preset.has_value()) { + // Only check heat distortion temperature when AMS has filament inserted; + // empty AMS only needs to respect the device hardware temperature limit. + bool has_filament_inserted = false; + for (const auto& tray_pair : dev_ams->GetTrays()) { + if (tray_pair.second && tray_pair.second->is_exists) { + has_filament_inserted = true; + break; + } + } + if (has_filament_inserted) { + auto limit_temperature = preset.value().filament_dev_ams_drying_heat_distortion_temperature; + if (temp_val > limit_temperature) { + warning_text += _L("The temperature shall not exceed the filament's heat distortion temperature") + "(" + + wxString::Format(wxT("%d"), static_cast(limit_temperature)) + wxString::FromUTF8("°C)\n"); + can_enable_button = false; + } + } + } + + if (time_val < 1) { + warning_text += _L("Minimum time value cannot be less than 1.") + "\n"; + can_enable_button = false; + } else if (time_val > 24) { + warning_text += _L("Maximum time value cannot be greater than 24.") + "\n"; + can_enable_button = false; + } + + m_next_button->Enable(can_enable_button); + m_normal_description->SetLabel(warning_text); + m_normal_description->Wrap(FromDIP(250)); + m_normal_description->GetParent()->Layout(); +} + +void AMSDryCtrWin::update_normal_state(DevAms* dev_ams) +{ + if (is_dry_ctr_idle(dev_ams)) { + m_next_button->Show(true); + m_normal_description->Show(true); + m_trays_combo->Enable(); + m_temperature_input->SetEditable(true); + m_time_input->SetEditable(true); + + m_stop_button->Hide(); + m_dry_error_sizer->Show(false); + } else if (is_dry_ctr_err(dev_ams)) { + m_dry_error_sizer->Show(true); + m_next_button->Hide(); + m_normal_description->Hide(); + + m_trays_combo->Hide(); + m_temperature_input->Hide(); + m_time_input->Hide(); + m_stop_button->Show(true); + } else { + m_next_button->Hide(); + m_normal_description->Hide(); + + m_trays_combo->Disable(); + m_temperature_input->SetEditable(false); + m_time_input->SetEditable(false); + m_stop_button->Show(true); + m_dry_error_sizer->Show(false); + } + + if (m_temperature_input->GetValue().IsEmpty() || m_time_input->GetValue().IsEmpty()) { + m_next_button->Disable(); + m_start_button->Disable(); + } else { + m_next_button->Enable(); + } + + update_normal_description(dev_ams); +} + +void AMSDryCtrWin::OnFilamentSelectionChanged(wxCommandEvent& event) +{ + int selectionIndex = event.GetSelection(); + wxString selectedFilament = event.GetString(); + + auto fila_system = get_fila_system(); + if (!fila_system) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::OnFilamentSelectionChanged: Invalid FilaSystem Pointer"; + return; + } + + DevAms* dev_ams = fila_system->GetAmsById(m_ams_info.m_ams_id); + if (!dev_ams) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::OnFilamentSelectionChanged: Invalid AMS id"; + return; + } + + std::optional preset = DevUtilBackend::GetFilamentDryingPreset(m_tray_ids[selectionIndex].filament_id); + if (preset.has_value()) { + DevFilamentDryingPreset info = preset.value(); + if (m_printer_status.m_is_printing) { + m_temperature_input->SetValue(std::to_string(static_cast(info.filament_dev_ams_drying_temperature_on_print[dev_ams->GetAmsType()]))); + m_time_input->SetValue(std::to_string(static_cast(info.filament_dev_ams_drying_time_on_print[dev_ams->GetAmsType()]))); + } else { + m_temperature_input->SetValue(std::to_string(static_cast(info.filament_dev_ams_drying_temperature_on_idle[dev_ams->GetAmsType()]))); + m_time_input->SetValue(std::to_string(static_cast(info.filament_dev_ams_drying_time_on_idle[dev_ams->GetAmsType()]))); + } + } + + update_filament_guide_info(dev_ams); +} + +wxString get_cannot_reason_text(DevAms::CannotDryReason reason) +{ + wxString cannot_reason_text; + switch (reason) + { + case DevAms::CannotDryReason::InsufficientPower: + cannot_reason_text = "*" + _L("Insufficient power") + "\n"; + cannot_reason_text += _L(" Too many AMS drying simultaneously. Please plug in the power or stop other drying processes before starting.") + "\n"; + break; + case DevAms::CannotDryReason::AmsBusy: + cannot_reason_text = "*" + _L("AMS is busy") + "\n"; + cannot_reason_text += _L(" AMS is calibrating | reading RFID | loading/unloading material, please wait.") + "\n"; + break; + case DevAms::CannotDryReason::ConsumableAtAmsOutlet: + cannot_reason_text = "*" + _L("Filament in AMS outlet") + "\n"; + cannot_reason_text += _L(" The high drying temperature may cause AMS blockage, please unload first."); + break; + case DevAms::CannotDryReason::InitiatingAmsDrying: + cannot_reason_text = "*" + _L("Initiating AMS drying") + "\n"; + break; + case DevAms::CannotDryReason::NotSupportedIn2dMode: + cannot_reason_text = "*" + _L("Not supported in 2D mode") + "\n"; + break; + case DevAms::CannotDryReason::DryingInProgress: + cannot_reason_text = "*" + _L("Task in progress") + "\n"; + cannot_reason_text += _L(" The AMS might be in use during Task.") + "\n"; + break; + case DevAms::CannotDryReason::Upgrading: + cannot_reason_text = "*" + _L("Upgrading") + "\n"; + cannot_reason_text += _L(" Firmware update in progress, please wait...") + "\n"; + break; + case DevAms::CannotDryReason::InsufficientPowerNeedPluginPower: + cannot_reason_text = "*" + _L("Insufficient power") + "\n"; + cannot_reason_text += _L(" Please plug in the power and then use the drying function.") + "\n"; + break; + case DevAms::CannotDryReason::FilamentAtAmsOutletManualUnload: + cannot_reason_text = "*" + _L("Filament in AMS outlet") + "\n"; + cannot_reason_text += _L(" The high drying temperature may cause AMS blockage. Please unload the filament manually before proceeding.") + "\n"; + break; + default: + cannot_reason_text = "*" + _L("System is busy") + "\n"; + cannot_reason_text += _L(" Initiating other drying processes, please wait a few seconds...") + "\n"; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": unknown cannot dry reason"; + break; + } + return cannot_reason_text; +} + +wxString organize_cannot_reasons_text(std::vector& reasons) +{ + wxString cannot_reasons_text; + if (std::find(reasons.begin(), reasons.end(), DevAms::CannotDryReason::DryingInProgress) != reasons.end()) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::DryingInProgress); + } else if (std::find(reasons.begin(), reasons.end(), DevAms::CannotDryReason::AmsBusy) != reasons.end()) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::AmsBusy); + } else if (std::find(reasons.begin(), reasons.end(), DevAms::CannotDryReason::ConsumableAtAmsOutlet) != reasons.end()) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::ConsumableAtAmsOutlet); + } else if (std::find(reasons.begin(), reasons.end(), DevAms::CannotDryReason::FilamentAtAmsOutletManualUnload) != reasons.end()) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::FilamentAtAmsOutletManualUnload); + } + + if (std::find(reasons.begin(), reasons.end(), DevAms::CannotDryReason::InsufficientPower) != reasons.end()) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::InsufficientPower); + } + + for (auto reason : reasons) { + if (reason == DevAms::CannotDryReason::InsufficientPowerNeedPluginPower) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::InsufficientPowerNeedPluginPower); + } else if (reason == DevAms::CannotDryReason::NotSupportedIn2dMode) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::NotSupportedIn2dMode); + } else if (reason == DevAms::CannotDryReason::InitiatingAmsDrying) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::InitiatingAmsDrying); + } else if (reason == DevAms::CannotDryReason::Upgrading) { + cannot_reasons_text += get_cannot_reason_text(DevAms::CannotDryReason::Upgrading); + } + } + + if (cannot_reasons_text.empty()) { + cannot_reasons_text += "*" + _L("System is busy") + "\n"; + cannot_reasons_text += _L(" Initiating other drying processes, please wait a few seconds...") + "\n"; + } + + return cannot_reasons_text; +} + +int AMSDryCtrWin::update_state(DevAms* dev_ams) +{ + std::vector cannot_reasons = dev_ams->GetCannotDryReason().has_value()? + dev_ams->GetCannotDryReason().value(): std::vector(); + + if (cannot_reasons.size() == 0 || + (cannot_reasons.size() == 1 && cannot_reasons[0] == DevAms::CannotDryReason::DryingInProgress)) { + m_normal_state_sizer->Show(true); + m_cannot_dry_sizer->Show(false); + m_unload_button->Show(false); + update_normal_state(dev_ams); + } else if (cannot_reasons.size() > 0) { + m_normal_state_sizer->Show(false); + m_cannot_dry_sizer->Show(true); + + m_cannot_dry_description_label->SetLabel(organize_cannot_reasons_text(cannot_reasons)); + m_cannot_dry_description_label->Wrap(FromDIP(300)); + + // Show unload button when ConsumableAtAmsOutlet reason is present + bool has_consumable_at_outlet = std::find(cannot_reasons.begin(), cannot_reasons.end(), + DevAms::CannotDryReason::ConsumableAtAmsOutlet) != cannot_reasons.end(); + m_unload_button->Show(has_consumable_at_outlet); + } + + restore_stop_button_if_deadline_passed(); + restore_unload_button_if_deadline_passed(); + + return 1; +} + +int AMSDryCtrWin::update_ams_change(DevAms* dev_ams) +{ + if (!is_ams_changed(dev_ams)) { + return 0; + } + + m_ams_info.m_ams_id = dev_ams->GetAmsId(); + if (dev_ams->GetAmsType() == DevAmsType::N3F) { + m_temperature_input->SetHint("45-65" + wxString::FromUTF8("°C")); + } else if (dev_ams->GetAmsType() == DevAmsType::N3S) { + m_temperature_input->SetHint("45-85" + wxString::FromUTF8("°C")); + } + + m_time_input->SetHint("1-24 h"); + + return 0; +} + +int AMSDryCtrWin::update_dryness_status(DevAms* dev_ams) +{ + int updated = 0; + + if (m_ams_info.m_humidity_percent != dev_ams->GetHumidityPercent()) { + updated += 1; + m_ams_info.m_humidity_percent = dev_ams->GetHumidityPercent(); + m_humidity_data_label->SetLabel(std::to_string(m_ams_info.m_humidity_percent) + "%"); + } + + if (m_ams_info.m_temperature != dev_ams->GetCurrentTemperature()) { + updated += 1; + m_ams_info.m_temperature = dev_ams->GetCurrentTemperature(); + m_temperature_data_label->SetLabel(std::to_string(m_ams_info.m_temperature) + wxString::FromUTF8("°C")); + } + + if (is_dry_ctr_idle(dev_ams)) { + m_time_descrition_container->Show(false); + m_original_page->Layout(); + } else { + if (is_dry_status_changed(dev_ams)) { + m_time_descrition_container->Show(true); + m_original_page->Layout(); + } + + if (m_ams_info.m_left_dry_time != dev_ams->GetLeftDryTime()) { + updated += 1; + m_ams_info.m_left_dry_time = dev_ams->GetLeftDryTime(); + m_time_data_label->SetLabel(wxString::Format("%02d : %02d", + m_ams_info.m_left_dry_time / 60, m_ams_info.m_left_dry_time % 60)); + } + } + + return updated; +} + +bool AMSDryCtrWin::is_tray_changed(DevAms* dev_ams) +{ + return false; +} + +void AMSDryCtrWin::update_filament_guide_info(DevAms* dev_ams) +{ + if (!IsShown()) { + return; + } + + m_guide_page->Freeze(); + m_ams_filament_panel->Clear(); + m_ams_filament_panel->SetAmsName(dev_ams->GetDisplayName()); + + // Get the temperature input value + long input_temp = 0; + bool valid_temp = !m_temperature_input->GetValue().IsEmpty() && + m_temperature_input->GetValue().ToLong(&input_temp); + bool can_start = true; + + int slot_count = 0, empty_count = 0; + for (auto& tray_pair : dev_ams->GetTrays()) { + if (!tray_pair.second) { + continue; + } + ++slot_count; + if (!tray_pair.second->is_exists) { + m_ams_filament_panel->AddFilamentItem("/", "dev_ams_dry_ctr_enable"); + ++empty_count; + continue; + } + auto preset_opt = tray_pair.second->get_ams_drying_preset(); + wxString filament_type = tray_pair.second->get_display_filament_type(); + DevFilamentDryingPreset preset; + if (filament_type.IsEmpty()) { + auto fallback_preset = DevUtilBackend::GetFilamentDryingPreset("GFA00"); + preset = fallback_preset.value(); + filament_type = "?"; + } else if (preset_opt.has_value()) { + preset = preset_opt.value(); + } else { + auto fallback_preset = DevUtilBackend::GetFilamentDryingPreset("GFA00"); + preset = fallback_preset.value(); + } + std::string icon_path = "dev_ams_dry_ctr_enable"; + int distortion_temp = static_cast(preset.filament_dev_ams_drying_heat_distortion_temperature); + if (valid_temp && distortion_temp < input_temp) { + icon_path = "dev_ams_dry_ctr_disable"; + can_start = false; + } + m_ams_filament_panel->AddFilamentItem(filament_type, icon_path); + } + if (slot_count == 0) { + can_start = false; + } + + if (can_start) { + m_guide_title_label->SetLabel(_L("For better drying results, remove the filament and allow it to rotate.")); + m_guide_description_label->SetLabel(_L("The AMS will automatically rotate the stored filament slots to enhance the drying performance.") + + "\n" + _L("Alternatively, you can dry the filament without removing it.") + + "\n" + "*" + _L("Unknown filaments will be treated as PLA.")); + m_guide_description_label->Wrap(FromDIP(300)); + } else { + m_guide_title_label->SetLabel(_L("Please store the filament marked with an exclamation mark.")); + m_guide_description_label->SetLabel(_L("Filament left in the feeder during drying may soften because the drying temperature exceeds the softening point of materials like PLA and TPU.") + + "\n" + "*" + _L("Unknown filaments will be treated as PLA.")); + m_guide_description_label->Wrap(FromDIP(300)); + } + + m_start_button->Enable(can_start); + m_guide_page->Layout(); + m_guide_page->Thaw(); +} + +int AMSDryCtrWin::update_filament_list(DevAms* dev_ams, MachineObject* obj) +{ + const bool ams_changed = is_ams_changed(dev_ams); + bool rebuilt_filament_list = false; + + // Build `m_tray_ids` and the combobox items from the preset bundle. + // This list is also used as a lookup table in non-idle state (type -> name), + // so it must be available even when the combobox is disabled. + auto rebuild_filament_list = [&]() -> bool { + m_trays_combo->Clear(); + m_tray_ids.clear(); + + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (!preset_bundle || !obj) { + return false; + } + + std::set filament_id_set; + auto & filaments = preset_bundle->filaments; + + // Get nozzle diameter using the same method as AMSMaterialsSetting::Popup + std::ostringstream stream; + int extruder_id = obj->GetFilaSystem()->GetExtruderIdByAmsId(m_ams_info.m_ams_id); + if (!obj->GetExtderSystem()->GetExtderById(extruder_id)) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " get extruder id failed"; + extruder_id = 0; + } + stream << std::fixed << std::setprecision(1) << obj->GetExtderSystem()->GetNozzleDiameter(extruder_id); + std::string nozzle_diameter_str = stream.str(); + std::set printer_names = preset_bundle->get_printer_names_by_printer_type_and_nozzle( + DevPrinterConfigUtil::get_printer_display_name(obj->printer_type), nozzle_diameter_str); + + for (auto filament_it = filaments.begin(); filament_it != filaments.end(); ++filament_it) { + Preset& preset = *filament_it; + // Filter by system preset: root preset and (system preset or user preset is supported) + if (filaments.get_preset_base(*filament_it) != &preset || (!filament_it->is_system && !obj->is_support_user_preset)) { + continue; + } + + ConfigOption * printer_opt = filament_it->config.option("compatible_printers"); + ConfigOptionStrings *printer_strs = dynamic_cast(printer_opt); + if (!printer_strs) continue; + + for (auto printer_str : printer_strs->values) { + if (printer_names.find(printer_str) != printer_names.end()) { + if (filament_id_set.find(filament_it->filament_id) != filament_id_set.end()) { + continue; + } + + filament_id_set.insert(filament_it->filament_id); + auto filament_alias = filaments.get_preset_alias(*filament_it, true); + if (!filament_alias.empty()) { + auto opt_info = preset_bundle->get_filament_by_filament_id(filament_it->filament_id); + if (opt_info.has_value()) { + auto real_info = opt_info.value(); + real_info.filament_name = filament_alias; + m_tray_ids.push_back(std::move(real_info)); + m_trays_combo->Append(wxString::FromUTF8(filament_alias)); + } + } + } + } + } + + if (m_tray_ids.empty()) { + BOOST_LOG_TRIVIAL(warning) << "AMSDryCtrWin::update_filament_list: No valid filaments found"; + return false; + } + + return true; + }; + + if (ams_changed || m_tray_ids.empty() || m_trays_combo->GetCount() == 0) { + // Disable start button during rebuild + if (m_start_button) { + m_start_button->Disable(); + } + + rebuilt_filament_list = rebuild_filament_list(); + } + + if (!is_dry_ctr_idle(dev_ams)) { + const std::string& ams_id = dev_ams->GetAmsId(); + const auto settings_opt = dev_ams->GetDrySettings(); + + // Set the combobox display label by the filament "type" string. + // Priority: last saved selection for this AMS (if the type matches) -> fallback to current `m_tray_ids`. + auto set_filament_label_by_type = [&](const std::string& filament_type) { + if (filament_type.empty()) { + return; + } + + auto it_name = m_dry_setting.m_filament_names.find(ams_id); + auto it_type = m_dry_setting.m_filament_type.find(ams_id); + if (it_name != m_dry_setting.m_filament_names.end() && it_type != m_dry_setting.m_filament_type.end() + && it_type->second == filament_type) { + m_trays_combo->SetLabel(wxString::FromUTF8(it_name->second)); + return; + } + + const auto it = std::find_if(m_tray_ids.begin(), m_tray_ids.end(), [&](const FilamentBaseInfo& tray) { + return tray.filament_type == filament_type; + }); + if (it != m_tray_ids.end()) { + m_trays_combo->SetLabel(wxString::FromUTF8(it->filament_name)); + } + }; + + if (settings_opt.has_value()) { + const auto& settings = settings_opt.value(); + m_temperature_input->SetValue(std::to_string(settings.dry_temp)); + m_time_input->SetValue(std::to_string(settings.dry_hour)); + set_filament_label_by_type(settings.dry_filament); + } else { + auto it_name = m_dry_setting.m_filament_names.find(ams_id); + if (it_name != m_dry_setting.m_filament_names.end()) { + m_trays_combo->SetLabel(wxString::FromUTF8(it_name->second)); + m_temperature_input->SetValue(std::to_string(m_dry_setting.m_dry_temp[ams_id])); + m_time_input->SetValue(std::to_string(m_dry_setting.m_dry_time[ams_id])); + } + } + + return 0; + } + + // Idle state: avoid re-selecting / firing selection change unless the list was rebuilt. + if (!rebuilt_filament_list && !ams_changed && is_dry_ctr_idle()) { + return 0; + } + + if (m_tray_ids.empty()) { + return 0; + } + + // Select recommended drying temperature and default filament + float min_dry_temp = std::numeric_limits::max(); + std::string default_filament_id = "GFA00"; + bool has_ready = false; + const auto fallback_preset = DevUtilBackend::GetFilamentDryingPreset("GFA00"); + for (const auto& tray_pair : dev_ams->GetTrays()) { + if (!tray_pair.second || !tray_pair.second->is_tray_info_ready()) continue; + has_ready = true; + wxString filament_type = tray_pair.second->get_display_filament_type(); + Slic3r::DevFilamentDryingPreset preset; + if (filament_type.IsEmpty()) { + // no filament type, is PLA + if (!fallback_preset) continue; + preset = fallback_preset.value(); + } else { + auto preset_opt = tray_pair.second->get_ams_drying_preset(); + if (preset_opt.has_value()) { + preset = preset_opt.value(); + } else { + // no preset,is PLA + if (!fallback_preset) continue; + preset = fallback_preset.value(); + } + } + float cur_temp = m_printer_status.m_is_printing + ? std::min({preset.filament_dev_ams_drying_temperature_on_print[dev_ams->GetAmsType()], + preset.filament_dev_drying_softening_temperature, preset.filament_dev_ams_drying_heat_distortion_temperature}) + : preset.filament_dev_ams_drying_temperature_on_idle[dev_ams->GetAmsType()]; + if (cur_temp < min_dry_temp) { + min_dry_temp = cur_temp; + default_filament_id = preset.filament_id; + } + } + // if no tray is ready, use PLA as default + if (!has_ready) { + if (fallback_preset.has_value()) { + Slic3r::DevFilamentDryingPreset preset = fallback_preset.value(); + float cur_temp = m_printer_status.m_is_printing + ? std::min({preset.filament_dev_ams_drying_temperature_on_print[dev_ams->GetAmsType()], + preset.filament_dev_drying_softening_temperature, preset.filament_dev_ams_drying_heat_distortion_temperature}) + : preset.filament_dev_ams_drying_temperature_on_idle[dev_ams->GetAmsType()]; + min_dry_temp = cur_temp; + default_filament_id = preset.filament_id; + } + } + m_ams_info.m_recommand_dry_temp = min_dry_temp; + + // Set default selection + unsigned int default_index = 0; + for (unsigned int i = 0; i < m_tray_ids.size(); i++) { + if (m_tray_ids[i].filament_id == default_filament_id) { + default_index = i; + break; + } + } + m_trays_combo->SetSelection(default_index); + wxCommandEvent evt(wxEVT_COMBOBOX, m_trays_combo->GetId()); + evt.SetInt(default_index); + OnFilamentSelectionChanged(evt); + return 1; +} + +std::shared_ptr AMSDryCtrWin::get_fila_system() const +{ + std::shared_ptr fila_system = m_fila_system.lock(); + if (!fila_system) { + const_cast(this)->Close(); + } + return fila_system; +} + +void AMSDryCtrWin::update_printer_state(MachineObject* obj) +{ + m_printer_status.m_is_printing = obj->is_in_printing() + && obj->GetExtderSystem()->GetCurrentAmsId() == m_ams_info.m_ams_id; +} + +void AMSDryCtrWin::update(std::shared_ptr fila_system, MachineObject* obj) +{ + if (!fila_system || !obj) { + return; + } + + update_printer_state(obj); + m_fila_system = fila_system; + + DevAms* dev_ams = fila_system->GetAmsById(m_ams_info.m_ams_id); + if (!dev_ams) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::update: Invalid AMS id"; + m_ams_info.m_ams_id = ""; + Close(); + return; + } + + if (!dev_ams->IsSupportRemoteDry(fila_system->GetOwner())) { + BOOST_LOG_TRIVIAL(info) << "AMSDryCtrWin::update: Selected AMS does not support remote drying"; + Close(); + return; + } + + + update_ams_change(dev_ams); + + update_image(dev_ams->GetAmsType(), + dev_ams->GetDryStatus().has_value()? dev_ams->GetDryStatus().value(): DevAms::DryStatus::Off, + dev_ams->GetDrySubStatus().has_value()? dev_ams->GetDrySubStatus().value(): DevAms::DrySubStatus::Off, + dev_ams->GetHumidityPercent()); + + update_state(dev_ams); + update_dryness_status(dev_ams); + + update_filament_list(dev_ams, obj); + update_filament_guide_info(dev_ams); + + m_is_ams_changed = false; + + check_values_changed(dev_ams); + + Layout(); + Refresh(); +} + +bool AMSDryCtrWin::is_ams_changed(DevAms* dev_ams) +{ + return m_ams_info.m_ams_id != dev_ams->GetAmsId() || m_is_ams_changed; +} + +bool AMSDryCtrWin::is_dry_status_changed(DevAms* dev_ams) +{ + if (!dev_ams->GetDryStatus().has_value() || !dev_ams->GetDrySubStatus().has_value()) { + return true; + } + + return dev_ams->GetDryStatus().value() != m_ams_info.m_dry_status + || dev_ams->GetDrySubStatus().value() != m_ams_info.m_dry_sub_status; +} + +bool AMSDryCtrWin::is_dry_ctr_idle(DevAms* dev_ams) +{ + if (!dev_ams->GetDryStatus().has_value() || !dev_ams->GetDrySubStatus().has_value()) { + return true; + } + + return dev_ams->GetDryStatus().value() == DevAms::DryStatus::Off + || dev_ams->GetDryStatus().value() == DevAms::DryStatus::Cooling; +} + +bool AMSDryCtrWin::is_dry_ctr_idle() +{ + return m_ams_info.m_dry_status == DevAms::DryStatus::Off || m_ams_info.m_dry_status == DevAms::DryStatus::Cooling; +} + +bool AMSDryCtrWin::is_dry_ctr_err(DevAms* dev_ams) +{ + if (!dev_ams->GetDryStatus().has_value() || !dev_ams->GetDrySubStatus().has_value()) { + return false; + } + + return dev_ams->GetDryStatus().value() == DevAms::DryStatus::Error; +} + +} // GUI +} // Slic3r diff --git a/src/slic3r/GUI/AMSDryControl.hpp b/src/slic3r/GUI/AMSDryControl.hpp new file mode 100644 index 0000000000..43e177eeb1 --- /dev/null +++ b/src/slic3r/GUI/AMSDryControl.hpp @@ -0,0 +1,253 @@ +#pragma once +#include "GUI_ObjectLayers.hpp" +#include "slic3r/GUI/Widgets/AMSItem.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" +#include "slic3r/GUI/Widgets/PopupWindow.hpp" + +#include "slic3r/GUI/wxExtensions.hpp" +#include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "slic3r/GUI/I18N.hpp" + +#include +#include + + +//Previous defintions +class wxGrid; + +namespace Slic3r { + +namespace GUI { + + +enum class DryCtrState { + IDLE, + DRY_WHEN_PRINT, + UNKNOWN +}; + +enum class DryCtrDev { + N3S, + N3F, + UNKNOWN +}; + +struct DryingPreset { + DryCtrState state; + DryCtrDev dev; + int dry_temp; + int dry_time; +}; + +class FilamentItemPanel : public wxPanel +{ +public: + FilamentItemPanel(wxWindow* parent, const wxString& text, const std::string& icon_name = "", + wxWindowID id = wxID_ANY); + + void SetText(const wxString& text); + void SetIcon(const std::string& icon_name); + void msw_rescale(); + +private: + void OnPaint(wxPaintEvent& event); + void OnSize(wxSizeEvent& event); + + Label* m_text_label; + wxStaticBitmap* m_icon_bitmap; + int m_target_size; + std::string m_icon_name; + ScalableBitmap m_icon; +}; + +class AMSFilamentPanel : public wxPanel +{ + wxBoxSizer* m_filament_sizer; + Label* m_ams_name_label; + int m_border_radius; + wxPanel* m_filament_container{nullptr}; + std::vector m_filament_items; + +public: + AMSFilamentPanel(wxWindow* parent, const wxString& ams_name, wxWindowID id = wxID_ANY); + + void AddFilamentItem(const wxString& text, const std::string& icon_name); + void AddFilamentItem(FilamentItemPanel* panel); + void SetAmsName(const wxString& ams_name); + void Clear(); + void msw_rescale(); +private: + void OnPaint(wxPaintEvent& event); +}; + + +class AMSDryCtrWin : public DPIDialog +{ +public: + AMSDryCtrWin(wxWindow *parent); + ~AMSDryCtrWin(); + + void msw_rescale(); + void update(std::shared_ptr fila_system, MachineObject* obj); + void set_ams_id(const std::string& ams_id); + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + +private: + wxSimplebook* m_main_simplebook{nullptr}; + wxPanel* m_original_page{nullptr}; + + wxWindow* m_amswin{nullptr}; + wxBoxSizer* m_sizer_ams_items{nullptr}; + wxScrolledWindow* m_panel_prv_left {nullptr}; + wxScrolledWindow* m_panel_prv_right{nullptr}; + wxBoxSizer* m_sizer_prv_left{nullptr}; + wxBoxSizer* m_sizer_prv_right{nullptr}; + + // left panel related members + ScalableBitmap m_humidity_image; + wxStaticBitmap* m_humidity_img{nullptr}; + Label* m_image_description{nullptr}; + wxStaticBitmap* m_image_description_icon{nullptr}; + ScalableBitmap m_description_icon_bitmap; + + Label* m_humidity_data_label = nullptr; + Label* m_temperature_data_label = nullptr; + Label* m_time_data_label = nullptr; + wxBoxSizer* m_time_descrition_container = nullptr; + + // right panel related members + wxBoxSizer* m_normal_state_sizer{nullptr}; + wxBoxSizer* m_cannot_dry_sizer{nullptr}; + wxBoxSizer* m_dry_error_sizer{nullptr}; + Label* m_cannot_dry_description_label = nullptr; + + // right panel normal state + ComboBox* m_trays_combo; + std::vector m_tray_ids; + wxTextCtrl* m_temperature_input; + wxTextCtrl* m_time_input; + Label* m_normal_description; + Button* m_start_button{nullptr}; + Button* m_next_button{nullptr}; + Button* m_stop_button{nullptr}; + Button* m_back_button{nullptr}; + Button* m_unload_button{nullptr}; + + // guide page description + Label* m_guide_title_label{nullptr}; + Label* m_guide_description_label{nullptr}; + + wxCheckBox* m_rotate_spool_toggle{nullptr}; + + wxPanel* m_progress_page; + ProgressBar* m_progress_gauge; + wxTimer* m_progress_timer; + + std::optional m_stop_button_restore_deadline; + std::optional m_unload_button_restore_deadline; + + Label* m_progress_title; + int m_progress_value; + int m_progress_message_index; + std::vector m_progress_text = { + _L("Starting: Checking adapter connection"), + _L("Starting: Checking filament status"), + _L("Starting: Checking drying presets"), + _L("Starting: Checking filament location"), + _L("Starting: Checking air intake"), + _L("Starting: Checking air vent") + }; + + // Guide page + wxPanel* m_guide_page{nullptr}; + AMSFilamentPanel* m_ams_filament_panel{nullptr}; + std::map m_filament_items; + wxStaticBitmap* m_image_placeholder{nullptr}; + ScalableBitmap m_guide_image; + + + bool m_is_ams_changed = false; + std::weak_ptr m_fila_system; + struct { + std::string m_ams_id; + DevAmsType m_model = DevAmsType::EXT_SPOOL; + DevAms::DryStatus m_dry_status = DevAms::DryStatus::Off; + DevAms::DrySubStatus m_dry_sub_status = DevAms::DrySubStatus::Off; + int m_humidity_percent; + int m_temperature; + int m_left_dry_time; + float m_recommand_dry_temp; + } m_ams_info; + + struct { + std::unordered_map m_filament_names; + std::unordered_map m_filament_type; + std::unordered_map m_dry_temp; + std::unordered_map m_dry_time; + } m_dry_setting; + + struct { + bool m_is_printing = false; + } m_printer_status; + +private: + void create(); + wxBoxSizer* create_guide_page_sizer(wxPanel* parent); + wxBoxSizer* create_main_content_section(wxPanel* parent); + wxBoxSizer* create_guide_info_filament(wxPanel* parent); + wxBoxSizer* create_guide_info_section(wxPanel* parent); + wxBoxSizer* create_guide_right_section(wxPanel* parent); + wxBoxSizer* create_main_page_sizer(wxPanel* parent); + wxBoxSizer* create_left_panel(wxPanel* parent); + wxBoxSizer* create_humidity_status_section(wxPanel* parent); + wxBoxSizer* create_description_item(wxPanel* parent, const wxString& title, Label*& dataLabel); + wxBoxSizer* create_status_descriptions_section(wxPanel* parent); + + wxBoxSizer* create_right_panel(wxPanel* parent); + wxBoxSizer* create_normal_state_panel(wxPanel* parent); + wxBoxSizer* create_cannot_dry_panel(wxPanel* parent); + wxBoxSizer* create_drying_error_panel(wxPanel* parent); + Button* create_button(wxPanel* parent, const wxString& title, + const wxColour& background_color, const wxColour& border_color, const wxColour& text_color); + + wxBoxSizer* create_progress_page_sizer(wxPanel* parent); + void OnProgressTimer(wxTimerEvent& event); + void OnClose(wxCloseEvent& event); + void OnShow(wxShowEvent& event); + + void OnFilamentSelectionChanged(wxCommandEvent& event); + + + wxScrolledWindow* create_preview_scrolled_window(wxWindow* parent); + + bool check_values_changed(DevAms* dev_ams); + int update_image(DevAmsType type, DevAms::DryStatus status, DevAms::DrySubStatus sub_status, int humidity_percent); + void update_img_description(DevAms::DryStatus status, DevAms::DrySubStatus sub_status); + void update_normal_description(DevAms* dev_ams); + int update_state(DevAms* dev_ams); + int update_dryness_status(DevAms* dev_ams); + int update_ams_change(DevAms* dev_ams); + int update_filament_list(DevAms* dev_ams, MachineObject* obj); + void update_filament_guide_info(DevAms* dev_ams); + void update_normal_state(DevAms* dev_ams); + void update_printer_state(MachineObject* obj); + + std::shared_ptr get_fila_system() const; + void start_sending_drying_command(); + void restore_stop_button_if_deadline_passed(); + void restore_unload_button_if_deadline_passed(); + void update_button_size(Button* button); + + bool is_dry_status_changed(DevAms* dev_ams); + bool is_dry_ctr_idle(DevAms* dev_ams); + bool is_ams_changed(DevAms* dev_ams); + bool is_dry_ctr_idle(); + bool is_tray_changed(DevAms* dev_ams); + bool is_dry_ctr_err(DevAms* dev_ams); + +}; + +} // GUI +} // Slic3r diff --git a/src/slic3r/GUI/AMSMaterialsSetting.cpp b/src/slic3r/GUI/AMSMaterialsSetting.cpp index 4a429a4a5a..bf727198c8 100644 --- a/src/slic3r/GUI/AMSMaterialsSetting.cpp +++ b/src/slic3r/GUI/AMSMaterialsSetting.cpp @@ -16,6 +16,9 @@ #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevFilaBlackList.h" #include "DeviceCore/DevFilaSystem.h" +#include "DeviceCore/DevFilaSwitch.h" +#include "DeviceCore/DevNozzleSystem.h" // DevNozzle / GetNozzleByPosId / GetNozzleRack +#include "DeviceCore/DevNozzleRack.h" // DevNozzleRack::IsSupported (rack gating) #define FILAMENT_MAX_TEMP 300 #define FILAMENT_MIN_TEMP 120 @@ -298,7 +301,7 @@ void AMSMaterialsSetting::create_panel_kn(wxWindow* parent) if (language.find("zh") == 0) region = "zh"; wxString link_url = wxString::Format("https://wiki.bambulab.com/%s/software/bambu-studio/calibration_pa", region); - m_wiki_ctrl = new HyperLink(parent, "Wiki Guide", link_url); + m_wiki_ctrl = new HyperLink(parent, _L("Wiki Guide"), link_url); cali_title_sizer->Add(m_ratio_text, 0, wxALIGN_CENTER_VERTICAL); cali_title_sizer->Add(m_wiki_ctrl, 0, wxALIGN_CENTER_VERTICAL); @@ -531,56 +534,121 @@ void AMSMaterialsSetting::on_select_reset(wxCommandEvent& event) { Close(); } +// Nozzle-context builder for the AMS-edit blacklist check. Factors the blacklist evaluation out of +// on_select_ok and threads rack-gated per-nozzle context (extruder id + nozzle flow + nozzle diameter) +// into CheckFilamentInfo, returning the accumulate-all CheckResult. As a side effect it resolves +// ams_filament_id/ams_setting_id from the matched preset. fila_name is kept as the preset name (not +// the short alias) so the name / name_suffix rules match on the non-rack fleet (no unintended +// activation of e.g. the PLA Glow rule). +static DevFilaBlacklist::CheckResult +sCheckFilamentInfo(PresetBundle* preset_bundle, + MachineObject* obj, + int ams_id, + int slot_id, + const std::string& filament_id, + std::string& ams_filament_id, + std::string& ams_setting_id) +{ + DevFilaBlacklist::CheckResult result; + if (!preset_bundle || !obj) + return result; + + // Orca: there is no lookup struct that also carries setting_id, so resolve the (root) preset by + // scanning the filaments collection for a matching filament_id. + Preset* fila_preset = nullptr; + for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); ++it) { + if (it->filament_id == filament_id) { + fila_preset = &(*it); + break; + } + } + if (!fila_preset) + return result; + + if (wxGetApp().app_config->get("skip_ams_blacklist_check") != "true") { + std::string filamnt_type; + fila_preset->get_filament_type(filamnt_type); + + DevFilaBlacklist::CheckFilamentInfo check_info; + check_info.dev_id = obj->get_dev_id(); + check_info.model_id = obj->printer_type; + check_info.fila_id = fila_preset->filament_id; + check_info.fila_type = filamnt_type; + check_info.fila_name = fila_preset->name; + check_info.has_filament_switch = obj->GetFilaSwitch()->IsInstalled(); + check_info.ams_id = ams_id; + check_info.slot_id = slot_id; + + if (auto vendor = dynamic_cast(fila_preset->config.option("filament_vendor")); + vendor && !vendor->values.empty()) { + check_info.fila_vendor = vendor->values[0]; + } + + check_info.extruder_id = obj->GetFilaSystem()->GetExtruderIdByAmsId(std::to_string(ams_id)); + + // Rack-gated per-nozzle context. For a multi-nozzle main extruder on a rack printer (H2C) the + // specific nozzle is resolved later by the print-dispatch rack mapping, so leave + // nozzle_flow/nozzle_diameter unset here to keep the high-flow nozzle rules dormant. Every + // non-rack printer takes the else branch, threading the reported nozzle flow + diameter and + // thereby activating the high-flow blacklist warnings in the AMS-edit dialog for H2D/H2S/X2D/P2S + // (and the E3D-kit X1C/P1x). + DevNozzleSystem* nozzle_system = obj->GetNozzleSystem(); + const bool rack_supported = nozzle_system && nozzle_system->GetNozzleRack() && + nozzle_system->GetNozzleRack()->IsSupported(); + if (check_info.extruder_id == MAIN_EXTRUDER_ID && rack_supported) { + ; // multi-nozzle main extruder on a rack printer — nozzle resolved later by print dispatch + } else { + check_info.nozzle_flow = obj->GetFilaSystem()->GetNozzleFlowStringByAmsId(std::to_string(ams_id)); + if (nozzle_system) { + DevNozzle nozzle = nozzle_system->GetNozzleByPosId(check_info.extruder_id.value_or(-1)); + if (!nozzle.IsEmpty()) + check_info.nozzle_diameter = nozzle.GetNozzleDiameter(); + } + } + + result = DevFilaBlacklist::check_filaments_in_blacklist(check_info); + } + + ams_filament_id = fila_preset->filament_id; + ams_setting_id = fila_preset->setting_id; + return result; +} + void AMSMaterialsSetting::on_select_ok(wxCommandEvent &event) { + if (!obj) + return; + //get filament id ams_filament_id = ""; ams_setting_id = ""; + // the combobox item + auto filament_item = map_filament_items[m_comboBox_filament->GetValue().ToStdString()]; + + // check filament info (rack-gated per-nozzle blacklist evaluation) PresetBundle* preset_bundle = wxGetApp().preset_bundle; - if (preset_bundle) { - for (auto it = preset_bundle->filaments.begin(); it != preset_bundle->filaments.end(); it++) { + const auto& fila_check_res = sCheckFilamentInfo(preset_bundle, obj, ams_id, slot_id, + filament_item.filament_id, ams_filament_id, ams_setting_id); - auto filament_item = map_filament_items[m_comboBox_filament->GetValue().ToStdString()]; - std::string filament_id = filament_item.filament_id; - if (it->filament_id.compare(filament_id) == 0) { + if (const auto& prohibit_items = fila_check_res.get_items_by_action("prohibition"); !prohibit_items.empty()) { + wxString info_msg; + for (const auto& item : prohibit_items) { info_msg += item.info_msg + "\n"; } + MessageDialog msg_wingow(nullptr, info_msg, _L("Error"), wxICON_WARNING | wxOK); + msg_wingow.ShowModal(); + return; + } - - //check is it in the filament blacklist - if (wxGetApp().app_config->get("skip_ams_blacklist_check") != "true") { - bool in_blacklist = false; - std::string action; - wxString info; - std::string filamnt_type; - std::string filamnt_name; - it->get_filament_type(filamnt_type); - - auto vendor = dynamic_cast(it->config.option("filament_vendor")); - - if (vendor && (vendor->values.size() > 0)) { - std::string vendor_name = vendor->values[0]; - DevFilaBlacklist::check_filaments_in_blacklist(obj->printer_type, vendor_name, filamnt_type, it->filament_id, ams_id, slot_id, it->name, in_blacklist, action, info); - } - - if (in_blacklist) { - if (action == "prohibition") { - MessageDialog msg_wingow(nullptr, info, _L("Error"), wxICON_WARNING | wxOK); - msg_wingow.ShowModal(); - //m_comboBox_filament->SetSelection(m_filament_selection); - return; - } - else if (action == "warning") { - MessageDialog msg_wingow(nullptr, info, _L("Warning"), wxICON_INFORMATION | wxOK); - msg_wingow.ShowModal(); - } - } - } - - ams_filament_id = it->filament_id; - ams_setting_id = it->setting_id; - break; - } + if (const auto& warning_items = fila_check_res.get_items_by_action("warning"); !warning_items.empty()) { + std::vector infos; + for (const auto& item : warning_items) { + FilamentWarningInfo winfo; + winfo.info_msg = item.info_msg; + winfo.wiki_url = item.wiki_url; + infos.emplace_back(winfo); } + FilamentWarningDialog msg_window(nullptr, _L("Warning"), infos); + msg_window.ShowModal(); } wxString nozzle_temp_min = m_input_nozzle_min->GetTextCtrl()->GetValue(); diff --git a/src/slic3r/GUI/AboutDialog.cpp b/src/slic3r/GUI/AboutDialog.cpp index 6bbc86f884..a4f0f06d65 100644 --- a/src/slic3r/GUI/AboutDialog.cpp +++ b/src/slic3r/GUI/AboutDialog.cpp @@ -324,10 +324,12 @@ AboutDialog::AboutDialog() m_html->SetFonts(font.GetFaceName(), font.GetFaceName(), size); m_html->SetMinSize(wxSize(FromDIP(-1), FromDIP(16))); m_html->SetBorders(2); + wxColour bgr_clr = GetBackgroundColour(); + const auto bgr_clr_str = encode_color(ColorRGB(bgr_clr.Red(), bgr_clr.Green(), bgr_clr.Blue())); const auto text = from_u8( (boost::format( "" - "" + "" "

https://www.orcaslicer.com

" "" "") diff --git a/src/slic3r/GUI/AmsMappingPopup.cpp b/src/slic3r/GUI/AmsMappingPopup.cpp index cf417498d5..af5df1f091 100644 --- a/src/slic3r/GUI/AmsMappingPopup.cpp +++ b/src/slic3r/GUI/AmsMappingPopup.cpp @@ -22,8 +22,12 @@ #include "Plater.hpp" #include "BitmapCache.hpp" #include "BindDialog.hpp" +#include "slic3r/GUI/DeviceCore/DevFilaSwitch.h" #include "DeviceCore/DevFilaSystem.h" +#include "DeviceCore/DevNozzleRack.h" +#include "DeviceCore/DevMappingNozzle.h" +#include "DeviceTab/wgtDeviceNozzleSelect.h" namespace Slic3r { namespace GUI { #define MATERIAL_ITEM_SIZE wxSize(FromDIP(65), FromDIP(50)) @@ -64,6 +68,7 @@ static void _add_containers(const AmsMapingPopup * win, //m_ams_wheel_mitem = ScalableBitmap(this, "ams_wheel", FromDIP(25)); m_ams_wheel_mitem = ScalableBitmap(this, "ams_wheel_narrow", 25); m_ams_not_match = ScalableBitmap(this, "filament_not_mactch", 25); + m_rack_nozzle_bitmap = ScalableBitmap(this, "dev_rack_nozzle_print_job", 22); m_material_coloul = mcolour; m_material_name = mname; @@ -73,9 +78,7 @@ static void _add_containers(const AmsMapingPopup * win, SetDoubleBuffered(true); #endif //__WINDOWS__ - SetSize(MATERIAL_ITEM_SIZE); - SetMinSize(MATERIAL_ITEM_SIZE); - SetMaxSize(MATERIAL_ITEM_SIZE); + messure_size(); SetBackgroundColour(*wxWHITE); Bind(wxEVT_PAINT, &MaterialItem::paintEvent, this); @@ -89,6 +92,7 @@ void MaterialItem::msw_rescale() { m_arraw_bitmap_white.msw_rescale(); m_transparent_mitem.msw_rescale(); m_ams_wheel_mitem.msw_rescale(); + m_rack_nozzle_bitmap.msw_rescale(); } void MaterialItem::allow_paint_dropdown(bool flag) { @@ -114,11 +118,22 @@ void MaterialItem::set_ams_info(wxColour col, wxString txt, int ctype, std::vect BOOST_LOG_TRIVIAL(info) << "set_ams_info " << m_ams_name; } +void MaterialItem::set_nozzle_info(const wxString& mapped_nozzle_str) +{ + if (m_mapped_nozzle_str != mapped_nozzle_str) { + m_mapped_nozzle_str = mapped_nozzle_str; + messure_size(); // a mapped nozzle adds/removes a row, changing the card height + Refresh(); + } +} + void MaterialItem::reset_ams_info() { m_ams_name = "-"; m_ams_coloul = wxColour(0xCE, 0xCE, 0xCE); m_ams_cols.clear(); m_ams_ctype = 0; + m_mapped_nozzle_str.Clear(); + messure_size(); Refresh(); } @@ -215,6 +230,11 @@ void MaterialItem::render(wxDC &dc) acolor = wxColour(0x90, 0x90, 0x90); } + // Header + AMS name keep their fixed-card positions; a mapped nozzle only adds a row below, so + // position this text against the base card height, not the grown one (else it slides down onto + // the nozzle row). Identical to GetSize().y when no nozzle row is present. + const float base_y = m_mapped_nozzle_str.IsEmpty() ? (float) GetSize().y : (float) MATERIAL_ITEM_SIZE.y; + // materials name dc.SetFont(::Label::Body_13); @@ -227,7 +247,7 @@ void MaterialItem::render(wxDC &dc) } auto material_txt_size = dc.GetTextExtent(m_material_name); - dc.DrawText(m_material_name, wxPoint((GetSize().x - material_txt_size.x) / 2, ((float)GetSize().y * 2 / 5 - material_txt_size.y) / 2)); + dc.DrawText(m_material_name, wxPoint((GetSize().x - material_txt_size.x) / 2, (base_y * 2 / 5 - material_txt_size.y) / 2)); @@ -238,11 +258,11 @@ void MaterialItem::render(wxDC &dc) if (mapping_txt.size() >= 4) { mapping_txt.insert(mapping_txt.size() / 2, "\n"); mapping_txt_size = dc.GetTextExtent(mapping_txt); - m_text_pos_y = ((float) GetSize().y * 3 / 5 - mapping_txt_size.y) / 2 + (float) GetSize().y * 2 / 5 - mapping_txt_size.y / 2; + m_text_pos_y = (base_y * 3 / 5 - mapping_txt_size.y) / 2 + base_y * 2 / 5 - mapping_txt_size.y / 2; m_text_pos_x = mapping_txt_size.x / 4; } else { mapping_txt_size = dc.GetTextExtent(mapping_txt); - m_text_pos_y = ((float) GetSize().y * 3 / 5 - mapping_txt_size.y) / 2 + (float) GetSize().y * 2 / 5; + m_text_pos_y = (base_y * 3 / 5 - mapping_txt_size.y) / 2 + base_y * 2 / 5; m_text_pos_x = 0; } @@ -258,12 +278,73 @@ void MaterialItem::match(bool mat) Refresh(); } +// A filament can map to several rack nozzles; the joined "R1, R2, ..." string is wrapped to a few +// slots per line so the label stays readable inside the narrow card. +static constexpr size_t MAPPED_NOZZLE_STR_MAX_CHARS_PER_LINE = 7; + +static wxString s_wrap_mapped_nozzle_str(const wxString& text) +{ + if (text.length() <= MAPPED_NOZZLE_STR_MAX_CHARS_PER_LINE) + return text; + + wxArrayString parts = wxSplit(text, ','); + wxString wrapped; + std::vector buffers; + for (auto& part : parts) { + if (!part.empty()) + buffers.push_back(part.Trim(false).Trim(true)); + + if (buffers.size() > 2) { + if (!wrapped.empty()) + wrapped += "\n"; + wrapped += buffers[0] + " " + buffers[1] + " " + buffers[2]; + buffers.clear(); + } + } + + if (!wrapped.empty()) + wrapped += "\n"; + if (buffers.size() > 0) + wrapped += buffers[0]; + if (buffers.size() > 1) + wrapped += " " + buffers[1]; + + return wrapped; +} + +static int s_get_mapped_nozzle_str_line_count(const wxString& text) +{ + if (text.empty()) + return 0; + return std::max(1, static_cast(wxSplit(s_wrap_mapped_nozzle_str(text), '\n', '\0').size())); +} + +void MaterialItem::messure_size() +{ + // Without a mapped nozzle the card is a fixed swatch + AMS wheel; a mapped nozzle adds a row + // below (glyph + slot label), growing the height by one text line per wrapped line. + if (m_mapped_nozzle_str.empty()) { + SetSize(MATERIAL_ITEM_SIZE); + SetMinSize(MATERIAL_ITEM_SIZE); + SetMaxSize(MATERIAL_ITEM_SIZE); + } else { + const int line_count = s_get_mapped_nozzle_str_line_count(m_mapped_nozzle_str); + const wxSize item_size(MATERIAL_ITEM_SIZE.x, FromDIP(84 + std::max(0, line_count - 1) * 10)); + SetSize(item_size); + SetMinSize(item_size); + SetMaxSize(item_size); + } +} + void MaterialItem::doRender(wxDC& dc) { wxSize size = GetSize(); auto mcolor = m_material_coloul; auto acolor = m_ams_coloul; change_the_opacity(acolor); + // Header + wheel keep their fixed-card geometry; when a nozzle row is present the extra height + // below is used for it, so lay out the top of the card against the base height, not the grown one. + const int base_y = m_mapped_nozzle_str.IsEmpty() ? size.y : MATERIAL_ITEM_SIZE.y; if (mcolor.Alpha() == 0) { dc.DrawBitmap(m_transparent_mitem.bmp(), FromDIP(1), FromDIP(1)); @@ -288,7 +369,7 @@ void MaterialItem::doRender(wxDC& dc) //bottom rectangle in wheel bitmap, size is MATERIAL_REC_WHEEL_SIZE(22) auto left = (size.x / 2 - MATERIAL_REC_WHEEL_SIZE.x) / 2 + FromDIP(3); - auto up = (size.y * 0.4 + (size.y * 0.6 - MATERIAL_REC_WHEEL_SIZE.y) / 2); + auto up = (base_y * 0.4 + (base_y * 0.6 - MATERIAL_REC_WHEEL_SIZE.y) / 2); auto right = left + MATERIAL_REC_WHEEL_SIZE.x - FromDIP(3); dc.SetPen(*wxTRANSPARENT_PEN); //bottom @@ -350,12 +431,12 @@ void MaterialItem::doRender(wxDC& dc) } dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawRoundedRectangle(FromDIP(0), FromDIP(0), MATERIAL_ITEM_SIZE.x - FromDIP(0), MATERIAL_ITEM_SIZE.y - FromDIP(0), 5); + dc.DrawRoundedRectangle(FromDIP(0), FromDIP(0), MATERIAL_ITEM_SIZE.x - FromDIP(0), size.y - FromDIP(0), 5); if (m_selected) { dc.SetPen(wxPen(AMS_CONTROL_BRAND_COLOUR, FromDIP(2))); dc.SetBrush(*wxTRANSPARENT_BRUSH); - dc.DrawRoundedRectangle(FromDIP(1), FromDIP(1), MATERIAL_ITEM_SIZE.x - FromDIP(1), MATERIAL_ITEM_SIZE.y - FromDIP(1), 5); + dc.DrawRoundedRectangle(FromDIP(1), FromDIP(1), MATERIAL_ITEM_SIZE.x - FromDIP(1), size.y - FromDIP(1), 5); } //#endif if (m_text_pos_y > 0 && m_match) { @@ -368,7 +449,7 @@ void MaterialItem::doRender(wxDC& dc) } auto wheel_left = (GetSize().x / 2 - m_ams_wheel_mitem.GetBmpSize().x) / 2 + FromDIP(2); - auto wheel_top = ((float)GetSize().y * 0.6 - m_ams_wheel_mitem.GetBmpSize().y) / 2 + (float)GetSize().y * 0.4; + auto wheel_top = ((float)base_y * 0.6 - m_ams_wheel_mitem.GetBmpSize().y) / 2 + (float)base_y * 0.4; if (!m_match) { wheel_left += m_ams_wheel_mitem.GetBmpSize().x; @@ -380,6 +461,29 @@ void MaterialItem::doRender(wxDC& dc) dc.DrawBitmap(m_ams_wheel_mitem.bmp(), wheel_left - FromDIP(LEFT_OFFSET), wheel_top); } } + + // Rack / filament-switcher printers: draw the physical nozzle the print-dispatch mapping assigned + // to this filament — a divider, the rack-nozzle glyph, and the slot label ("R1", "L R", ...) in + // the extra row below the wheel. Nothing is drawn when no nozzle is mapped (all other printers). + if (!m_mapped_nozzle_str.IsEmpty()) { + int row_top = wheel_top + m_ams_wheel_mitem.GetBmpSize().y + FromDIP(4); + dc.SetPen(wxPen(wxColour("#CECECE"), 1, wxPENSTYLE_SHORT_DASH)); // Orca: WXCOLOUR_GREY400 macro not in scope here + dc.DrawLine(FromDIP(1), row_top, FromDIP(size.x), row_top); + + int bitmap_y = row_top + (size.y - row_top - m_rack_nozzle_bitmap.GetBmpHeight()) / 2; + int bitmap_l = wheel_left + (m_ams_wheel_mitem.GetBmpWidth() - m_rack_nozzle_bitmap.GetBmpWidth()) / 2 + FromDIP(2); + dc.DrawBitmap(m_rack_nozzle_bitmap.bmp(), bitmap_l, bitmap_y); + + // Orca: BBS width-fits this label via a get_suitable_font_size overload Orca lacks; the wrapped + // slot string is short, so a fixed label font renders it cleanly without that helper. + const wxString wrapped = s_wrap_mapped_nozzle_str(m_mapped_nozzle_str); + dc.SetFont(::Label::Head_12); + dc.SetTextForeground(StateColor::darkModeColorFor(wxColour(0x26, 0x2E, 0x30))); + const wxSize text_size = dc.GetMultiLineTextExtent(wrapped); + int text_x = (size.x + bitmap_l + m_rack_nozzle_bitmap.GetBmpWidth() - text_size.x) / 2; + int text_y = row_top + (size.y - row_top - text_size.y) / 2; + dc.DrawText(wrapped, text_x, text_y); + } } void MaterialItem::reset_valid_info() { @@ -569,7 +673,7 @@ void MaterialSyncItem::doRender(wxDC &dc) dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 1, MATERIAL_ITEM_SIZE.y - 1, 5); if (m_selected) { - dc.SetPen(wxColour(0x00, 0xAE, 0x42)); + dc.SetPen(wxColour("#009688")); // ORCA selected item border color dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(1, 1, MATERIAL_ITEM_SIZE.x - 1, MATERIAL_ITEM_SIZE.y - 1, 5); } @@ -580,7 +684,7 @@ void MaterialSyncItem::doRender(wxDC &dc) dc.DrawRoundedRectangle(0, 0, MATERIAL_ITEM_SIZE.x, MATERIAL_ITEM_SIZE.y, 5); if (m_selected) { - dc.SetPen(wxPen(wxColour(0x00, 0xAE, 0x42), FromDIP(2))); + dc.SetPen(wxPen(wxColour("#009688"), FromDIP(2))); // ORCA selected item border color dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(FromDIP(1), FromDIP(1), MATERIAL_ITEM_SIZE.x - FromDIP(1), MATERIAL_ITEM_SIZE.y - FromDIP(1), 5); } @@ -725,6 +829,16 @@ AmsMapingPopup::AmsMapingPopup(wxWindow *parent, bool use_in_sync_dialog) : m_right_first_text_panel->SetMaxSize(wxSize(-1, FromDIP(same_height))); m_sizer_ams_right->Add(m_right_first_text_panel, 0, wxEXPAND | wxBOTTOM | wxTOP, FromDIP(8)); + + // Flush-waste warning (rack printers only). Orca: uses a plain Label here. + // Hidden by default => zero layout effect for non-rack printers. + m_flush_warning_panel = new Label(m_right_marea_panel); + m_flush_warning_panel->SetFont(::Label::Body_12); + m_flush_warning_panel->SetForegroundColour(StateColor::darkModeColorFor("#F09A17")); + m_flush_warning_panel->SetBackgroundColour(StateColor::darkModeColorFor("#FFFFE0")); + m_flush_warning_panel->Show(false); + m_sizer_ams_right->Add(m_flush_warning_panel, 0, wxBOTTOM | wxALIGN_LEFT, FromDIP(8)); + m_right_split_ams_sizer = create_split_sizer(m_right_marea_panel, _L("Right AMS")); m_sizer_ams_right->Add(m_right_split_ams_sizer, 0, wxEXPAND, 0); m_sizer_ams_right->Add(m_sizer_ams_basket_right, 0, wxEXPAND|wxTOP, FromDIP(8)); @@ -740,6 +854,14 @@ AmsMapingPopup::AmsMapingPopup(wxWindow *parent, bool use_in_sync_dialog) : m_sizer_ams->Add(0, 0, 0, wxEXPAND, FromDIP(15)); m_sizer_ams->Add(m_right_marea_panel, 1, wxEXPAND, FromDIP(0)); + // Rack nozzle manual-pick, alongside the AMS area (rack printers only). Hidden by default + // => contributes nothing to layout for non-rack printers. + m_rack_nozzle_select = new wgtDeviceNozzleRackSelect(this); + m_rack_nozzle_select->Bind(EVT_NOZZLE_SELECT_CHANGED, &AmsMapingPopup::OnNozzleMappingSelected, this); + m_rack_nozzle_select->Bind(EVT_NOZZLE_SELECT_CLICKED, [this](wxCommandEvent& e) { this->Dismiss(); }); + m_rack_nozzle_select->Show(false); + m_sizer_ams->Add(m_rack_nozzle_select, 0, wxEXPAND | wxTOP | wxLEFT, FromDIP(15)); + m_sizer_main->Add(title_panel, 0, wxEXPAND | wxALL, FromDIP(2)); m_sizer_main->Add(m_sizer_ams, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(14)); m_sizer_main->Add( 0, 0, 0, wxTOP, FromDIP(14)); @@ -782,6 +904,7 @@ void AmsMapingPopup::msw_rescale() m_right_extra_slot->msw_rescale(); for (auto item : m_mapping_item_list) { item->msw_rescale(); } for (auto container : m_amsmapping_container_list) { container->msw_rescale(); } + if (m_rack_nozzle_select) { m_rack_nozzle_select->Rescale(); } Fit(); Refresh(); @@ -813,7 +936,7 @@ void AmsMapingPopup::msw_rescale() m_split_left_line->SetMaxSize(wxSize(-1, 1)); sizer_split_ams->Add(0, 0, 0, wxEXPAND, 0); sizer_split_ams->Add(ams_title_text, 0, wxALIGN_CENTER, 0); - sizer_split_ams->Add(m_split_left_line, 1, wxEXPAND, 0); + sizer_split_ams->Add(m_split_left_line, 1, wxALIGN_CENTER, 0); // ORCA align line vertically return sizer_split_ams; } @@ -852,6 +975,8 @@ void AmsMapingPopup::on_left_down(wxMouseEvent &evt) auto left = item->GetSize(); if (pos.x > p_rect.x && pos.y > p_rect.y && pos.x < (p_rect.x + item->GetSize().x) && pos.y < (p_rect.y + item->GetSize().y)) { + // Orca: the external spool is un-pickable while a Filament Track Switch is installed (Apple hit-tests here). + if (m_fila_switch_installed && (item->m_ams_id == VIRTUAL_TRAY_MAIN_ID || item->m_ams_id == VIRTUAL_TRAY_DEPUTY_ID)) { return; } if (item->m_tray_data.type == TrayType::NORMAL) { if (!m_ext_mapping_filatype_check && (item->m_ams_id == VIRTUAL_TRAY_MAIN_ID || item->m_ams_id == VIRTUAL_TRAY_DEPUTY_ID)) { // Do nothing @@ -1038,7 +1163,7 @@ void AmsMapingPopup::update_items_check_state(const std::vector& a } } -void AmsMapingPopup::update(MachineObject* obj, const std::vector& ams_mapping_result) +void AmsMapingPopup::update(MachineObject* obj, const std::vector& ams_mapping_result, bool use_dynamic_switch, std::optional print_type) { //BOOST_LOG_TRIVIAL(info) << "ams_mapping nozzle count " << obj->get_extder_system()->nozzle.size(); BOOST_LOG_TRIVIAL(info) << "ams_mapping total count " << obj->GetFilaSystem()->GetAmsCount(); @@ -1047,6 +1172,11 @@ void AmsMapingPopup::update(MachineObject* obj, const std::vector& if (!obj) {return;} m_ams_remain_detect_flag = obj->GetFilaSystem()->IsDetectRemainEnabled(); + // Orca: with a Filament Track Switch installed, filament routes through the switch and the external + // spool cannot be used, so its mapping slots are rendered greyed-out and un-pickable. Inert (false) + // on any printer without a switch — GetFilaSwitch()->IsInstalled() defaults to false. + m_fila_switch_installed = obj->GetFilaSwitch()->IsInstalled(); + for (auto& ams_container : m_amsmapping_container_list) { ams_container->Destroy(); } @@ -1252,11 +1382,68 @@ void AmsMapingPopup::update(MachineObject* obj, const std::vector& } else { m_right_split_ams_sizer->Show(false); } + + /*rack (manual nozzle pick; rack printers only)*/ + update_rack_select(obj, use_dynamic_switch, print_type); + update_flush_waste(obj); + Layout(); Fit(); Refresh(); } +void AmsMapingPopup::update_rack_select(MachineObject* obj, bool use_dynamic_switch, std::optional print_from_type) +{ + // Orca: MachineObject has no GetNozzleRack() convenience; route through the nozzle system instead. + m_rack = obj ? obj->GetNozzleSystem()->GetNozzleRack() : nullptr; + + bool show_rack_select_area = false; + if (!m_mapping_from_multi_machines && !m_use_in_sync_dialog && + obj && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported() && + print_from_type.has_value() && print_from_type.value() == PrintFromType::FROM_NORMAL) { + const auto& nozzle_pos_vec = obj->get_nozzle_mapping_result()->GetMappedNozzlePosVecByFilaId(m_current_filament_id); + m_rack_nozzle_select->UpdatSelectedNozzles(obj->GetNozzleSystem()->GetNozzleRack(), nozzle_pos_vec, use_dynamic_switch, print_from_type); + show_rack_select_area = true; + } + + if (show_rack_select_area != m_rack_nozzle_select->IsShown()) { + m_right_tip_text = show_rack_select_area ? _L("Select Filament && Hotends") : _L("Select Filament"); + m_right_tips->SetLabel(m_right_tip_text); + m_rack_nozzle_select->Show(show_rack_select_area); + Layout(); + Fit(); + } +} + +void AmsMapingPopup::update_flush_waste(MachineObject* obj) +{ + if (!obj) { + m_flush_warning_panel->Hide(); + return; + }; + + float flush_waste_base = obj->get_nozzle_mapping_result()->GetFlushWeightBase(); + float flush_waste_current = obj->get_nozzle_mapping_result()->GetFlushWeightCurrent(); + if ((flush_waste_base != -1) && (flush_waste_current != -1) && flush_waste_current > flush_waste_base) { + m_flush_warning_panel->SetLabel(wxString::Format(_L("Printing with the current nozzle may produce an extra %0.2f g of waste."), flush_waste_current - flush_waste_base)); + m_flush_warning_panel->Show(); + } else { + m_flush_warning_panel->Hide(); + } +} + +void AmsMapingPopup::OnNozzleMappingSelected(wxCommandEvent& evt) +{ + if (auto ptr = m_rack.lock()) { + MachineObject* obj = ptr->GetNozzleSystem()->GetOwner(); + obj->get_nozzle_mapping_result()->SetManualNozzleMappingByFila(m_current_filament_id, m_rack_nozzle_select->GetSelectedNozzlePosID()); + update_flush_waste(obj); + } + + evt.Skip(); + Dismiss(); +} + std::vector AmsMapingPopup::parse_ams_mapping(const std::map& amsList) { std::vector m_tray_data; @@ -1367,6 +1554,20 @@ void AmsMapingPopup::add_ext_ams_mapping(TrayData tray_data, MappingItem* item) #ifdef __APPLE__ m_mapping_item_list.push_back(item); #endif + + // Orca: a Filament Track Switch cannot route the external spool, so grey the ext slot out and make it + // un-pickable, with a tooltip explaining why (the click below is disabled; on_left_down also skips it). + if (m_fila_switch_installed) { + const wxString disp_name = (tray_data.type == THIRD) ? wxString("?") + : (tray_data.type == EMPTY) ? wxString("-") + : wxString(tray_data.name); + item->set_data(m_tag_material, wxColour(0xEE, 0xEE, 0xEE), disp_name, false, tray_data, true); + item->SetToolTip(_L("External spools is not supported since Filament Track Switch has been installed. If you want to use external spool, please uninstall it.")); + item->Bind(wxEVT_LEFT_DOWN, [](wxMouseEvent&) { /* un-pickable while the switch is installed */ }); + item->set_tray_index(_L("Ext")); + return; + } + // set button if (tray_data.type == NORMAL) { if (is_match_material(tray_data.filament_type)) { @@ -1420,7 +1621,7 @@ bool AmsMapingPopup::ProcessLeftDown(wxMouseEvent &event) void AmsMapingPopup::paintEvent(wxPaintEvent &evt) { wxPaintDC dc(this); - dc.SetPen(wxColour(0xAC, 0xAC, 0xAC)); + dc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour("#009688")),FromDIP(2))); // ORCA use colorful border for separation dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); } @@ -2281,7 +2482,7 @@ AmsRMGroup* AmsReplaceMaterialDialog::create_backup_group(wxString gname, std::m void AmsReplaceMaterialDialog::paintEvent(wxPaintEvent& evt) { wxPaintDC dc(this); - dc.SetPen(wxColour(0xAC, 0xAC, 0xAC)); + dc.SetPen(StateColor::darkModeColorFor(wxColour("#DBDBDB"))); // ORCA fix popup border color for dark mode dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); } @@ -2305,12 +2506,25 @@ _GetBackupStatus(unsigned int fila_back_group) for (int j = 16; j < 32; j++)/* single ams is from 128*/ { + // N9 / AMS-Lite-mixed reports its four backup slots in bits 24-27, which decode directly to + // tray ids 24-27 (handled in the loop below). Keep those bits out of the single-ams (128+) + // range; all other bits keep their existing mapping unchanged. + if (j >= 24 && j <= 27) + continue; if (fila_back_group & (1 << j)) { trayid_group[128 + j - 16] = true; } } + for (int i = 24; i <= 27; i++)/* ams lite for N9 */ + { + if (fila_back_group & (1 << i)) + { + trayid_group[i] = true; + } + } + return trayid_group; } diff --git a/src/slic3r/GUI/AmsMappingPopup.hpp b/src/slic3r/GUI/AmsMappingPopup.hpp index bbfb967822..0850c0e728 100644 --- a/src/slic3r/GUI/AmsMappingPopup.hpp +++ b/src/slic3r/GUI/AmsMappingPopup.hpp @@ -41,8 +41,15 @@ #include "slic3r/GUI/DeviceCore/DevUtil.h" +#include + #define MAPPING_ITEM_INVALID_REMAIN -1 +namespace Slic3r { +class DevNozzleRack; +namespace GUI { class wgtDeviceNozzleRackSelect; } +} + namespace Slic3r { namespace GUI { @@ -93,6 +100,9 @@ public: //info wxColour m_ams_coloul; wxString m_ams_name; + // Physical nozzle(s) the print-dispatch mapping assigned to this filament (e.g. "R1", "L R"). + // Empty on printers without a nozzle rack or filament switcher; when set, the card grows a row. + wxString m_mapped_nozzle_str; int m_ams_ctype = 0; std::vector m_ams_cols = std::vector(); //reset @@ -107,6 +117,7 @@ public: ScalableBitmap m_filament_wheel_transparent; ScalableBitmap m_ams_wheel_mitem; ScalableBitmap m_ams_not_match; + ScalableBitmap m_rack_nozzle_bitmap; bool m_selected {false}; bool m_warning{false}; @@ -117,6 +128,10 @@ public: void allow_paint_dropdown(bool flag); void set_ams_info(wxColour col, wxString txt, int ctype=0, std::vector cols= std::vector(),bool record_back_info = false); void reset_ams_info(); + // Set the mapped-nozzle label ("R1", "L R", ...); grows/shrinks the card as the row appears/clears. + void set_nozzle_info(const wxString& mapped_nozzle_str); + // Size the card: base swatch height, plus one row when a nozzle label is present. + void messure_size(); void disable(); void enable(); @@ -229,6 +244,9 @@ public: bool m_has_unmatch_filament {false}; int m_current_filament_id; ShowType m_show_type{ShowType::RIGHT}; + // Orca: set from update() — true when a Filament Track Switch is installed, which makes the + // external-spool slots un-pickable (false on any printer without a switch, so behavior is unchanged). + bool m_fila_switch_installed{false}; std::string m_tag_material; wxBoxSizer *m_sizer_main{nullptr}; wxBoxSizer *m_sizer_ams{nullptr}; @@ -259,12 +277,19 @@ public: wxBoxSizer* m_sizer_split_ams_right; bool m_mapping_from_multi_machines {false}; + // Rack nozzle manual-pick (rack printers only; hidden by default via Show(false)). + wgtDeviceNozzleRackSelect* m_rack_nozzle_select{nullptr}; + Label* m_flush_warning_panel{nullptr}; // Orca: uses a plain Label for the flush warning + std::weak_ptr m_rack; + void set_sizer_title(wxBoxSizer *sizer, wxString text); wxBoxSizer* create_split_sizer(wxWindow* parent, wxString text); void set_send_win(wxWindow* win) {send_win = win;}; void update_materials_list(std::vector list); void set_tag_texture(std::string texture); - void update(MachineObject* obj, const std::vector& ams_mapping_result); + void update(MachineObject* obj, const std::vector& ams_mapping_result, bool use_dynamic_switch = false, std::optional print_type = std::nullopt); + void update_rack_select(MachineObject* obj, bool use_dynamic_switch, std::optional print_type); + void update_flush_waste(MachineObject* obj); void update_title(MachineObject* obj); void update_items_check_state(const std::vector& ams_mapping_result); void update_ams_data_multi_machines(); @@ -295,6 +320,8 @@ public: void EnableExtMappingFilaTypeCheck(bool to_check = true) { m_ext_mapping_filatype_check = to_check;} ; private: + void OnNozzleMappingSelected(wxCommandEvent& evt); + ResetCallback m_reset_callback{nullptr}; std::string m_material_index; bool m_only_show_ext_spool{false}; diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 46ff3afff9..23b647303e 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -231,7 +231,20 @@ void BackgroundSlicingProcess::process_fff() if (m_current_plate->get_real_filament_map_mode(preset_bundle.project_config) < FilamentMapMode::fmmManual) { std::vector f_maps = m_fff_print->get_filament_maps(); m_current_plate->set_filament_maps(f_maps); + // The engine's concrete per-filament volume assignment is merged into the print + // config by the ToolOrdering write-back; reading it back keeps the plate config the + // next apply overlays equal to the written-back state (no diff, no re-invalidation) + // and persists the auto result (always concrete Std/HF, never the Hybrid seed). + std::vector f_volume_maps = m_fff_print->get_filament_volume_maps(); + m_current_plate->set_filament_volume_maps(f_volume_maps); } + if (m_current_plate->get_real_filament_map_mode(preset_bundle.project_config) != FilamentMapMode::fmmNozzleManual) { + // The engine-resolved nozzle map is read back for every non-nozzle-manual mode so the + // plate config the next apply overlays matches the engine's written-back state + // (otherwise the full-config diff would invalidate the g-code on every apply). + std::vector f_nozzle_maps = m_fff_print->get_filament_nozzle_maps(); + m_current_plate->set_filament_nozzle_maps(f_nozzle_maps); + } wxCommandEvent evt(m_event_slicing_completed_id); // Post the Slicing Finished message for the G-code viewer to update. // Passing the timestamp @@ -241,6 +254,9 @@ void BackgroundSlicingProcess::process_fff() //BBS: add plate index into render params m_temp_output_path = this->get_current_plate()->get_tmp_gcode_path(); m_fff_print->export_gcode(m_temp_output_path, m_gcode_result, [this](const ThumbnailsParams& params) { return this->render_thumbnails(params); }); + // Orca: BBL printers post-process the g-code in place here and never re-parse it into a fresh + // GCodeProcessorResult, so m_gcode_result->nozzle_group_result (consumed by the H2C print-dispatch + // nozzle mapping) survives post-processing. No preservation guard is needed on this path. if(m_fff_print->is_BBL_printer()) run_post_process_scripts(m_temp_output_path, false, "File", m_temp_output_path, m_fff_print->full_print_config()); diff --git a/src/slic3r/GUI/BaseTransparentDPIFrame.cpp b/src/slic3r/GUI/BaseTransparentDPIFrame.cpp index fa2b8cab91..918116d89b 100644 --- a/src/slic3r/GUI/BaseTransparentDPIFrame.cpp +++ b/src/slic3r/GUI/BaseTransparentDPIFrame.cpp @@ -30,6 +30,19 @@ BaseTransparentDPIFrame::BaseTransparentDPIFrame( // SetBackgroundStyle(wxBackgroundStyle::wxBG_STYLE_TRANSPARENT); SetTransparent(m_init_transparent); SetBackgroundColour(wxColour(23, 25, 22, 128)); + + // ORCA add border + Bind(wxEVT_PAINT, [this](wxPaintEvent& evt) { + wxPaintDC dc(this); + dc.SetPen(wxPen(StateColor::darkModeColorFor(wxColour("#009688")), FromDIP(2))); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(0, 0, GetSize().x, GetSize().y, 0); + }); + + int window_padding = 15; + auto imgsize = 32; + auto imgright = 10; + //Adaptive Frame Width wxClientDC dc(parent); wxSize msg_sz = dc.GetMultiLineTextExtent(ok_text); @@ -44,21 +57,16 @@ BaseTransparentDPIFrame::BaseTransparentDPIFrame( m_sizer_main = new wxBoxSizer(wxVERTICAL); wxBoxSizer *text_sizer = new wxBoxSizer(wxHORIZONTAL); - text_sizer->AddSpacer(FromDIP(20)); - auto image_sizer = new wxBoxSizer(wxVERTICAL); - auto imgsize = FromDIP(25); - auto completedimg = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("completed", this, 25), wxDefaultPosition, wxSize(imgsize, imgsize), 0); - image_sizer->Add(completedimg, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(0)); - image_sizer->AddStretchSpacer(); - text_sizer->Add(image_sizer); - text_sizer->AddSpacer(FromDIP(5)); + + auto completedimg = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("completed", this, imgsize), wxDefaultPosition, FromDIP(wxSize(imgsize, imgsize)), 0); + + text_sizer->Add(completedimg, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(imgright)); m_finish_text = new Label(this, win_text, LB_AUTO_WRAP); - m_finish_text->SetMinSize(wxSize(FromDIP(win_width - 64), -1)); - m_finish_text->SetMaxSize(wxSize(FromDIP(win_width - 64), -1)); + m_finish_text->SetMinSize(wxSize(FromDIP(win_width - (window_padding * 2 + imgright + imgsize)), -1)); + m_finish_text->SetMaxSize(wxSize(FromDIP(win_width - (window_padding * 2 + imgright + imgsize)), -1)); m_finish_text->SetForegroundColour(wxColour(255, 255, 255, 255)); - text_sizer->Add(m_finish_text, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxALL, 0); - text_sizer->AddSpacer(FromDIP(20)); - m_sizer_main->Add(text_sizer, FromDIP(0), wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxTOP, FromDIP(15)); + text_sizer->Add(m_finish_text, 0, wxALIGN_CENTER_VERTICAL); + m_sizer_main->Add(text_sizer, 0, wxALL, FromDIP(15)); wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL); bSizer_button->SetMinSize(wxSize(FromDIP(100), -1)); @@ -66,22 +74,18 @@ BaseTransparentDPIFrame::BaseTransparentDPIFrame( bSizer_button->Add(m_checkbox, 0, wxALIGN_LEFT);*/ bSizer_button->AddStretchSpacer(1); m_button_ok = new Button(this, ok_text); - m_button_ok->SetStyle(ButtonStyle::Confirm, ButtonType::Window); - m_button_ok->SetSize(wxSize(FromDIP(60), FromDIP(30))); - m_button_ok->SetMinSize(wxSize(FromDIP(90), FromDIP(30))); - bSizer_button->Add(m_button_ok, 0, wxALIGN_RIGHT | wxLEFT | wxTOP, FromDIP(10)); + m_button_ok->SetStyle(ButtonStyle::Confirm, ButtonType::Choice); + bSizer_button->Add(m_button_ok, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(10)); m_button_ok->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent &e) { deal_ok(); }); m_button_cancel = new Button(this, cancel_text); - m_button_cancel->SetStyle(ButtonStyle::Regular, ButtonType::Window); - m_button_cancel->SetSize(wxSize(FromDIP(65), FromDIP(30))); - m_button_cancel->SetMinSize(wxSize(FromDIP(65), FromDIP(30))); - bSizer_button->Add(m_button_cancel, 0, wxALIGN_RIGHT | wxLEFT | wxTOP, FromDIP(10)); + m_button_cancel->SetStyle(ButtonStyle::Regular, ButtonType::Choice); + bSizer_button->Add(m_button_cancel, 0, wxALIGN_RIGHT | wxLEFT, FromDIP(10)); m_button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent &e) { deal_cancel(); }); - m_sizer_main->Add(bSizer_button, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(20)); + m_sizer_main->Add(bSizer_button, 1, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(window_padding)); Bind(wxEVT_CLOSE_WINDOW, [this](auto &e) { on_hide(); diff --git a/src/slic3r/GUI/BindDialog.cpp b/src/slic3r/GUI/BindDialog.cpp index 316778a994..ab838033de 100644 --- a/src/slic3r/GUI/BindDialog.cpp +++ b/src/slic3r/GUI/BindDialog.cpp @@ -590,7 +590,7 @@ PingCodeBindDialog::~PingCodeBindDialog() { sizer_error_code->Add(m_st_txt_error_code, 0, wxALL, 0); - auto st_title_error_desc = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, wxT("Error desc")); + auto st_title_error_desc = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, _L("Error desc")); auto st_title_error_desc_doc = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, ": "); m_st_txt_error_desc = new Label(m_sw_bind_failed_info, wxEmptyString); st_title_error_desc->SetForegroundColour(0x909090); @@ -607,7 +607,7 @@ PingCodeBindDialog::~PingCodeBindDialog() { sizer_error_desc->Add(st_title_error_desc_doc, 0, wxALL, 0); sizer_error_desc->Add(m_st_txt_error_desc, 0, wxALL, 0); - auto st_title_extra_info = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, wxT("Extra info")); + auto st_title_extra_info = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, _L("Extra info")); auto st_title_extra_info_doc = new wxStaticText(m_sw_bind_failed_info, wxID_ANY, ": "); m_st_txt_extra_info = new Label(m_sw_bind_failed_info, wxEmptyString); st_title_extra_info->SetForegroundColour(0x909090); diff --git a/src/slic3r/GUI/BonjourDialog.cpp b/src/slic3r/GUI/BonjourDialog.cpp index db7794a52a..8b3217e193 100644 --- a/src/slic3r/GUI/BonjourDialog.cpp +++ b/src/slic3r/GUI/BonjourDialog.cpp @@ -8,7 +8,6 @@ #include #include -#include #include #include #include @@ -20,6 +19,8 @@ #include "slic3r/GUI/format.hpp" #include "slic3r/Utils/Bonjour.hpp" +#include "slic3r/GUI/Widgets/DialogButtons.hpp" + namespace Slic3r { @@ -63,30 +64,30 @@ BonjourDialog::BonjourDialog(wxWindow *parent, Slic3r::PrinterTechnology tech) , timer_state(0) , tech(tech) { + SetBackgroundColour(*wxWHITE); + const int em = GUI::wxGetApp().em_unit(); list->SetMinSize(wxSize(80 * em, 30 * em)); wxBoxSizer *vsizer = new wxBoxSizer(wxVERTICAL); + label->SetFont(Label::Body_14); vsizer->Add(label, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, em); list->SetSingleStyle(wxLC_SINGLE_SEL); list->SetSingleStyle(wxLC_SORT_DESCENDING); - list->AppendColumn(_(L("Address")), wxLIST_FORMAT_LEFT, 5 * em); + list->AppendColumn(_(L("Address")), wxLIST_FORMAT_LEFT, 20 * em); list->AppendColumn(_(L("Hostname")), wxLIST_FORMAT_LEFT, 10 * em); list->AppendColumn(_(L("Service name")), wxLIST_FORMAT_LEFT, 20 * em); if (tech == ptFFF) { - list->AppendColumn(_(L("OctoPrint version")), wxLIST_FORMAT_LEFT, 5 * em); + list->AppendColumn(_(L("OctoPrint version")), wxLIST_FORMAT_LEFT, 15 * em); } vsizer->Add(list, 1, wxEXPAND | wxALL, em); - wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL); - button_sizer->Add(new wxButton(this, wxID_OK, _L("OK")), 0, wxALL, em); - button_sizer->Add(new wxButton(this, wxID_CANCEL, _L("Cancel")), 0, wxALL, em); - // ^ Note: The Ok/Cancel labels are translated by wxWidgets + auto dlg_btns = new GUI::DialogButtons(this, {"OK", "Cancel"}); - vsizer->Add(button_sizer, 0, wxALIGN_CENTER); + vsizer->Add(dlg_btns, 0, wxEXPAND); SetSizerAndFit(vsizer); Bind(EVT_BONJOUR_REPLY, &BonjourDialog::on_reply, this); @@ -241,12 +242,15 @@ IPListDialog::IPListDialog(wxWindow* parent, const wxString& hostname, const std , m_list(new wxListView(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLC_REPORT | wxSIMPLE_BORDER)) , m_selected_index (selected_index) { + SetBackgroundColour(*wxWHITE); + const int em = GUI::wxGetApp().em_unit(); m_list->SetMinSize(wxSize(40 * em, 30 * em)); wxBoxSizer* vsizer = new wxBoxSizer(wxVERTICAL); auto* label = new wxStaticText(this, wxID_ANY, GUI::format_wxstr(_L("There are several IP addresses resolving to hostname %1%.\nPlease select one that should be used."), hostname)); + label->SetFont(Label::Body_14); vsizer->Add(label, 0, wxEXPAND | wxTOP | wxLEFT | wxRIGHT, em); m_list->SetSingleStyle(wxLC_SINGLE_SEL); @@ -259,11 +263,9 @@ IPListDialog::IPListDialog(wxWindow* parent, const wxString& hostname, const std vsizer->Add(m_list, 1, wxEXPAND | wxALL, em); - wxBoxSizer* button_sizer = new wxBoxSizer(wxHORIZONTAL); - button_sizer->Add(new wxButton(this, wxID_OK, _L("OK")), 0, wxALL, em); - button_sizer->Add(new wxButton(this, wxID_CANCEL, _L("Cancel")), 0, wxALL, em); + auto dlg_btns = new GUI::DialogButtons(this, {"OK", "Cancel"}); - vsizer->Add(button_sizer, 0, wxALIGN_CENTER); + vsizer->Add(dlg_btns, 0, wxEXPAND); SetSizerAndFit(vsizer); GUI::wxGetApp().UpdateDlgDarkUI(this); diff --git a/src/slic3r/GUI/CaliHistoryDialog.cpp b/src/slic3r/GUI/CaliHistoryDialog.cpp index 8ed0305369..2e7f2caf97 100644 --- a/src/slic3r/GUI/CaliHistoryDialog.cpp +++ b/src/slic3r/GUI/CaliHistoryDialog.cpp @@ -13,6 +13,9 @@ #include "Plater.hpp" #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevManager.h" +#include "DeviceCore/DevConfigUtil.h" +#include "DeviceCore/DevNozzleSystem.h" +#include "DeviceCore/DevNozzleRack.h" namespace Slic3r { namespace GUI { @@ -26,6 +29,7 @@ namespace GUI { enum CaliColumnType : int { Cali_Name = 0, Cali_Filament, + Cali_Nozzle_ID, Cali_Nozzle, Cali_K_Value, Cali_Delete, @@ -33,6 +37,9 @@ enum CaliColumnType : int { Cali_Type_Count }; +// Orca: derive nozzle-volume support from the machine preset's nozzle_volume array +// rather than a live device-capability query, to avoid flipping the Nozzle-Flow column +// visibility on shipping printers (H2D/X1/P1/A1). bool support_nozzle_volume(const MachineObject* obj) { if (!obj) @@ -49,14 +56,17 @@ bool support_nozzle_volume(const MachineObject* obj) return false; } -int get_colume_idx(CaliColumnType type, MachineObject* obj) +// Rack hotend position code -> label: 0 = fixed ("R"); >=0x10 = rack slot number; else N/A. +static wxString nozzle_id_code_to_string(int code) { - if (!support_nozzle_volume(obj) - && (type > CaliColumnType::Cali_Nozzle)) { - return type - 1; + if (code == 0) { + return "R"; + } else if (code >= 0x10) { + return wxString::Format("%d", code - 0x10 + 1); + } else { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "Nozzle position id is -1 or invalid."; + return "N/A"; } - - return type; } static wxString get_preset_name_by_filament_id(std::string filament_id) @@ -244,6 +254,10 @@ void HistoryWindow::on_device_connected(MachineObject* obj) } m_comboBox_nozzle_dia->SetSelection(selection); + m_extruder_switch_btn->SetLabels( + _L(DevPrinterConfigUtil::get_toolhead_display_name(obj->printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase)), + _L(DevPrinterConfigUtil::get_toolhead_display_name(obj->printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase))); + if (obj->is_multi_extruders()) m_extruder_switch_btn->Show(); else @@ -320,7 +334,21 @@ void HistoryWindow::enbale_action_buttons(bool enable) { } } +// The main extruder can carry a nozzle rack (H2C); the Nozzle-ID column only shows for it. +bool HistoryWindow::support_nozzle_id_column() +{ + if (!curr_obj || get_extruder_id() != MAIN_EXTRUDER_ID) + return false; + auto ns = curr_obj->GetNozzleSystem(); + if (!ns) + return false; + auto rack = ns->GetNozzleRack(); + return rack && rack->IsSupported(); +} + void HistoryWindow::sync_history_data() { + int column_idx = 0; + Freeze(); m_history_data_panel->DestroyChildren(); m_history_data_panel->Enable(); @@ -331,24 +359,35 @@ void HistoryWindow::sync_history_data() { m_history_data_panel->SetSizer(gbSizer, true); + const bool has_nozzle_id = support_nozzle_id_column(); + auto title_name = new Label(m_history_data_panel, _L("Name")); title_name->SetFont(Label::Head_14); - gbSizer->Add(title_name, {0, get_colume_idx(CaliColumnType::Cali_Name, curr_obj) }, {1, 1}, wxBOTTOM, FromDIP(15)); - BOOST_LOG_TRIVIAL(info) << "=====================" << title_name->GetLabelText().ToStdString(); + gbSizer->Add(title_name, {0, column_idx++ }, {1, 1}, wxBOTTOM, FromDIP(15)); auto title_preset_name = new Label(m_history_data_panel, _L("Filament")); title_preset_name->SetFont(Label::Head_14); - gbSizer->Add(title_preset_name, { 0, get_colume_idx(CaliColumnType::Cali_Filament, curr_obj) }, { 1, 1 }, wxBOTTOM, FromDIP(15)); + gbSizer->Add(title_preset_name, { 0, column_idx++ }, { 1, 1 }, wxBOTTOM, FromDIP(15)); + + if (has_nozzle_id) { + auto nozzle_id_name = new Label(m_history_data_panel, _L("Nozzle ID")); + nozzle_id_name->SetFont(Label::Head_14); + { + wxString chd_ext_name = _L(DevPrinterConfigUtil::get_toolhead_display_name(curr_obj->printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)); + nozzle_id_name->SetToolTip(wxString::Format(_L("Note: The hotend number on the %s is tied to the holder. When the hotend is moved to a new holder, its number will update automatically."), chd_ext_name)); + } + gbSizer->Add(nozzle_id_name, {0, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + } if (support_nozzle_volume(curr_obj)) { auto nozzle_name = new Label(m_history_data_panel, _L("Nozzle Flow")); nozzle_name->SetFont(Label::Head_14); - gbSizer->Add(nozzle_name, {0, get_colume_idx(CaliColumnType::Cali_Nozzle, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(nozzle_name, {0, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); } auto title_k = new Label(m_history_data_panel, _L("Factor K")); title_k->SetFont(Label::Head_14); - gbSizer->Add(title_k, { 0, get_colume_idx(CaliColumnType::Cali_K_Value,curr_obj) }, { 1, 1 }, wxBOTTOM, FromDIP(15)); + gbSizer->Add(title_k, { 0, column_idx++ }, { 1, 1 }, wxBOTTOM, FromDIP(15)); // Hide //auto title_n = new Label(m_history_data_panel, wxID_ANY, _L("N")); @@ -357,7 +396,12 @@ void HistoryWindow::sync_history_data() { auto title_action = new Label(m_history_data_panel, _L("Action")); title_action->SetFont(Label::Head_14); - gbSizer->Add(title_action, {0, get_colume_idx(CaliColumnType::Cali_Delete, curr_obj)}, {1, 1}); + gbSizer->Add(title_action, {0, column_idx++}, {1, 1}); + + // grid item num in row (Delete + Edit share one "Action" header) + const int column_count = column_idx + 1; + // reset column_idx for the data rows + column_idx = 0; int i = 1; for (auto& result : m_calib_results_history) { @@ -373,13 +417,13 @@ void HistoryWindow::sync_history_data() { n_value->Hide(); auto delete_button = new Button(m_history_data_panel, _L("Delete")); delete_button->SetStyle(ButtonStyle::Alert, ButtonType::Window); - delete_button->Bind(wxEVT_BUTTON, [this, gbSizer, i, &result](auto& e) { + delete_button->Bind(wxEVT_BUTTON, [this, gbSizer, i, &result, column_count](auto& e) { if (m_ui_op_lock) { return; } else { m_ui_op_lock = true; } - for (int j = 0; j < HISTORY_WINDOW_ITEMS_COUNT; j++) { + for (int j = 0; j < column_count; j++) { auto item = gbSizer->FindItemAtPosition({ i, j }); if (item && item->GetWindow()) item->GetWindow()->Hide(); @@ -392,6 +436,8 @@ void HistoryWindow::sync_history_data() { cali_info.cali_idx = result.cali_idx; cali_info.nozzle_diameter = result.nozzle_diameter; cali_info.filament_id = result.filament_id; + cali_info.nozzle_pos_id = result.nozzle_pos_id; + cali_info.nozzle_sn = result.nozzle_sn; CalibUtils::delete_PA_calib_result(cali_info); }); @@ -418,17 +464,23 @@ void HistoryWindow::sync_history_data() { } }); - gbSizer->Add(name_value, {i, get_colume_idx(CaliColumnType::Cali_Name, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); - gbSizer->Add(preset_name_value, {i, get_colume_idx(CaliColumnType::Cali_Filament, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(name_value, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(preset_name_value, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + if (has_nozzle_id) { + wxString nozzle_id = nozzle_id_code_to_string(result.nozzle_pos_id); + auto nozzle_id_label = new Label(m_history_data_panel, nozzle_id); + gbSizer->Add(nozzle_id_label, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + } if (support_nozzle_volume(curr_obj)) { wxString nozzle_name = get_nozzle_volume_type_name(result.nozzle_volume_type); auto nozzle_name_label = new Label(m_history_data_panel, nozzle_name); - gbSizer->Add(nozzle_name_label, {i, get_colume_idx(CaliColumnType::Cali_Nozzle, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(nozzle_name_label, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); } - gbSizer->Add(k_value, {i, get_colume_idx(CaliColumnType::Cali_K_Value, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(k_value, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); //gbSizer->Add(n_value, { i, 3 }, { 1, 1 }, wxBOTTOM, FromDIP(15)); - gbSizer->Add(delete_button, {i, get_colume_idx(CaliColumnType::Cali_Delete, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); - gbSizer->Add(edit_button, {i, get_colume_idx(CaliColumnType::Cali_Edit, curr_obj)}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(delete_button, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + gbSizer->Add(edit_button, {i, column_idx++}, {1, 1}, wxBOTTOM, FromDIP(15)); + column_idx = 0; i++; m_ui_op_lock = false; } @@ -523,13 +575,22 @@ EditCalibrationHistoryDialog::EditCalibrationHistoryDialog(wxWindow if (obj && obj->is_multi_extruders()) { Label *extruder_name_title = new Label(top_panel, _L("Extruder")); - int extruder_index = obj->is_main_extruder_on_left() ? result.extruder_id : 1 - result.extruder_id; - wxString extruder_name = extruder_index == 0 ? _L("Left") : _L("Right"); + wxString extruder_name = _L(DevPrinterConfigUtil::get_toolhead_display_name( + obj->printer_type, result.extruder_id, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true)); Label *extruder_name_value = new Label(top_panel, extruder_name); flex_sizer->Add(extruder_name_title); flex_sizer->Add(extruder_name_value); } + if (obj && obj->GetNozzleSystem() && obj->GetNozzleSystem()->GetNozzleRack() + && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported() && result.extruder_id == MAIN_EXTRUDER_ID) { + Label* nozzle_id_title = new Label(top_panel, _L("Nozzle ID")); + wxString nozzle_id = nozzle_id_code_to_string(result.nozzle_pos_id); + Label* nozzle_id_value = new Label(top_panel, nozzle_id); + flex_sizer->Add(nozzle_id_title); + flex_sizer->Add(nozzle_id_value); + } + if (support_nozzle_volume(curr_obj)) { Label *nozzle_name_title = new Label(top_panel, _L("Nozzle")); wxString nozzle_name; @@ -768,14 +829,40 @@ NewCalibrationHistoryDialog::NewCalibrationHistoryDialog(wxWindow *parent, const Label *extruder_name_title = new Label(top_panel, _L("Extruder")); m_comboBox_extruder = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY); wxArrayString extruder_items; - extruder_items.push_back(_L("Left")); - extruder_items.push_back(_L("Right")); + extruder_items.push_back(_L(DevPrinterConfigUtil::get_toolhead_display_name( + curr_obj->printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); + extruder_items.push_back(_L(DevPrinterConfigUtil::get_toolhead_display_name( + curr_obj->printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); m_comboBox_extruder->Set(extruder_items); m_comboBox_extruder->SetSelection(-1); flex_sizer->Add(extruder_name_title); flex_sizer->Add(m_comboBox_extruder); } + // Nozzle ID (rack printers only): choose the hotend position this manual record belongs to. + if (curr_obj->GetNozzleSystem() && curr_obj->GetNozzleSystem()->GetNozzleRack() + && curr_obj->GetNozzleSystem()->GetNozzleRack()->IsSupported()) { + auto rack = curr_obj->GetNozzleSystem()->GetNozzleRack(); + Label *nozzle_id_title = new Label(top_panel, _L("Nozzle ID")); + m_comboBox_nozzle_id = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY); + m_comboBox_nozzle_id->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &NewCalibrationHistoryDialog::on_select_nozzle_pos, this); + + auto main_extder = curr_obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID); + int r_nozzle_id = main_extder ? main_extder->GetNozzleId() : 0; + auto r_nozzle = curr_obj->GetNozzleSystem()->GetExtNozzle(r_nozzle_id); + if (r_nozzle.IsNormal()) { + m_comboBox_nozzle_id->Append("R", wxNullBitmap, new int{0}); + } + for (auto nozzle_item : rack->GetRackNozzles()) { + if (nozzle_item.second.IsNormal()) { + m_comboBox_nozzle_id->Append(wxString::Format("%d", nozzle_item.first + 1), wxNullBitmap, new int{0x10 | nozzle_item.first}); + } + } + m_comboBox_nozzle_id->SetSelection(-1); + flex_sizer->Add(nozzle_id_title); + flex_sizer->Add(m_comboBox_nozzle_id); + } + if (support_nozzle_volume(curr_obj)) { Label *nozzle_name_title = new Label(top_panel, _L("Nozzle")); m_comboBox_nozzle_type = new ::ComboBox(top_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, NEW_HISTORY_DIALOG_INPUT_SIZE, 0, nullptr, wxCB_READONLY); @@ -839,6 +926,35 @@ int NewCalibrationHistoryDialog::get_extruder_id(int extruder_index) return 0; } +int NewCalibrationHistoryDialog::get_nozzle_combo_id_code() const +{ + if (!m_comboBox_nozzle_id) + return -1; + + auto sel = m_comboBox_nozzle_id->GetSelection(); + if (sel != wxNOT_FOUND && m_comboBox_nozzle_id->GetClientData(sel)) + return *(reinterpret_cast(m_comboBox_nozzle_id->GetClientData(sel))); + + return -1; +} + +void NewCalibrationHistoryDialog::on_select_nozzle_pos(wxCommandEvent &event) +{ + // Mirror the picked hotend's flow onto the (Orca index-based) nozzle-type combo. + if (!curr_obj || !m_comboBox_nozzle_id || !m_comboBox_nozzle_type || !curr_obj->GetNozzleSystem()) + return; + + int pos = get_nozzle_combo_id_code(); + if (pos < 0) + return; + + DevNozzle nozzle = curr_obj->GetNozzleSystem()->GetNozzleByPosId(pos); + if (nozzle.IsNormal()) { + NozzleVolumeType volume_type = DevNozzle::ToNozzleVolumeType(nozzle.GetNozzleFlowType()); + m_comboBox_nozzle_type->SetSelection(static_cast(volume_type)); + } +} + void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event) { wxString name = m_name_value->GetTextCtrl()->GetValue(); @@ -897,6 +1013,7 @@ void NewCalibrationHistoryDialog::on_ok(wxCommandEvent &event) m_new_result.nozzle_diameter = nozzle_value; m_new_result.filament_id = filament_id; m_new_result.setting_id = setting_id; + m_new_result.nozzle_pos_id = get_nozzle_combo_id_code(); // Check for duplicate names from history { diff --git a/src/slic3r/GUI/CaliHistoryDialog.hpp b/src/slic3r/GUI/CaliHistoryDialog.hpp index 3eb0a84f9d..d5159b634c 100644 --- a/src/slic3r/GUI/CaliHistoryDialog.hpp +++ b/src/slic3r/GUI/CaliHistoryDialog.hpp @@ -27,6 +27,7 @@ protected: void enbale_action_buttons(bool enable); float get_nozzle_value(); int get_extruder_id(); + bool support_nozzle_id_column(); void on_click_new_button(wxCommandEvent &event); @@ -76,10 +77,12 @@ public: protected: virtual void on_ok(wxCommandEvent &event); virtual void on_cancel(wxCommandEvent &event); + void on_select_nozzle_pos(wxCommandEvent &event); wxArrayString get_all_filaments(const MachineObject *obj); int get_extruder_id(int extruder_index); // extruder_index 0 : left, 1 : right + int get_nozzle_combo_id_code() const; // rack hotend position code, -1 if none protected: PACalibResult m_new_result; @@ -93,6 +96,7 @@ protected: ComboBox *m_comboBox_filament; ComboBox *m_comboBox_extruder; ComboBox *m_comboBox_nozzle_type; + ComboBox *m_comboBox_nozzle_id{nullptr}; struct FilamentInfos { diff --git a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp index 970635c770..db97354ad1 100644 --- a/src/slic3r/GUI/CalibrationWizardPresetPage.cpp +++ b/src/slic3r/GUI/CalibrationWizardPresetPage.cpp @@ -9,7 +9,9 @@ #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevFilaBlackList.h" #include "DeviceCore/DevFilaSystem.h" +#include "DeviceCore/DevFilaSwitch.h" #include "DeviceCore/DevManager.h" +#include "DeviceCore/DevNozzleSystem.h" #include "DeviceCore/DevStorage.h" #define CALIBRATION_LABEL_SIZE wxSize(FromDIP(150), FromDIP(24)) @@ -1457,31 +1459,40 @@ bool CalibrationPresetPage::is_filament_in_blacklist(int tray_id, Preset* preset get_tray_ams_and_slot_id(curr_obj, tray_id, ams_id, slot_id, out_tray_id); if (wxGetApp().app_config->get("skip_ams_blacklist_check") != "true") { - bool in_blacklist = false; - std::string action; - wxString info; - std::string filamnt_type; - preset->get_filament_type(filamnt_type); + DevFilaBlacklist::CheckFilamentInfo check_info; + check_info.dev_id = curr_obj->get_dev_id(); + check_info.model_id = curr_obj->printer_type; + check_info.fila_id = preset->filament_id; + preset->get_filament_type(check_info.fila_type); + check_info.ams_id = ams_id; + check_info.slot_id = slot_id; + check_info.has_filament_switch = curr_obj->GetFilaSwitch()->IsInstalled(); + // fila_name intentionally left empty: the engine recovers it from the selected AMS slot, + // preserving the name-match behavior. auto vendor = dynamic_cast (preset->config.option("filament_vendor")); if (vendor && (vendor->values.size() > 0)) { - std::string vendor_name = vendor->values[0]; - DevFilaBlacklist::check_filaments_in_blacklist(curr_obj->printer_type, vendor_name, filamnt_type, preset->filament_id, ams_id, slot_id, "", in_blacklist, action, info); + check_info.fila_vendor = vendor->values[0]; } - if (in_blacklist) { - error_tips = info.ToUTF8().data(); - if (action == "prohibition") { - return false; - } - else if (action == "warning") { - return true; - } + const auto &result = DevFilaBlacklist::check_filaments_in_blacklist(check_info); + + if (const auto &prohibition_items = result.get_items_by_action("prohibition"); !prohibition_items.empty()) { + wxString combined_msg; + for (const auto &item : prohibition_items) { combined_msg += item.info_msg + "\n"; } + error_tips = combined_msg.ToUTF8().data(); + return false; } - else { - error_tips = ""; + + if (const auto &warning_items = result.get_items_by_action("warning"); !warning_items.empty()) { + wxString combined_msg; + for (const auto &item : warning_items) { combined_msg += item.info_msg + "\n"; } + error_tips = combined_msg.ToUTF8().data(); return true; } + + error_tips = ""; + return true; } if (devPrinterUtil::IsVirtualSlot(ams_id)) { if (m_cali_mode == CalibMode::Calib_PA_Line && (m_cali_method == CalibrationMethod::CALI_METHOD_AUTO || m_cali_method == CalibrationMethod::CALI_METHOD_NEW_AUTO)) { @@ -1663,7 +1674,9 @@ bool CalibrationPresetPage::is_nozzle_info_synced() const if (curr_obj->is_nozzle_flow_type_supported()) { if (extruder.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE) return false; - if (int(extruder.GetNozzleFlowType()) - 1 != int(get_nozzle_volume_type(extruder_id))) + // Map device flow -> volume type via DevNozzle::ToNozzleVolumeType so U_FLOW resolves to + // nvtTPUHighFlow(3); the naive flow-1 would yield nvtHybrid(2). Identical to flow-1 for S/H flow. + if (int(DevNozzle::ToNozzleVolumeType(extruder.GetNozzleFlowType())) != int(get_nozzle_volume_type(extruder_id))) return false; } } @@ -2124,7 +2137,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) } if (obj->GetExtderSystem()->GetNozzleFlowType(i) != NozzleFlowType::NONE_FLOWTYPE) { - m_left_comboBox_nozzle_volume->SetSelection(obj->GetExtderSystem()->GetNozzleFlowType(i) - 1); + m_left_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i)))); } else { m_left_comboBox_nozzle_volume->SetSelection(0); } @@ -2144,7 +2157,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) } if (obj->GetExtderSystem()->GetNozzleFlowType(i) != NozzleFlowType::NONE_FLOWTYPE) { - m_right_comboBox_nozzle_volume->SetSelection(obj->GetExtderSystem()->GetNozzleFlowType(i) - 1); + m_right_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(i)))); } else { m_right_comboBox_nozzle_volume->SetSelection(0); } @@ -2182,7 +2195,7 @@ void CalibrationPresetPage::init_with_machine(MachineObject* obj) else { if ((obj->GetExtderSystem()->GetTotalExtderCount() > 0) && (obj->GetExtderSystem()->GetNozzleFlowType(0) != NozzleFlowType::NONE_FLOWTYPE)) { - m_comboBox_nozzle_volume->SetSelection(obj->GetExtderSystem()->GetNozzleFlowType(0) - 1); + m_comboBox_nozzle_volume->SetSelection(int(DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(0)))); } else { m_comboBox_nozzle_volume->SetSelection(0); } diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.cpp b/src/slic3r/GUI/CalibrationWizardSavePage.cpp index f14238d990..78bc4bb77f 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.cpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.cpp @@ -2,6 +2,9 @@ #include "I18N.hpp" #include "Widgets/Label.hpp" #include "MsgDialog.hpp" +#include "DeviceCore/DevConfigUtil.h" +#include "DeviceCore/DevNozzleSystem.h" +#include "DeviceCore/DevNozzleRack.h" namespace Slic3r { namespace GUI { @@ -95,35 +98,43 @@ enum class GridTextInputType { class GridTextInput : public TextInput { public: - GridTextInput(wxWindow* parent, wxString text, wxString label, wxSize size, int col_idx, GridTextInputType type); + GridTextInput(wxWindow* parent, wxString text, wxString label, wxSize size, int col_idx, GridTextInputType type, int extruder_id = MAIN_EXTRUDER_ID); int get_col_idx() { return m_col_idx; } void set_col_idx(int idx) { m_col_idx = idx; } + int get_extruder_id() { return m_extruder_id; } + void set_extruder_id(int id) { m_extruder_id = id; } GridTextInputType get_type() { return m_type; } void set_type(GridTextInputType type) { m_type = type; } private: int m_col_idx; + int m_extruder_id{MAIN_EXTRUDER_ID}; GridTextInputType m_type; }; -GridTextInput::GridTextInput(wxWindow* parent, wxString text, wxString label, wxSize size, int col_idx, GridTextInputType type) +GridTextInput::GridTextInput(wxWindow* parent, wxString text, wxString label, wxSize size, int col_idx, GridTextInputType type, int extruder_id) : TextInput(parent, text, label, "", wxDefaultPosition, size, wxTE_PROCESS_ENTER) , m_col_idx(col_idx) + , m_extruder_id(extruder_id) , m_type(type) { } class GridComboBox : public ComboBox { public: - GridComboBox(wxWindow* parent, wxSize size, int col_idx); + GridComboBox(wxWindow* parent, wxSize size, int col_idx, int extruder_id = MAIN_EXTRUDER_ID); int get_col_idx() { return m_col_idx; } void set_col_idx(int idx) { m_col_idx = idx; } + int get_extruder_id() { return m_extruder_id; } + void set_extruder_id(int id) { m_extruder_id = id; } private: int m_col_idx; + int m_extruder_id{MAIN_EXTRUDER_ID}; }; -GridComboBox::GridComboBox(wxWindow* parent, wxSize size, int col_idx) +GridComboBox::GridComboBox(wxWindow* parent, wxSize size, int col_idx, int extruder_id) : ComboBox(parent, wxID_ANY, "", wxDefaultPosition, size, 0, nullptr) , m_col_idx(col_idx) + , m_extruder_id(extruder_id) { } @@ -227,7 +238,7 @@ void CaliPASaveAutoPanel::sync_cali_result(const std::vector& cal m_calib_results.clear(); for (auto& item : cali_result) { if (item.confidence == 0) - m_calib_results[item.tray_id] = item; + m_calib_results.push_back(item); } m_grid_panel->DestroyChildren(); auto grid_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -281,14 +292,14 @@ void CaliPASaveAutoPanel::sync_cali_result(const std::vector& cal wxString tray_name = get_tray_name_by_tray_id(item.tray_id); tray_title->SetLabel(tray_name); - auto k_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::K); - auto n_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::N); + auto k_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::K, item.extruder_id); + auto n_value = new GridTextInput(m_grid_panel, "", "", CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, GridTextInputType::N, item.extruder_id); k_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); n_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); auto k_value_failed = new Label(m_grid_panel, _L("Failed")); auto n_value_failed = new Label(m_grid_panel, _L("Failed")); - auto comboBox_tray_name = new GridComboBox(m_grid_panel, CALIBRATION_SAVE_INPUT_SIZE, item.tray_id); + auto comboBox_tray_name = new GridComboBox(m_grid_panel, CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, item.extruder_id); auto tray_name_failed = new Label(m_grid_panel, " - "); wxArrayString selections; static std::vector filtered_results; @@ -395,17 +406,26 @@ void CaliPASaveAutoPanel::save_to_result_from_widgets(wxWindow* window, bool* ou return; //operate + // The grid can hold two rows with the same tray_id under different extruders + // (rack / dual-address configs), so results must be keyed by (tray_id, extruder_id). + auto find_result = [this](int tray_id, int extruder_id) -> PACalibResult* { + auto it = std::find_if(m_calib_results.begin(), m_calib_results.end(), [tray_id, extruder_id](const PACalibResult& r) { + return r.tray_id == tray_id && r.extruder_id == extruder_id; + }); + return it != m_calib_results.end() ? &(*it) : nullptr; + }; auto input = dynamic_cast(window); if (input && input->IsShown()) { - int tray_id = input->get_col_idx(); + int tray_id = input->get_col_idx(); + int extruder_id = input->get_extruder_id(); if (input->get_type() == GridTextInputType::K) { float k = 0.0f; if (!CalibUtils::validate_input_k_value(input->GetTextCtrl()->GetValue(), &k)) { *out_msg = wxString::Format(_L("Please input a valid value (K in %.1f~%.1f)"), MIN_PA_K_VALUE, MAX_PA_K_VALUE); *out_is_valid = false; } - else - m_calib_results[tray_id].k_value = k; + else if (auto* result = find_result(tray_id, extruder_id)) + result->k_value = k; } else if (input->get_type() == GridTextInputType::N) { } @@ -413,7 +433,8 @@ void CaliPASaveAutoPanel::save_to_result_from_widgets(wxWindow* window, bool* ou auto comboBox = dynamic_cast(window); if (comboBox && comboBox->IsShown()) { - int tray_id = comboBox->get_col_idx(); + int tray_id = comboBox->get_col_idx(); + int extruder_id = comboBox->get_extruder_id(); wxString name = comboBox->GetTextCtrl()->GetValue().ToStdString(); if (name.IsEmpty()) { *out_msg = _L("Please enter the name you want to save to printer."); @@ -423,7 +444,8 @@ void CaliPASaveAutoPanel::save_to_result_from_widgets(wxWindow* window, bool* ou *out_msg = _L("The name cannot exceed 40 characters."); *out_is_valid = false; } - m_calib_results[tray_id].name = into_u8(name); + if (auto* result = find_result(tray_id, extruder_id)) + result->name = into_u8(name); } auto childern = window->GetChildren(); @@ -441,52 +463,7 @@ bool CaliPASaveAutoPanel::get_result(std::vector& out_result) { else save_to_result_from_widgets(m_grid_panel, &is_valid, &err_msg); if (is_valid) { - /* - std::vector to_save_result; - for (auto &result : m_calib_results) { - auto iter = std::find_if(to_save_result.begin(), to_save_result.end(), [this, &result](const PACalibResult &item) { - bool has_same_name = (item.name == result.second.name && item.filament_id == result.second.filament_id); - if (m_obj && m_obj->is_multi_extruders()) { - has_same_name &= (item.extruder_id == result.second.extruder_id && item.nozzle_volume_type == result.second.nozzle_volume_type); - } - return has_same_name; - }); - - if (iter != to_save_result.end()) { - MessageDialog msg_dlg(nullptr, _L("Only one of the results with the same name will be saved. Are you sure you want to overwrite the other results?"), - wxEmptyString, wxICON_WARNING | wxYES_NO); - if (msg_dlg.ShowModal() != wxID_YES) { - return false; - } else { - break; - } - } - } - - for (auto &result : m_history_results) { - auto iter = std::find_if(m_history_results.begin(), m_history_results.end(), [this, &result](const PACalibResult &item) { - bool has_same_name = (item.name == result.name && item.filament_id == result.filament_id); - if (m_obj && m_obj->is_multi_extruders()) { - has_same_name &= (item.extruder_id == result.extruder_id && item.nozzle_volume_type == result.nozzle_volume_type); - } - return has_same_name; - }); - - if (iter != m_history_results.end()) { - MessageDialog msg_dlg(nullptr, - wxString::Format(_L("There is already a historical calibration result with the same name: %s. Are you sure you want to override the historical result?"), - result.name), - wxEmptyString, wxICON_WARNING | wxYES_NO); - if (msg_dlg.ShowModal() != wxID_YES) { - return false; - } - } - } - */ - - for (auto& result : m_calib_results) { - out_result.push_back(result.second); - } + out_result = m_calib_results; return true; } else { @@ -517,11 +494,12 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< m_calib_results.clear(); for (auto &item : cali_result) { if (item.confidence == 0) { - int tray_id = 4 * item.ams_id + item.slot_id; + PACalibResult result = item; + result.tray_id = 4 * item.ams_id + item.slot_id; if (item.ams_id == VIRTUAL_TRAY_MAIN_ID || item.ams_id == VIRTUAL_TRAY_DEPUTY_ID) { - tray_id = item.ams_id; + result.tray_id = item.ams_id; } - m_calib_results[tray_id] = item; + m_calib_results.push_back(result); } } m_multi_extruder_grid_panel->DestroyChildren(); @@ -532,14 +510,21 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< m_multi_extruder_grid_panel->SetSizer(grid_sizer, true); m_multi_extruder_grid_panel->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { SetFocusIgnoringChildren(); }); - wxStaticBoxSizer *left_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L("Left extruder")); - wxStaticBoxSizer *right_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L("Right extruder")); + const std::string& cwsp_pt = m_obj->printer_type; + wxStaticBoxSizer *left_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L(DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::SentenceCase))); + wxStaticBoxSizer *right_sizer = new wxStaticBoxSizer(wxVERTICAL, m_multi_extruder_grid_panel, _L(DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::SentenceCase))); grid_sizer->Add(left_sizer); grid_sizer->AddSpacer(COLUMN_GAP); grid_sizer->Add(right_sizer); wxFlexGridSizer *left_grid_sizer = new wxFlexGridSizer(3, COLUMN_GAP, ROW_GAP); - wxFlexGridSizer *right_grid_sizer = new wxFlexGridSizer(3, COLUMN_GAP, ROW_GAP); + + // The main extruder can carry a nozzle rack (H2C); non-rack printers keep the 3-column layout. + auto ns = m_obj->GetNozzleSystem(); + auto rack = ns ? ns->GetNozzleRack() : nullptr; + bool has_rack = rack && rack->IsSupported(); + + wxFlexGridSizer *right_grid_sizer = new wxFlexGridSizer(has_rack ? 4 : 3, COLUMN_GAP, ROW_GAP); left_sizer->Add(left_grid_sizer); right_sizer->Add(right_grid_sizer); @@ -567,29 +552,46 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< auto k_title = new Label(m_multi_extruder_grid_panel, _L("Factor K"), 0, CALIBRATION_SAVE_NUMBER_INPUT_SIZE); k_title->SetFont(Label::Head_14); right_grid_sizer->Add(k_title, 1, wxALIGN_CENTER); + + if (has_rack) { + auto nozzle_title = new Label(m_multi_extruder_grid_panel, _L("Nozzle ID"), 0, CALIBRATION_SAVE_NUMBER_INPUT_SIZE); + nozzle_title->SetFont(Label::Head_14); + right_grid_sizer->Add(nozzle_title, 1, wxALIGN_CENTER); + } } - std::vector> preset_names; + // key: (extruder_id, tray_id) + std::vector, std::string>> preset_names; int i = 1; std::unordered_set set; for (auto &info : m_obj->selected_cali_preset) { std::string default_name; - // extruder _id + // Derive extruder_id from the tray so the extruder/tray key stays consistent + // with the calibration result's extruder_id. + int extruder_id = 0; + if (info.tray_id == VIRTUAL_TRAY_MAIN_ID) { + extruder_id = 0; + } else if (info.tray_id == VIRTUAL_TRAY_DEPUTY_ID) { + extruder_id = 1; + } else { + int ams_id = info.tray_id / 4; + extruder_id = m_obj->get_extruder_id_by_ams_id(std::to_string(ams_id)); + } { - int extruder_id = 0; - if (info.tray_id == VIRTUAL_TRAY_MAIN_ID) { - extruder_id = 0; - } else if (info.tray_id == VIRTUAL_TRAY_DEPUTY_ID) { - extruder_id = 1; - } else { - int ams_id = info.tray_id / 4; - extruder_id = m_obj->get_extruder_id_by_ams_id(std::to_string(ams_id)); - } - - if (extruder_id == 0) { - default_name += L("Right Nozzle"); - } else if (extruder_id == 1){ - default_name += L("Left Nozzle"); + if (extruder_id == MAIN_EXTRUDER_ID) { + default_name += DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, MAIN_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase); + if (has_rack) { + default_name += "_"; + if (info.nozzle_pos_id == 0) { + default_name += "R"; + } else if (info.nozzle_pos_id >= 0x10) { + default_name += std::to_string((info.nozzle_pos_id & 0x0f) + 1); + } else { + default_name += "N/A"; + } + } + } else if (extruder_id == DEPUTY_EXTRUDER_ID) { + default_name += DevPrinterConfigUtil::get_toolhead_display_name(cwsp_pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase); } } @@ -614,7 +616,7 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< } } - preset_names.push_back({info.tray_id, default_name}); + preset_names.push_back({{extruder_id, info.tray_id}, default_name}); } bool left_first_add_item = true; @@ -648,14 +650,19 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< tray_title->SetBitmap(*get_extruder_color_icon(full_filament_ams_list[item.tray_id].opt_string("filament_colour", 0u), tray_name.ToStdString(), FromDIP(20), FromDIP(20))); tray_title->SetToolTip(""); - auto k_value = new GridTextInput(m_multi_extruder_grid_panel, "", "", CALIBRATION_SAVE_NUMBER_INPUT_SIZE, item.tray_id, GridTextInputType::K); - auto n_value = new GridTextInput(m_multi_extruder_grid_panel, "", "", CALIBRATION_SAVE_NUMBER_INPUT_SIZE, item.tray_id, GridTextInputType::N); + auto k_value = new GridTextInput(m_multi_extruder_grid_panel, "", "", CALIBRATION_SAVE_NUMBER_INPUT_SIZE, item.tray_id, GridTextInputType::K, item.extruder_id); + auto n_value = new GridTextInput(m_multi_extruder_grid_panel, "", "", CALIBRATION_SAVE_NUMBER_INPUT_SIZE, item.tray_id, GridTextInputType::N, item.extruder_id); k_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); n_value->GetTextCtrl()->SetValidator(wxTextValidator(wxFILTER_NUMERIC)); auto k_value_failed = new Label(m_multi_extruder_grid_panel, _L("Failed")); auto n_value_failed = new Label(m_multi_extruder_grid_panel, _L("Failed")); - auto comboBox_tray_name = new GridComboBox(m_multi_extruder_grid_panel, CALIBRATION_SAVE_INPUT_SIZE, item.tray_id); + auto nozzle_id_value = new Label(m_multi_extruder_grid_panel, wxEmptyString); + nozzle_id_value->SetMinSize(wxSize(FromDIP(180), FromDIP(24))); + nozzle_id_value->Wrap(-1); + auto nozzle_id_failed = new Label(m_multi_extruder_grid_panel, _L("Failed")); + + auto comboBox_tray_name = new GridComboBox(m_multi_extruder_grid_panel, CALIBRATION_SAVE_INPUT_SIZE, item.tray_id, item.extruder_id); auto tray_name_failed = new Label(m_multi_extruder_grid_panel, " - "); wxArrayString selections; static std::vector filtered_results; @@ -671,22 +678,26 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< } comboBox_tray_name->Set(selections); - auto set_edit_mode = [this, k_value, n_value, k_value_failed, n_value_failed, comboBox_tray_name, tray_name_failed](std::string str) { + auto set_edit_mode = [this, k_value, n_value, k_value_failed, n_value_failed, nozzle_id_value, nozzle_id_failed, comboBox_tray_name, tray_name_failed](std::string str, bool display_nozzle) { if (str == "normal") { comboBox_tray_name->Show(); tray_name_failed->Show(false); k_value->Show(); n_value->Show(); + nozzle_id_value->Show(display_nozzle); k_value_failed->Show(false); n_value_failed->Show(false); + nozzle_id_failed->Show(false); } if (str == "failed") { comboBox_tray_name->Show(false); tray_name_failed->Show(); k_value->Show(false); n_value->Show(false); + nozzle_id_value->Show(false); k_value_failed->Show(); n_value_failed->Show(); + nozzle_id_failed->Show(display_nozzle); } // hide n value @@ -698,15 +709,39 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< }; if (!result_failed) { - set_edit_mode("normal"); + set_edit_mode("normal", has_rack && item.extruder_id == MAIN_EXTRUDER_ID); auto k_str = wxString::Format("%.3f", item.k_value); auto n_str = wxString::Format("%.3f", item.n_coef); k_value->GetTextCtrl()->SetValue(k_str); n_value->GetTextCtrl()->SetValue(n_str); + if (has_rack && item.extruder_id == MAIN_EXTRUDER_ID) { + wxString nozzle_id_str; + if (item.nozzle_pos_id == 0) { + nozzle_id_str += "R | "; + } else if (item.nozzle_pos_id >= 0x10) { + nozzle_id_str += wxString::Format("%d | ", (item.nozzle_pos_id & 0x0f) + 1); + } else { + nozzle_id_str += "N/A | "; + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "Nozzle position id is -1 or invalid."; + } + nozzle_id_str += wxString::Format("%.1f mm ", item.nozzle_diameter); + switch (item.nozzle_volume_type) { + case NozzleVolumeType::nvtStandard: nozzle_id_str += _L("Standard Flow"); break; + case NozzleVolumeType::nvtHighFlow: nozzle_id_str += _L("High Flow"); break; + case NozzleVolumeType::nvtTPUHighFlow: nozzle_id_str += _L("TPU High Flow"); break; + default: break; + } + nozzle_id_value->SetLabel(nozzle_id_str); + } + for (auto &name : preset_names) { - if (item.tray_id == name.first) { comboBox_tray_name->SetValue(from_u8(name.second)); } + int extruder_id = name.first.first; + int tray_id = name.first.second; + if (item.tray_id == tray_id && item.extruder_id == extruder_id) { + comboBox_tray_name->SetValue(from_u8(name.second)); + } } comboBox_tray_name->Bind(wxEVT_COMBOBOX, [this, comboBox_tray_name, k_value, n_value](auto &e) { @@ -714,7 +749,7 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< auto history = filtered_results[selection]; }); } else { - set_edit_mode("failed"); + set_edit_mode("failed", has_rack && item.extruder_id == MAIN_EXTRUDER_ID); } if ((m_obj->is_main_extruder_on_left() && item.extruder_id == 0) @@ -762,6 +797,14 @@ void CaliPASaveAutoPanel::sync_cali_result_for_multi_extruder(const std::vector< } else { right_grid_sizer->Add(k_value_failed, 1, wxEXPAND); } + + if (has_rack) { + if (nozzle_id_value->IsShown()) { + right_grid_sizer->Add(nozzle_id_value, 1, wxEXPAND); + } else { + right_grid_sizer->Add(nozzle_id_failed, 1, wxEXPAND); + } + } } } diff --git a/src/slic3r/GUI/CalibrationWizardSavePage.hpp b/src/slic3r/GUI/CalibrationWizardSavePage.hpp index 3233116d34..4726cb1230 100644 --- a/src/slic3r/GUI/CalibrationWizardSavePage.hpp +++ b/src/slic3r/GUI/CalibrationWizardSavePage.hpp @@ -107,7 +107,10 @@ protected: wxPanel* m_part_failed_panel; wxPanel* m_grid_panel{ nullptr }; wxPanel* m_multi_extruder_grid_panel{ nullptr }; - std::map m_calib_results;// map + // keyed by (tray_id, extruder_id): the same tray_id can appear under two + // extruders (rack / dual-address configs), so a tray_id-only map would + // silently overwrite one extruder's K/N. + std::vector m_calib_results; std::vector m_history_results; bool m_is_all_failed{ true }; MachineObject* m_obj{ nullptr }; diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 46758e3e64..57f25eba24 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -713,6 +713,36 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in toggle_field("top_layer_direction", has_top_shell); toggle_field("bottom_layer_direction", has_bottom_shell); + toggle_line("top_surface_expansion", has_top_shell); + toggle_line("top_surface_expansion_margin", has_top_shell); + bool has_top_surface_expansion = config->opt_float("top_surface_expansion") > 0; + toggle_field("top_surface_expansion_margin", has_top_surface_expansion); + toggle_line("top_surface_expansion_direction", has_top_shell); + toggle_field("top_surface_expansion_direction", has_top_surface_expansion); + + // Orca: Archimedean Chords and Octagram Spiral are the centered surface patterns that the + // pattern-centering feature acts on. + auto is_centered_pattern = [](InfillPattern p) { + return p == InfillPattern::ipArchimedeanChords || p == InfillPattern::ipOctagramSpiral; + }; + bool is_top_centered = is_centered_pattern(config->option>("top_surface_pattern")->value); + bool is_bottom_centered = is_centered_pattern(config->option>("bottom_surface_pattern")->value); + bool has_centered_surface = (has_top_shell && is_top_centered) || (has_bottom_shell && is_bottom_centered); + + // Orca: center of surface pattern + toggle_line("center_of_surface_pattern", has_centered_surface); + + // Orca: separate infills + bool is_internal_infill_separable = is_separable_infill_pattern(config->option>("sparse_infill_pattern")->value) || + config->opt_string("sparse_infill_rotate_template") != "" || + config->opt_string("solid_infill_rotate_template") != ""; + toggle_line("separated_infills", is_internal_infill_separable); + + // Fill order is only meaningful for the center-based surface fill patterns; hide it otherwise. + auto is_centered_fill = [](InfillPattern p) { return p == ipConcentric || p == ipArchimedeanChords || p == ipOctagramSpiral; }; + toggle_line("top_surface_fill_order", has_top_shell && is_centered_fill(config->opt_enum("top_surface_pattern"))); + toggle_line("bottom_surface_fill_order", has_bottom_shell && is_centered_fill(config->opt_enum("bottom_surface_pattern"))); + for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap", "bridge_angle", "internal_bridge_angle", "relative_bridge_angle", "solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", @@ -916,7 +946,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in toggle_line("wipe_tower_extra_rib_length", have_rib_wall); toggle_line("wipe_tower_rib_width", have_rib_wall); toggle_line("wipe_tower_fillet_wall", have_rib_wall); - toggle_field("prime_tower_width", have_prime_tower && (supports_wipe_tower_2 || have_rib_wall)); + toggle_field("prime_tower_width", have_prime_tower && !have_rib_wall); toggle_line("single_extruder_multi_material_priming", !bSEMM && have_prime_tower && supports_wipe_tower_2); diff --git a/src/slic3r/GUI/ConfigWizard.cpp b/src/slic3r/GUI/ConfigWizard.cpp index 9d2a6e9905..0bbbc15f87 100644 --- a/src/slic3r/GUI/ConfigWizard.cpp +++ b/src/slic3r/GUI/ConfigWizard.cpp @@ -1440,7 +1440,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) spin_bed->SetValue(default_bed != nullptr && default_bed->size() > 0 ? default_bed->get_at(0) : 0); append_text(_L("Enter the nozzle_temperature needed for extruding your filament.")); - append_text(_L("A rule of thumb is 160 to 230 °C for PLA, and 215 to 250 °C for ABS.")); + append_text(_L("A rule of thumb is 160 to 230℃ for PLA, and 215 to 250℃ for ABS.")); #endif auto *sizer_extr = new wxFlexGridSizer(3, 5, 5); @@ -1455,7 +1455,7 @@ PageTemperatures::PageTemperatures(ConfigWizard *parent) append_spacer(VERTICAL_SPACING); append_text(_L("Enter the bed temperature needed for getting your filament to stick to your heated bed.")); - append_text(_L("A rule of thumb is 60 °C for PLA and 110 °C for ABS. Leave zero if you have no heated bed.")); + append_text(_L("A rule of thumb is 60℃ for PLA and 110℃ for ABS. Leave zero if you have no heated bed.")); auto *sizer_bed = new wxFlexGridSizer(3, 5, 5); auto *text_bed = new wxStaticText(this, wxID_ANY, _L("Bed Temperature:")); diff --git a/src/slic3r/GUI/DeviceCore/CMakeLists.txt b/src/slic3r/GUI/DeviceCore/CMakeLists.txt index 57fd747228..e06cbe0abe 100644 --- a/src/slic3r/GUI/DeviceCore/CMakeLists.txt +++ b/src/slic3r/GUI/DeviceCore/CMakeLists.txt @@ -28,6 +28,8 @@ list(APPEND SLIC3R_GUI_SOURCES GUI/DeviceCore/DevFilaSystem.h GUI/DeviceCore/DevFilaSystem.cpp GUI/DeviceCore/DevFilaSystemCtrl.cpp + GUI/DeviceCore/DevFilaSwitch.h + GUI/DeviceCore/DevFilaSwitch.cpp GUI/DeviceCore/DevFirmware.h GUI/DeviceCore/DevFirmware.cpp GUI/DeviceCore/DevPrintOptions.h @@ -47,10 +49,17 @@ list(APPEND SLIC3R_GUI_SOURCES GUI/DeviceCore/DevManager.cpp GUI/DeviceCore/DevMapping.h GUI/DeviceCore/DevMapping.cpp + GUI/DeviceCore/DevMappingNozzle.h + GUI/DeviceCore/DevMappingNozzle.cpp GUI/DeviceCore/DevNozzleSystem.h GUI/DeviceCore/DevNozzleSystem.cpp + GUI/DeviceCore/DevNozzleRack.h + GUI/DeviceCore/DevNozzleRack.cpp + GUI/DeviceCore/DevNozzleRackCtrl.cpp GUI/DeviceCore/DevUtil.h GUI/DeviceCore/DevUtil.cpp + GUI/DeviceCore/DevUtilBackend.h + GUI/DeviceCore/DevUtilBackend.cpp ) set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp b/src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp index 14fa87c127..03c5c0587d 100644 --- a/src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp +++ b/src/slic3r/GUI/DeviceCore/DevConfigUtil.cpp @@ -87,6 +87,28 @@ std::string DevPrinterConfigUtil::get_printer_ext_img(const std::string& type_st return (vec.size() > pos) ? vec[pos] : std::string(); }; +std::string DevPrinterConfigUtil::get_filament_load_img(const std::string &type_str, int ext_id, bool has_nozzle_rack) +{ + if (has_nozzle_rack) + { + const auto &rack_vec = get_value_from_config>(type_str, "filament_load_image_nozzle_rack"); + if (!rack_vec.empty()) + { + if (ext_id >= 0 && static_cast(ext_id) < rack_vec.size()) + { + return rack_vec[ext_id]; + } + return rack_vec[0]; + } + } + const auto &vec = get_value_from_config>(type_str, "filament_load_image"); + if (ext_id >= 0 && static_cast(ext_id) < vec.size()) + { + return vec[ext_id]; + } + return vec.empty() ? std::string() : vec[0]; +} + std::string DevPrinterConfigUtil::get_fan_text(const std::string& type_str, const std::string& key) { std::vector filaments; diff --git a/src/slic3r/GUI/DeviceCore/DevConfigUtil.h b/src/slic3r/GUI/DeviceCore/DevConfigUtil.h index 48b458768c..f8f9b21199 100644 --- a/src/slic3r/GUI/DeviceCore/DevConfigUtil.h +++ b/src/slic3r/GUI/DeviceCore/DevConfigUtil.h @@ -74,6 +74,7 @@ public: static std::string get_printer_use_ams_type(std::string type_str) { return get_value_from_config(type_str, "use_ams_type"); } static std::string get_printer_ams_img(const std::string& type_str) { return get_value_from_config(type_str, "printer_use_ams_image"); } static std::string get_printer_ext_img(const std::string& type_str, int pos);//printer_ext_image + static std::string get_filament_load_img(const std::string &type_str, int ext_id, bool has_nozzle_rack = false); /*fan*/ static std::string get_fan_text(const std::string& type_str, const std::string& key); diff --git a/src/slic3r/GUI/DeviceCore/DevDefs.h b/src/slic3r/GUI/DeviceCore/DevDefs.h index 468ed0184a..640f984024 100644 --- a/src/slic3r/GUI/DeviceCore/DevDefs.h +++ b/src/slic3r/GUI/DeviceCore/DevDefs.h @@ -10,6 +10,7 @@ #pragma once #include +#include enum PrinterArch { @@ -40,6 +41,41 @@ enum AmsStatusMain AMS_STATUS_MAIN_UNKNOWN = 0xFF, }; +enum DevAmsType : int +{ + EXT_SPOOL = 0, // EXT + AMS = 1, // AMS1 + AMS_LITE = 2, // AMS-Lite + N3F = 3, // N3F, AMS 2PRO + N3S = 4, // N3S, AMS HT + AMS_LITE_MIXED = 5, // AMS-Lite for N9 +}; + +// Device-numbered filament-change step codes. Newer firmware reports the exact change-step +// sequence through the AMS (ams.cfs), keyed by these codes, instead of the client hardcoding +// steps per model. Distinct from the legacy GUI-side Slic3r::GUI::FilamentStep enum. +// STEP_CHECK_POSITION and STEP_CONFIRM_EXTRUDED share code 0x08 by device design. +enum DevFilamentStep +{ + STEP_IDLE = 0x00, + STEP_PAUSE = 0x01, + STEP_HEAT_NOZZLE = 0x02, + STEP_CUT_FILAMENT = 0x03, + STEP_PULL_CURR_FILAMENT = 0x04, + STEP_PUSH_NEW_FILAMENT = 0x05, + STEP_GRAB_NEW_FILAMENT = 0x06, + STEP_PURGE_OLD_FILAMENT = 0x07, + STEP_CHECK_POSITION = 0x08, + STEP_SWITCH_EXTRUDER = 0x09, + STEP_SWITCH_HOTEND = 0x0A, + STEP_AMS_FILA_COOLING = 0x0B, + STEP_PUSH_SWITCHER_FILA = 0x0C, + STEP_PULL_SWITCHER_FILA = 0x0D, + STEP_SWITCHER_SWITCH = 0x0E, + STEP_CONFIRM_EXTRUDED = 0x08, + STEP_COUNT, +}; + // Slots and Tray #define VIRTUAL_TRAY_MAIN_ID 255 #define VIRTUAL_TRAY_DEPUTY_ID 254 @@ -47,21 +83,44 @@ enum AmsStatusMain #define VIRTUAL_AMS_MAIN_ID_STR "255" #define VIRTUAL_AMS_DEPUTY_ID_STR "254" +// Tray index offset for the AMS-Lite-mixed unit (A2L / N9). Its 4 trays occupy +// global tray indices 24..27. +#define AMS_LITE_MIXED_TRAY_INDEX_OFFSET 24 + #define INVALID_AMS_TEMPERATURE std::numeric_limits::min() +// (ams_id, slot_id) pair. +using DevAmsSlotId = std::pair; + /* Extruder*/ #define MAIN_EXTRUDER_ID 0 #define DEPUTY_EXTRUDER_ID 1 #define UNIQUE_EXTRUDER_ID MAIN_EXTRUDER_ID #define INVALID_EXTRUDER_ID -1 +/* Logical extruder ids (multi-nozzle). */ +#define LOGIC_UNIQUE_EXTRUDER_ID 0 +#define LOGIC_L_EXTRUDER_ID 0 +#define LOGIC_R_EXTRUDER_ID 1 + /* Nozzle*/ enum NozzleFlowType { NONE_FLOWTYPE, S_FLOW, - H_FLOW + H_FLOW, + U_FLOW, // TPU 1.75 High Flow (device-reported; maps to nvtTPUHighFlow) +}; + +// Discrete nozzle diameters reported by the device. +enum NozzleDiameterType : int +{ + NONE_DIAMETER_TYPE, + NOZZLE_DIAMETER_0_2, + NOZZLE_DIAMETER_0_4, + NOZZLE_DIAMETER_0_6, + NOZZLE_DIAMETER_0_8 }; /*Print speed*/ @@ -96,4 +155,39 @@ public: static bool IsVirtualSlot(const std::string& ams_id) { return (ams_id == VIRTUAL_AMS_MAIN_ID_STR || ams_id == VIRTUAL_AMS_DEPUTY_ID_STR); } }; -};// namespace Slic3r \ No newline at end of file +namespace GUI +{ +// Print source. Defined here (rather than in SelectMachine.hpp) so the shared device-mapping +// GUI headers — AmsMappingPopup, wgtDeviceNozzleSelect — can name it without pulling in +// SelectMachine.hpp, which would create an include cycle. +enum PrintFromType +{ + FROM_NORMAL, + FROM_SDCARD_VIEW, +}; +} + +};// namespace Slic3r + +// A nozzle requirement of the sliced plate (or an installed nozzle's identity), compared in the +// pre-print slicing-vs-installed nozzle checks. +struct NozzleDef +{ + float nozzle_diameter; + Slic3r::NozzleFlowType nozzle_flow_type; + + bool operator==(const NozzleDef& other) const + { + return nozzle_diameter == other.nozzle_diameter && nozzle_flow_type == other.nozzle_flow_type; + } +}; + +template<> struct std::hash +{ + std::size_t operator()(const NozzleDef& v) const noexcept + { + size_t h1 = std::hash{}(v.nozzle_diameter * 1000); + size_t h2 = std::hash{}(v.nozzle_flow_type); + return h1 ^ (h2 + 0x9e3779b9 + (h1 << 6) + (h1 >> 2)); + }; +}; \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp b/src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp index 6c96d85496..7f49f4ab3a 100644 --- a/src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevExtruderSystem.cpp @@ -1,6 +1,7 @@ #include #include "DevExtruderSystem.h" #include "DevNozzleSystem.h" +#include "DevFilaSystem.h" // complete type for GetFilaSystem()->GetTrayIndexMap() in GetBackupAmsSlotInGroup // TODO: remove this include #include "slic3r/GUI/DeviceManager.hpp" @@ -48,17 +49,43 @@ namespace Slic3r NozzleType DevExtder::GetNozzleType() const { - return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_nozzle_type; + return system->Owner()->GetNozzleSystem()->GetExtNozzle(m_current_nozzle_id).m_nozzle_type; } NozzleFlowType DevExtder::GetNozzleFlowType() const { - return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_nozzle_flow; + return system->Owner()->GetNozzleSystem()->GetExtNozzle(m_current_nozzle_id).m_nozzle_flow; } float DevExtder::GetNozzleDiameter() const { - return system->Owner()->GetNozzleSystem()->GetNozzle(m_current_nozzle_id).m_diameter; + return system->Owner()->GetNozzleSystem()->GetExtNozzle(m_current_nozzle_id).m_diameter; + } + + std::unordered_map DevExtder::GetBackupStatus(unsigned int fila_back_group) + { + std::unordered_map trayid_group; + for (int i = 0; i < 16; i++) + { + if (fila_back_group & (1 << i)) + { + trayid_group[i] = true; + } + } + + for (int j = 16; j <= 23; j++)/* single ams is from 128*/ + { + if (fila_back_group & (1 << j)) { + trayid_group[128 + j - 16] = true; + } + } + + for (int i = 24; i <= 27; i++) /* ams lite for N9*/ + { + if (fila_back_group & (1 << i)) { trayid_group[i] = true; } + } + + return trayid_group; } DevExtderSystem::DevExtderSystem(MachineObject* obj) @@ -143,6 +170,24 @@ namespace Slic3r return false; } + std::vector DevExtderSystem::GetBackupAmsSlotInGroup(const DevAmsSlotId& ams_slot_id) + { + std::map tray_map = Owner()->GetFilaSystem()->GetTrayIndexMap(); + + std::vector backup_group; + for (const auto& extruder : m_extders) { + for (int fila_backup : extruder.GetFilamBackup()) { + for (auto [tray_id, is_valid] : DevExtder::GetBackupStatus(fila_backup)) { + if (is_valid && tray_map.find(tray_id) != tray_map.end() && tray_map[tray_id] != ams_slot_id) { + backup_group.emplace_back(tray_map[tray_id]); + } + } + } + } + + return backup_group; + } + void ExtderSystemParser::ParseV1_0(const nlohmann::json& print_json, DevExtderSystem* system) { if (system->GetTotalExtderCount() != 1) diff --git a/src/slic3r/GUI/DeviceCore/DevExtruderSystem.h b/src/slic3r/GUI/DeviceCore/DevExtruderSystem.h index f4b174ba02..5e1b93174e 100644 --- a/src/slic3r/GUI/DeviceCore/DevExtruderSystem.h +++ b/src/slic3r/GUI/DeviceCore/DevExtruderSystem.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "libslic3r/CommonDefs.hpp" #include "slic3r/Utils/json_diff.hpp" @@ -66,6 +67,10 @@ public: bool HasFilamBackup() const { return !m_filam_bak.empty(); } std::vector GetFilamBackup() const { return m_filam_bak; } + // Decode a filament-backup bit group into { tray_id -> valid }. Bits 0-15 map directly to tray ids, + // bits 16-23 to single-AMS tray ids 128+, bits 24-27 to AMS-Lite-mixed (N9) tray ids 24-27. + static std::unordered_map GetBackupStatus(unsigned int fila_back_group); + // ams binding on current extruder const DevAmsSlotInfo& GetSlotPre() const { return m_spre; } const DevAmsSlotInfo& GetSlotNow() const { return m_snow; } @@ -168,6 +173,11 @@ public: bool HasFilamentBackup() const; bool HasFilamentInExt(int exter_id) { return GetExtderById(exter_id) ? GetExtderById(exter_id)->HasFilamentInExt() : false; } + // List the other AMS slots that back up the given slot within the same filament-backup group, + // across all extruders. Uses DevFilaSystem::GetTrayIndexMap() to translate backup bits (incl. the + // A2L/N9 AMS-Lite-mixed trays 24-27) into ams/slot ids. + std::vector GetBackupAmsSlotInGroup(const DevAmsSlotId& ams_slot_id); + protected: void AddExtder(const DevExtder& ext) { m_extders[ext.GetExtId()] = ext; }; diff --git a/src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp b/src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp index d2febcdec1..e75622720c 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp +++ b/src/slic3r/GUI/DeviceCore/DevFilaBlackList.cpp @@ -1,8 +1,12 @@ #include +#include +#include + #include "DevFilaBlackList.h" #include "DevFilaSystem.h" #include "DevManager.h" +#include "DevConfigUtil.h" #include "libslic3r/Utils.hpp" @@ -73,64 +77,97 @@ static std::string _get_filament_name_from_ams(int ams_id, int slot_id) } // moved from tao.wang and zhimin.zeng -void check_filaments(std::string model_id, - std::string tag_vendor, - std::string tag_type, - int ams_id, - int slot_id, - std::string tag_name, - bool& in_blacklist, - std::string& ac, - wxString& info, - wxString& wiki_url) +// Struct-in / struct-out, accumulate-all parser: every matching rule is pushed into +// result.action_items[action] and scanning continues (rather than stopping at the first match). +void check_filaments(const DevFilaBlacklist::CheckFilamentInfo& check_info, DevFilaBlacklist::CheckResult& result) { + std::string tag_type = check_info.fila_type; + std::string tag_name = check_info.fila_name; + std::string tag_vendor = check_info.fila_vendor; + std::string tag_calib_mode = check_info.calib_mode; + + // Orca: the print-send and calibration consumers do not populate fila_name; recover it from the + // selected AMS slot so name / name_suffix rules keep matching. if (tag_name.empty()) { - tag_name = _get_filament_name_from_ams(ams_id, slot_id); + tag_name = _get_filament_name_from_ams(check_info.ams_id, check_info.slot_id); } - in_blacklist = false; std::transform(tag_vendor.begin(), tag_vendor.end(), tag_vendor.begin(), ::tolower); std::transform(tag_type.begin(), tag_type.end(), tag_type.begin(), ::tolower); std::transform(tag_name.begin(), tag_name.end(), tag_name.begin(), ::tolower); + std::transform(tag_calib_mode.begin(), tag_calib_mode.end(), tag_calib_mode.begin(), ::tolower); DevFilaBlacklist::load_filaments_blacklist_config(); if (DevFilaBlacklist::filaments_blacklist.contains("blacklist")) { for (auto filament_item : DevFilaBlacklist::filaments_blacklist["blacklist"]) { - - std::string vendor = filament_item.contains("vendor") ? filament_item["vendor"].get() : ""; - std::string type = filament_item.contains("type") ? filament_item["type"].get() : ""; - std::string type_suffix = filament_item.contains("type_suffix") ? filament_item["type_suffix"].get() : ""; - std::string name = filament_item.contains("name") ? filament_item["name"].get() : ""; - std::string slot = filament_item.contains("slot") ? filament_item["slot"].get() : ""; - std::vector model_ids = filament_item.contains("model_id") ? filament_item["model_id"].get>() : std::vector(); std::string action = filament_item.contains("action") ? filament_item["action"].get() : ""; std::string description = filament_item.contains("description") ? filament_item["description"].get() : ""; + // blacklist items + std::string vendor = filament_item.contains("vendor") ? filament_item["vendor"].get() : ""; + std::string type = filament_item.contains("type") ? filament_item["type"].get() : ""; + std::vector types = filament_item.contains("types") ? filament_item["types"].get>() : std::vector(); + std::string type_suffix = filament_item.contains("type_suffix") ? filament_item["type_suffix"].get() : ""; + std::string name_suffix = filament_item.contains("name_suffix") ? filament_item["name_suffix"].get() : ""; + std::string name = filament_item.contains("name") ? filament_item["name"].get() : ""; + std::string slot = filament_item.contains("slot") ? filament_item["slot"].get() : ""; + std::optional used_for_print_support = filament_item.contains("used_for_print_support") ? filament_item["used_for_print_support"].get() : std::optional(); + std::optional used_for_print_object = filament_item.contains("used_for_print_object") ? filament_item["used_for_print_object"].get() : std::optional(); + std::vector model_ids = filament_item.contains("model_id") ? filament_item["model_id"].get>() : std::vector(); + std::vector extruder_ids = filament_item.contains("extruder_id") ? filament_item["extruder_id"].get>() : std::vector(); + std::vector nozzle_flows = filament_item.contains("nozzle_flows") ? filament_item["nozzle_flows"].get>() : std::vector(); + std::string calib_mode = filament_item.contains("calib_mode") ? filament_item["calib_mode"].get() : ""; + // check model id - if (!model_ids.empty() && std::find(model_ids.begin(), model_ids.end(), model_id) == model_ids.end()) { continue; } + if (!model_ids.empty() && std::find(model_ids.begin(), model_ids.end(), check_info.model_id) == model_ids.end()) { continue; } + + // A rule keyed on nozzle_flows/nozzle_diameters only matches when check_info carries real + // per-nozzle context (threaded by the print-send consumer). Consumers that leave + // nozzle_flow/nozzle_diameter unset (AMS edit, calibration, and the no-nozzle-context + // fallback) never satisfy the non-empty match below, so those rules stay dormant there. + + // check nozzle flows + if (!nozzle_flows.empty() && std::find(nozzle_flows.begin(), nozzle_flows.end(), check_info.nozzle_flow.value_or("")) == nozzle_flows.end()) { continue; } + + // check nozzle diameter + const std::vector nozzle_diameters = filament_item.contains("nozzle_diameters") ? filament_item["nozzle_diameters"].get>() : std::vector(); + if (!nozzle_diameters.empty() && check_info.nozzle_diameter.has_value() && + std::find(nozzle_diameters.begin(), nozzle_diameters.end(), check_info.nozzle_diameter.value()) == nozzle_diameters.end()) { + continue; + } // check vendor std::transform(vendor.begin(), vendor.end(), vendor.begin(), ::tolower); if (!vendor.empty()) { - if ((vendor == "bambu lab" && (tag_vendor == vendor)) || - (vendor == "third party" && (tag_vendor != "bambu lab"))) - { - // Do nothing - } - else + if (!((vendor == "bambu lab" && tag_vendor == "bambu lab") || + (vendor == "third party" && tag_vendor != "bambu lab"))) { continue; } } + // check calib mode + std::transform(calib_mode.begin(), calib_mode.end(), calib_mode.begin(), ::tolower); + if (!calib_mode.empty() && calib_mode != tag_calib_mode) { continue; } + // check type std::transform(type.begin(), type.end(), type.begin(), ::tolower); if (!type.empty() && (type != tag_type)) { continue; } + // check types (plural): item matches if tag_type is any of the listed types. + if (!types.empty()) + { + auto it = std::find_if(types.begin(), types.end(), [&tag_type](std::string ttype) { + std::transform(ttype.begin(), ttype.end(), ttype.begin(), ::tolower); + return ttype == tag_type; + }); + if (it == types.end()) { continue; } + } + // check type suffix std::transform(type_suffix.begin(), type_suffix.end(), type_suffix.begin(), ::tolower); if (!type_suffix.empty()) @@ -143,10 +180,31 @@ void check_filaments(std::string model_id, std::transform(name.begin(), name.end(), name.begin(), ::tolower); if (!name.empty() && (name != tag_name)) { continue; } + // check name suffix + std::transform(name_suffix.begin(), name_suffix.end(), name_suffix.begin(), ::tolower); + if (!name_suffix.empty()) + { + if (tag_name.length() < name_suffix.length()) { continue; } + if ((tag_name.substr(tag_name.length() - name_suffix.length()) != name_suffix)) { continue; } + } + + // check filament used for print support + if (used_for_print_support.has_value() && used_for_print_support != check_info.used_for_print_support) { continue; } + + // check filament used for print object + if (used_for_print_object.has_value() && used_for_print_object != check_info.used_for_print_object) { continue; } + + // check filament switch + if (filament_item.contains("has_filament_switch")) + { + bool has_filament_switch = filament_item["has_filament_switch"].get(); + if (check_info.has_filament_switch != has_filament_switch) { continue; } + } + // check loc if (!slot.empty()) { - bool is_virtual_slot = devPrinterUtil::IsVirtualSlot(ams_id); + bool is_virtual_slot = devPrinterUtil::IsVirtualSlot(check_info.ams_id); bool check_virtual_slot = (slot == "ext"); bool check_ams_slot = (slot == "ams"); if (is_virtual_slot && !check_virtual_slot) @@ -159,71 +217,115 @@ void check_filaments(std::string model_id, } } - if (GUI::wxGetApp().app_config->get("skip_ams_blacklist_check") == "true") { - action = "warning"; + // check extruder id + if (!extruder_ids.empty() && check_info.extruder_id.has_value() && + std::find(extruder_ids.begin(), extruder_ids.end(), check_info.extruder_id.value()) == extruder_ids.end()) { + continue; } - in_blacklist = true; - ac = action; - info = _L(description); - wiki_url = filament_item.contains("wiki") ? filament_item["wiki"].get() : ""; - return; + // white items: a matched rule is suppressed when the filament is whitelisted + { + // contains match + std::set white_names = filament_item.contains("white_names") ? filament_item["white_names"].get>() : std::set(); + if (!white_names.empty() && !tag_name.empty()) + { + auto it = std::find_if(white_names.begin(), white_names.end(), [&tag_name](std::string white_name) { + std::transform(white_name.begin(), white_name.end(), white_name.begin(), ::tolower); + return tag_name.find(white_name) != std::string::npos; + }); + if (it != white_names.end()) { continue; } + } + } + { + // equal match + std::set white_fila_ids = filament_item.contains("white_fila_ids") ? filament_item["white_fila_ids"].get>() : std::set(); + if (!white_fila_ids.empty() && !check_info.fila_id.empty()) + { + auto it = std::find_if(white_fila_ids.begin(), white_fila_ids.end(), [&check_info](const std::string& white_fila_id) { + return white_fila_id == check_info.fila_id; + }); + if (it != white_fila_ids.end()) { continue; } + } + } + + // the item is matched: accumulate it (do not stop scanning) + DevFilaBlacklist::CheckResultItem result_item; + result_item.action = action; + result_item.wiki_url = filament_item.contains("wiki") ? filament_item["wiki"].get() : ""; + + if (description == "%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution.") { + result_item.info_msg = wxString::Format(_L(description), check_info.fila_name); + } else if (description == "%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution.") { + result_item.info_msg = wxString::Format(_L(description), check_info.fila_type); + } else if (description == "%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution.") { + result_item.info_msg = wxString::Format(_L(description), check_info.fila_name); + } else if (description == "%s may fail to load or unload due to the Filament Track Switch. If you wish to continue.") { + result_item.info_msg = wxString::Format(_L(description), check_info.fila_name); + } else { + result_item.info_msg = _L(description); + } + + result.action_items[result_item.action].push_back(result_item); + continue; // Error in description L("TPU is not supported by AMS."); L("AMS does not support 'Bambu Lab PET-CF'."); + L("The current filament doesn't support the E3D high-flow nozzle and can't be used."); + L("The current filament doesn't support the TPU high-flow nozzle and can't be used."); + L("Auto dynamic flow calibration is not supported for TPU filament."); + L("Bambu TPU 85A is not supported for printing with 0.4 mm Standard or High Flow nozzles."); // Warning in description + L("How to feed TPU filament."); + L("How to feed TPU filament on X2D."); L("Please cold pull before printing TPU to avoid clogging. You may use cold pull maintenance on the printer."); L("Damp PVA will become flexible and get stuck inside AMS, please take care to dry it before use."); L("Damp PVA is flexible and may get stuck in extruder. Dry it before use."); L("The rough surface of PLA Glow can accelerate wear on the AMS system, particularly on the internal components of the AMS Lite."); + L("PLA Glow may wear the AMS first stage feeder. Use an external spool instead."); L("CF/GF filaments are hard and brittle, it's easy to break or get stuck in AMS, please use with caution."); L("PPS-CF is brittle and could break in bended PTFE tube above Toolhead."); L("PPA-CF is brittle and could break in bended PTFE tube above Toolhead."); + L("Default settings may affect print quality. Adjust as needed for best results."); + L("%s has a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution."); + L("%s filaments are hard and brittle and could break in AMS, and there is also a risk of nozzle clogging when using 0.4mm high-flow nozzles. Use with caution."); + L("%s has a risk of nozzle clogging when using 0.4, 0.6, 0.8mm high-flow nozzles. Use with caution."); + L("%s may fail to load or unload due to the Filament Track Switch. If you wish to continue."); } } } - -void DevFilaBlacklist::check_filaments_in_blacklist(std::string model_id, - std::string tag_vendor, - std::string tag_type, - const std::string& filament_id, - int ams_id, - int slot_id, - std::string tag_name, - bool& in_blacklist, - std::string& ac, - wxString& info) +// Extends the prohibition-only bit check with a 4-level filament_extruder_compatibility model +// (0 printable / 1 error / 2 critical warning / 3 warning), bowden-extruder message variants and +// toolhead display names for the "%s extruder" name. +// +// Orca: several deliberate divergences preserve H2D dual-extruder behaviour when the compatibility +// key is absent (default 0 = printable): +// - The extruder is resolved from the ams_id rather than a threaded check_info.extruder_id with an +// early-return: extruder_id is only threaded on the print-send consumer, so falling back on +// ams_id keeps the bit-check firing on the AMS-edit / calibration paths. +// - The prohibition bit-check keeps check_info.fila_type for its "%s", preserving the exact H2D +// AMS-edit message that ships today. The new 4-level messages use the fila_name fallback since +// they stay inert until a filament declares the compatibility key (only X2D ships it). +// - is_bowden_extruder is assigned correctly here so the Bowden message variants actually fire. +void check_filaments_printable(const DevFilaBlacklist::CheckFilamentInfo& check_info, DevFilaBlacklist::CheckResult& result) { - wxString wiki_url; - check_filaments_in_blacklist_url(model_id, tag_vendor, tag_type, filament_id, ams_id, slot_id, tag_name, in_blacklist, ac, info, wiki_url); -} + DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) { return; } + MachineObject* obj = dev->get_selected_machine(); + if (obj == nullptr || !obj->is_multi_extruders()) { return; } -bool check_filaments_printable(const std::string &tag_vendor, const std::string &tag_type, const std::string& filament_id, int ams_id, bool &in_blacklist, std::string &ac, wxString &info) -{ - DeviceManager *dev = Slic3r::GUI::wxGetApp().getDeviceManager(); - if (!dev) { - return true; - } + Preset* printer_preset = GUI::get_printer_preset(obj); + if (!printer_preset) { return; } - MachineObject *obj = dev->get_selected_machine(); - if (obj == nullptr || !obj->is_multi_extruders()) { - return true; - } + ConfigOptionInts* physical_extruder_map_op = dynamic_cast(printer_preset->config.option("physical_extruder_map")); + if (!physical_extruder_map_op) { return; } - Preset *printer_preset = GUI::get_printer_preset(obj); - if (!printer_preset) - return true; - - ConfigOptionInts *physical_extruder_map_op = dynamic_cast(printer_preset->config.option("physical_extruder_map")); - if (!physical_extruder_map_op) - return true; std::vector physical_extruder_maps = physical_extruder_map_op->values; - int obj_extruder_id = obj->get_extruder_id_by_ams_id(std::to_string(ams_id)); + int obj_extruder_id = obj->get_extruder_id_by_ams_id(std::to_string(check_info.ams_id)); int extruder_idx = obj_extruder_id; for (int index = 0; index < physical_extruder_maps.size(); ++index) { if (physical_extruder_maps[index] == obj_extruder_id) { @@ -232,32 +334,85 @@ bool check_filaments_printable(const std::string &tag_vendor, const std::string } } - PresetBundle *preset_bundle = GUI::wxGetApp().preset_bundle; - std::optional filament_info = preset_bundle->get_filament_by_filament_id(filament_id, printer_preset->name); - if (filament_info.has_value() && !(filament_info->filament_printable >> extruder_idx & 1)) { - wxString extruder_name = extruder_idx == 0 ? _L("left") : _L("right"); - ac = "prohibition"; - info = wxString::Format(_L("%s is not supported by %s extruder."), tag_type, extruder_name); - in_blacklist = true; - return false; + PresetBundle* preset_bundle = GUI::wxGetApp().preset_bundle; + std::optional filament_info = preset_bundle->get_filament_by_filament_id(check_info.fila_id, printer_preset->name); + if (!filament_info.has_value()) { return; } + + // Physical extruder 0 -> deputy (left), 1 -> main (right); the toolhead display name replaces the + // hard-coded left/right labels (falls back to "left"/"right" for printers without an override). + int bl_ext_id = (extruder_idx == 0) ? DEPUTY_EXTRUDER_ID : MAIN_EXTRUDER_ID; + wxString extruder_name = _L(DevPrinterConfigUtil::get_toolhead_display_name( + obj->printer_type, bl_ext_id, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase, true)); + + // Prohibition-only bit check; keeps fila_type in the "%s" to preserve current behaviour. + if (!(filament_info->filament_printable >> extruder_idx & 1)) { + DevFilaBlacklist::CheckResultItem item; + item.action = "prohibition"; + item.info_msg = wxString::Format(_L("%s is not supported by %s extruder."), check_info.fila_type, extruder_name); + result.action_items[item.action].push_back(item); + return; } - return true; + // Is this a bowden extruder? (drives the message variant for compatibility warnings.) + bool is_bowden_extruder = false; + auto extruder_type_opt = dynamic_cast(printer_preset->config.option("extruder_type")); + if (extruder_type_opt && (int) extruder_type_opt->values.size() > extruder_idx) { + ExtruderType extruder_type = (ExtruderType) extruder_type_opt->values[extruder_idx]; + is_bowden_extruder = (extruder_type == ExtruderType::etBowden); + } + + // Compatibility levels: 0 = printable, 1 = error, 2 = critical warning, 3 = warning (4-7 reserved). + std::string fila_name = check_info.fila_name.empty() ? check_info.fila_type : check_info.fila_name; + int compatible_val = filament_info->get_extruder_compatibility(extruder_idx); + if (compatible_val == 0) { + // printable, nothing to report + } else if (compatible_val == 1) { + DevFilaBlacklist::CheckResultItem item; + item.action = "prohibition"; + item.info_msg = wxString::Format(_L("%s is not supported by %s extruder."), fila_name, extruder_name); + result.action_items[item.action].push_back(item); + } else if (compatible_val == 2) { + DevFilaBlacklist::CheckResultItem item; + item.action = "warning"; + item.info_msg = is_bowden_extruder + ? wxString::Format(_L("There may be critical print quality issues when printing '%s' with %s Bowden extruder. Use with caution!"), fila_name, extruder_name) + : wxString::Format(_L("There may be critical print quality issues when printing '%s' with %s extruder. Use with caution!"), fila_name, extruder_name); + result.action_items[item.action].push_back(item); + } else if (compatible_val == 3) { + DevFilaBlacklist::CheckResultItem item; + item.action = "warning"; + item.info_msg = is_bowden_extruder + ? wxString::Format(_L("There may be print quality issues when printing '%s' with %s Bowden extruder. Use with caution."), fila_name, extruder_name) + : wxString::Format(_L("There may be print quality issues when printing '%s' with %s extruder. Use with caution."), fila_name, extruder_name); + result.action_items[item.action].push_back(item); + } } -void DevFilaBlacklist::check_filaments_in_blacklist_url(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info, wxString& wiki_url) +DevFilaBlacklist::CheckResult DevFilaBlacklist::check_filaments_in_blacklist(const CheckFilamentInfo& info) { - if (ams_id < 0 || slot_id < 0) + CheckResult result; + if (info.ams_id < 0 || info.slot_id < 0) { - return; + return result; } - if (!check_filaments_printable(tag_vendor, tag_type, filament_id, ams_id, in_blacklist, ac, info)) - { - return; + // check the filaments in preset + check_filaments_printable(info, result); + + // check the filaments in blacklist file + check_filaments(info, result); + + // If skip_ams_blacklist_check is true, demote every prohibition to a warning (aggregate: demote + // all at once rather than per-item). + if (GUI::wxGetApp().app_config->get("skip_ams_blacklist_check") == "true") { + const auto& prohibit_items = result.get_items_by_action("prohibition"); + if (!prohibit_items.empty()) { + for (const auto& prohibit_item : prohibit_items) { result.action_items["warning"].push_back(prohibit_item); } + result.action_items.erase("prohibition"); + } } - check_filaments(model_id, tag_vendor, tag_type, ams_id, slot_id, tag_name, in_blacklist, ac, info, wiki_url); + return result; } -} \ No newline at end of file +} diff --git a/src/slic3r/GUI/DeviceCore/DevFilaBlackList.h b/src/slic3r/GUI/DeviceCore/DevFilaBlackList.h index 7eed1f5a97..80340d6efd 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaBlackList.h +++ b/src/slic3r/GUI/DeviceCore/DevFilaBlackList.h @@ -1,18 +1,70 @@ #pragma once + +#include #include #include "slic3r/Utils/json_diff.hpp" namespace Slic3r { +class MachineObject; class DevFilaBlacklist { +public: + // Struct-in / struct-out check API that accumulates all matching rules, + // replacing the earlier out-param, first-match overloads. + // The per-nozzle dimensions (extruder_id/nozzle_flow/nozzle_diameter), calib_mode and + // has_filament_switch are currently left unset, so the engine behaves exactly as the + // old first-match parser for the shipping rule set. + struct CheckFilamentInfo + { + std::string dev_id; + std::string model_id; + + std::string fila_id; + std::string fila_type; + std::string fila_name; + std::string fila_vendor; + + std::string calib_mode; + bool has_filament_switch = false; + + std::optional used_for_print_support;// optional + std::optional used_for_print_object;// optional + + int ams_id; + int slot_id; + + std::optional extruder_id;// optional + std::optional nozzle_flow;// optional + std::optional nozzle_diameter;// optional + }; + + struct CheckResultItem + { + std::string action;// warning/prohibition + wxString info_msg; + wxString wiki_url; + }; + + struct CheckResult + { + std::map> action_items; + std::vector get_items_by_action(const std::string& action) const + { + auto it = action_items.find(action); + if (it != action_items.end()) { + return it->second; + } + return std::vector(); + } + }; + public: static bool load_filaments_blacklist_config(); - static void check_filaments_in_blacklist(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info); - static void check_filaments_in_blacklist_url(std::string model_id, std::string tag_vendor, std::string tag_type, const std::string& filament_id, int ams_id, int slot_id, std::string tag_name, bool& in_blacklist, std::string& ac, wxString& info, wxString& wiki_url); + static CheckResult check_filaments_in_blacklist(const CheckFilamentInfo& info); public: static json filaments_blacklist; };// class DevFilaBlacklist -}// namespace Slic3r \ No newline at end of file +}// namespace Slic3r diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSwitch.cpp b/src/slic3r/GUI/DeviceCore/DevFilaSwitch.cpp new file mode 100644 index 0000000000..1f7a9a7623 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevFilaSwitch.cpp @@ -0,0 +1,131 @@ +#include "DevExtruderSystem.h" +#include "DevFilaSystem.h" +#include "DevFilaSwitch.h" +#include "DevUtil.h" + +#include "slic3r/GUI/DeviceManager.hpp" + +namespace Slic3r { + +DevFilaSwitch::DevFilaSwitch(MachineObject *owner) { m_owner = owner; } + +bool DevFilaSwitch::IsReady() const +{ + if (!m_is_installed) { return false; } + + const auto& ams_list = m_owner->GetFilaSystem()->GetAmsList(); + for (const auto& ams_item : ams_list) { + if (ams_item.second->GetBindedExtruderSet().empty()) { return false; } + if (!ams_item.second->GetSwitcherPos().has_value()) { return false; } + } + + return true; +} + +void DevFilaSwitch::Reset() +{ + m_is_installed = false; + m_in_a_has_filament.reset(); + m_in_b_has_filament.reset(); + m_in_a_slot.reset(); + m_in_b_slot.reset(); + m_out_a_extruder_id.reset(); + m_out_b_extruder_id.reset(); + m_cali_status = CaliStatus::CALI_IDLE; +} + +std::optional DevFilaSwitch::GetInA_Slot() const +{ + auto ams_id_opt = GetInA_SlotId(); + if (m_owner && ams_id_opt.has_value()) { return m_owner->get_tray(std::to_string(ams_id_opt->first), std::to_string(ams_id_opt->first)); } + + return std::nullopt; +} + +std::optional DevFilaSwitch::GetInB_Slot() const +{ + auto ams_id_opt = GetInB_SlotId(); + if (m_owner && ams_id_opt.has_value()) { return m_owner->get_tray(std::to_string(ams_id_opt->first), std::to_string(ams_id_opt->first)); } + + return std::nullopt; +} + +std::optional DevFilaSwitch::GetOutA_Extruder() const +{ + auto ext_id_opt = GetOutA_ExtruderId(); + if (m_owner && ext_id_opt.has_value()) { return m_owner->GetExtderSystem()->GetExtderById(ext_id_opt.value()); } + + return std::nullopt; +} + +std::optional DevFilaSwitch::GetOutB_Extruder() const +{ + auto ext_id_opt = GetOutB_ExtruderId(); + if (m_owner && ext_id_opt.has_value()) { return m_owner->GetExtderSystem()->GetExtderById(ext_id_opt.value()); } + + return std::nullopt; +} + +void DevFilaSwitch::ParseFilaSwitchInfo(const nlohmann::json &print_jj) +{ + if (print_jj.contains("aux")) { + const auto &info_bits = DevJsonValParser::GetVal(print_jj, "aux"); + if (m_is_installed != (DevUtil::get_flag_bits(info_bits, 29, 1) == 1)) { + m_is_installed = (DevUtil::get_flag_bits(info_bits, 29, 1) == 1); + if (!m_is_installed) { Reset(); } + }; + } + + if (print_jj.contains("device") && print_jj["device"].contains("fila_switch")) { + const auto &fila_switch_jj = print_jj["device"]["fila_switch"]; + if (fila_switch_jj.contains("in")) { + const auto &in_vec = DevJsonValParser::GetVal>(fila_switch_jj, "in"); + if (in_vec.size() == 2) { + if (in_vec[0] != -1) { + DevAmsSlotId slot_id; + slot_id.first = DevUtil::get_flag_bits(in_vec[0], 8, 8); + slot_id.second = DevUtil::get_flag_bits(in_vec[0], 0, 8); + m_in_b_slot = slot_id; + } else { + m_in_b_slot = std::nullopt; + }; + + if (in_vec[1] != -1) { + DevAmsSlotId slot_id; + slot_id.first = DevUtil::get_flag_bits(in_vec[1], 8, 8); + slot_id.second = DevUtil::get_flag_bits(in_vec[1], 0, 8); + m_in_a_slot = slot_id; + } else { + m_in_a_slot.reset(); + }; + } + } + + if (fila_switch_jj.contains("out")) { + const auto &out_vec = DevJsonValParser::GetVal>(fila_switch_jj, "out"); + if (out_vec.size() == 2) { + if (out_vec[0] != 0xE) { + m_out_b_extruder_id = out_vec[0]; + } else { + m_out_b_extruder_id.reset(); + } + + if (out_vec[1] != 0xE) { + m_out_a_extruder_id = out_vec[1]; + } else { + m_out_a_extruder_id.reset(); + } + } + } + + if (fila_switch_jj.contains("stat")) { m_cali_status = DevJsonValParser::GetVal(fila_switch_jj, "stat"); } + + if (fila_switch_jj.contains("info")) { + const auto &info_bits = DevJsonValParser::GetVal(fila_switch_jj, "info"); + m_in_b_has_filament = DevUtil::get_flag_bits(info_bits, 0, 1); + m_in_a_has_filament = DevUtil::get_flag_bits(info_bits, 0, 1); + } + } +} + +}; // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSwitch.h b/src/slic3r/GUI/DeviceCore/DevFilaSwitch.h new file mode 100644 index 0000000000..e18dea338c --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevFilaSwitch.h @@ -0,0 +1,91 @@ +#pragma once +#include "DevDefs.h" +#include +#include + +namespace Slic3r +{ + // Previous definitions +class MachineObject; +class DevExtder; +class DevAmsTray; + +// Filament Track Switch (H2-family hardware). +// The filament blacklist consumes IsInstalled() for the `has_filament_switch` +// rule (e.g. PLA Silk). m_is_installed defaults to false and is only raised when +// the device reports the switch over MQTT (aux bit 29), so the rule stays inert on +// every printer that does not report an installed switch. +class DevFilaSwitch +{ +public: + enum class CaliStatus : int + { + CALI_IDLE = 0, + CALI_STEPING = 1, + }; + + enum class CaliStep : int + { + CALI_IDLE = 0, + CALI_SWITCHING = 1, + CALI_SWITCH_CHECK = 2, + CALI_FILA_CHECK = 3, + CALI_FILA_TO_AMS = 4, + CALI_FILA_TO_SWITCH = 5, + CALI_FILA_BACK = 9, + CALI_FINISHED = 14, + }; + + enum SwitchPos : int + { + POS_IN_B = 0, + POS_IN_A = 1, + }; + +public: + DevFilaSwitch(MachineObject* owner); + virtual ~DevFilaSwitch() = default; + +public: + bool IsInstalled() const { return m_is_installed; }; + + // Ready once installed and every AMS has resolved both its extruder binding and its + // switcher track position from the device. The send dialog and sidebar sync UX only + // treat the switch as usable when this is true. + bool IsReady() const; + + std::optional IsInA_HasFilament() const { return m_in_a_has_filament; }; + std::optional IsInB_HasFilament() const { return m_in_b_has_filament; }; + + std::optional GetInA_Slot() const; + std::optional GetInB_Slot() const; + std::optional GetInA_SlotId() const { return m_in_a_slot; }; + std::optional GetInB_SlotId() const { return m_in_b_slot; }; + + std::optional GetOutA_Extruder() const; + std::optional GetOutB_Extruder() const; + std::optional GetOutA_ExtruderId() const { return m_out_a_extruder_id; }; + std::optional GetOutB_ExtruderId() const { return m_out_b_extruder_id; }; + + CaliStatus GetCaliStatus() const { return m_cali_status; }; + + void Reset(); + void ParseFilaSwitchInfo(const nlohmann::json& print_jj); + +private: + MachineObject* m_owner; + + bool m_is_installed = false; + + std::optional m_in_a_has_filament; + std::optional m_in_b_has_filament; + + std::optional m_in_a_slot; + std::optional m_in_b_slot; + + std::optional m_out_a_extruder_id; + std::optional m_out_b_extruder_id; + + CaliStatus m_cali_status = CaliStatus::CALI_IDLE; +}; +}; diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp index 8f35ccf454..038032d0ca 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystem.cpp @@ -1,11 +1,13 @@ #include #include "DevFilaSystem.h" +#include "DevNozzleSystem.h" // DevNozzle / DevNozzleSystem for GetNozzleFlowStringByAmsId // TODO: remove this include #include "slic3r/GUI/DeviceManager.hpp" #include "slic3r/GUI/I18N.hpp" #include "DevUtil.h" +#include "DevUtilBackend.h" using namespace nlohmann; @@ -98,6 +100,11 @@ std::string DevAmsTray::get_filament_type() return m_fila_type; } +std::optional DevAmsTray::get_ams_drying_preset() const +{ + return DevUtilBackend::GetFilamentDryingPreset(setting_id); +} + DevAms::DevAms(const std::string& ams_id, int extruder_id, AmsType type) { @@ -111,7 +118,7 @@ DevAms::DevAms(const std::string& ams_id, int nozzle_id, int type) m_ams_id = ams_id; m_ext_id = nozzle_id; m_ams_type = (AmsType)type; - assert(DUMMY < type && m_ams_type <= N3S); + assert(EXT_SPOOL < type && m_ams_type <= AMS_LITE_MIXED); } DevAms::~DevAms() @@ -137,7 +144,8 @@ static unordered_map s_ams_display_formats = { wxString DevAms::GetDisplayName() const { wxString ams_display_format; - auto iter = s_ams_display_formats.find(m_ams_type); + // GetAmsType() maps AMS_LITE_MIXED -> AMS_LITE so N9 shows the AMS-Lite name. + auto iter = s_ams_display_formats.find(GetAmsType()); if (iter != s_ams_display_formats.end()) { ams_display_format = iter->second; @@ -166,11 +174,13 @@ wxString DevAms::GetDisplayName() const int DevAms::GetSlotCount() const { - if (m_ams_type == AMS || m_ams_type == AMS_LITE || m_ams_type == N3F) + // GetAmsType() maps AMS_LITE_MIXED -> AMS_LITE, so N9 reports 4 slots like AMS-Lite. + auto ams_type = GetAmsType(); + if (ams_type == AMS || ams_type == AMS_LITE || ams_type == N3F) { return 4; } - else if (m_ams_type == N3S) + else if (ams_type == N3S) { return 1; } @@ -189,6 +199,27 @@ DevAmsTray* DevAms::GetTray(const std::string& tray_id) const return nullptr; } +bool DevAms::IsSupportRemoteDry(const MachineObject* obj) const +{ + if (obj && obj->is_support_remote_dry) { + return SupportDrying(); + } + + return false; +} + +bool DevAms::AmsIsDrying() +{ + if (!GetDryStatus().has_value()) { + return false; + } + + return GetDryStatus().value() == DevAms::DryStatus::Checking + || GetDryStatus().value() == DevAms::DryStatus::Drying + || GetDryStatus().value() == DevAms::DryStatus::Error + || GetDryStatus().value() == DevAms::DryStatus::CannotStopHeatOutofControl; +} + DevFilaSystem::~DevFilaSystem() { for (auto it = amsList.begin(); it != amsList.end(); it++) @@ -258,6 +289,44 @@ int DevFilaSystem::GetExtruderIdByAmsId(const std::string& ams_id) const return 0; // not found } +std::string DevFilaSystem::GetNozzleFlowStringByAmsId(const std::string& ams_id) const +{ + auto extruder_id = GetExtruderIdByAmsId(ams_id); + auto nozzle = GetOwner()->GetNozzleSystem()->GetExtNozzle(extruder_id); + return DevNozzle::GetNozzleFlowTypeString(nozzle.GetNozzleFlowType()); +} + +std::map DevFilaSystem::GetTrayIndexMap() +{ + std::map tray_id_map; + tray_id_map[VIRTUAL_TRAY_MAIN_ID] = DevAmsSlotId{VIRTUAL_TRAY_MAIN_ID, 0}; + tray_id_map[VIRTUAL_TRAY_DEPUTY_ID] = DevAmsSlotId{VIRTUAL_TRAY_DEPUTY_ID, 0}; + + for (auto& [ams_id, ams_item] : GetAmsList()) { + for (auto &[slot_id, slot_item] : ams_item->GetTrays()) { + if (ams_item && slot_item) { + try { + int ams_id_int = stoi(ams_id); + int slot_id_int = stoi(slot_id); + int tray_index = -1; + if (ams_item->GetAmsType() == DevAms::N3S) { + tray_index = ams_id_int; + } else if(ams_item->GetAmsType() == DevAms::AMS_LITE && ams_item->IsAmsLiteMixed()) { + tray_index = 24 + slot_id_int; + } else { + tray_index = (ams_id_int * 4 + slot_id_int); + } + tray_id_map[tray_index] = {ams_id_int, slot_id_int}; + } catch(...) { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "invalid ams id: " << ams_id << " or slot id: " << slot_id; + } + } + } + } + + return tray_id_map; +} + bool DevFilaSystem::IsAmsSettingUp() const { int setting_up_stat = DevUtil::get_flag_bits(m_ams_cali_stat, 0, 8); @@ -304,6 +373,15 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS if (!key_field_only) { + // Newer firmware sends the exact filament-change step sequence in ams.cfs, so the + // client no longer hardcodes the steps per model. Absent on current firmware, which + // keeps the list empty and the legacy hardcoded/ams_status_sub step path in effect. + if (jj["ams"].contains("cfs")) { + system->m_filament_change_steps = DevJsonValParser::GetVal>(jj["ams"], "cfs"); + } else { + system->m_filament_change_steps.clear(); + } + if (jj["ams"].contains("tray_read_done_bits")) { obj->tray_read_done_bits = stol(jj["ams"]["tray_read_done_bits"].get(), nullptr, 16); @@ -361,17 +439,43 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS int type_id = 1; // 0:dummy 1:ams 2:ams-lite 3:n3f 4:n3s /*ams info*/ + std::set binded_extruder_set; + std::optional binded_switcher_pos; if (it->contains("info")) { const std::string& info = (*it)["info"].get(); type_id = DevUtil::get_flag_bits(info, 0, 4); extuder_id = DevUtil::get_flag_bits(info, 8, 4); + if (extuder_id == 0xE && obj->GetFilaSwitch()->IsInstalled()) { + int bind_switch_in = DevUtil::get_flag_bits(info, 24, 4); + if (bind_switch_in == 0 || bind_switch_in == 1) { + binded_extruder_set = { MAIN_EXTRUDER_ID, DEPUTY_EXTRUDER_ID }; + } + + if (bind_switch_in == 0) { + binded_switcher_pos = DevFilaSwitch::SwitchPos::POS_IN_B; + } else if (bind_switch_in == 1) { + binded_switcher_pos = DevFilaSwitch::SwitchPos::POS_IN_A; + } + + // Orca: the switch feeds every AMS to both extruders; pin a deterministic + // single-extruder id so legacy GetExtruderId() consumers keep a valid value + // while switch-aware code reads the binding set instead. + extuder_id = MAIN_EXTRUDER_ID; + } else if (extuder_id != 0xE) { + binded_extruder_set = { extuder_id }; + } } else { if (!obj->is_enable_ams_np && obj->get_printer_ams_type() == "f1") { type_id = DevAms::AMS_LITE; } + binded_extruder_set = { MAIN_EXTRUDER_ID }; } /*AMS without initialization*/ + // Orca: an AMS reporting extruder 0xE without a Filament Track Switch installed has + // no usable extruder binding; drop it, preserving the existing display for + // half-initialized printers. With the switch installed the 0xE case is remapped + // above to both extruders and falls through to normal handling. if (extuder_id == 0xE) { ams_id_set.erase(ams_id); @@ -403,6 +507,13 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS /*set ams type flag*/ curr_ams->SetAmsType(type_id); + // Refresh the switch-aware extruder binding on every push (both create and + // update paths) so it can't go stale after an AMS is re-homed to another + // extruder. Without the switch the set holds the single bound extruder and + // the track position stays empty. + curr_ams->m_binded_extruder_set = binded_extruder_set; + curr_ams->m_binded_switcher_pos = binded_switcher_pos; + /*set ams exist flag*/ try @@ -415,6 +526,11 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS { curr_ams->m_exist = (obj->ams_exist_bits & (1 << ams_id_int)) != 0 ? true : false; } + else if (type_id == DevAms::AMS_LITE_MIXED) + { + // Mixed AMS-Lite (A2L / N9) exist flag lives at bit 12. + curr_ams->m_exist = DevUtil::get_flag_bits(obj->ams_exist_bits, 12); + } else { curr_ams->m_exist = DevUtil::get_flag_bits(obj->ams_exist_bits, 4 + (ams_id_int - 128)); @@ -426,9 +542,18 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS ; } - if (it->contains("dry_time") && (*it)["dry_time"].is_number()) + + if (it->contains("temp")) { - curr_ams->m_left_dry_time = (*it)["dry_time"].get(); + std::string temp = (*it)["temp"].get(); + try + { + curr_ams->m_current_temperature = DevUtil::string_to_float(temp); + } + catch (...) + { + curr_ams->m_current_temperature = INVALID_AMS_TEMPERATURE; + } } if (it->contains("humidity")) @@ -457,17 +582,32 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS } } - - if (it->contains("temp")) + if (it->contains("dry_time") && (*it)["dry_time"].is_number()) { - std::string temp = (*it)["temp"].get(); - try - { - curr_ams->m_current_temperature = DevUtil::string_to_float(temp); + curr_ams->m_left_dry_time = (*it)["dry_time"].get(); + } + + // Drying status — only parse if printer supports remote drying + if (obj->is_support_remote_dry) { + if (it->contains("info")) { + const std::string& info = (*it)["info"].get(); + curr_ams->m_dry_status = (DevAms::DryStatus)DevUtil::get_flag_bits(info, 4, 4); + curr_ams->m_dry_fan1_status = (DevAms::DryFanStatus)DevUtil::get_flag_bits(info, 18, 2); + curr_ams->m_dry_fan2_status = (DevAms::DryFanStatus)DevUtil::get_flag_bits(info, 20, 2); + curr_ams->m_dry_sub_status = (DevAms::DrySubStatus)DevUtil::get_flag_bits(info, 22, 2); } - catch (...) - { - curr_ams->m_current_temperature = INVALID_AMS_TEMPERATURE; + + if (it->contains("dry_setting")) { + const auto& j_dry_settings = (*it)["dry_setting"]; + DevAms::DrySettings dry_settings; + DevJsonValParser::ParseVal(j_dry_settings, "dry_filament", dry_settings.dry_filament); + DevJsonValParser::ParseVal(j_dry_settings, "dry_temperature", dry_settings.dry_temp); + DevJsonValParser::ParseVal(j_dry_settings, "dry_duration", dry_settings.dry_hour); + curr_ams->m_dry_settings = dry_settings; + } + + if (it->contains("dry_sf_reason")) { + curr_ams->m_dry_cannot_reasons = DevJsonValParser::GetVal>((*it), "dry_sf_reason"); } } @@ -628,6 +768,11 @@ void DevFilaSystemParser::ParseV1_0(const json& jj, MachineObject* obj, DevFilaS { curr_tray->is_exists = (obj->tray_exist_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0 ? true : false; } + else if (type_id == DevAms::AMS_LITE_MIXED) + { + // Mixed AMS-Lite (A2L / N9) trays occupy tray-exist bits 24..27. + curr_tray->is_exists = DevUtil::get_flag_bits(obj->tray_exist_bits, AMS_LITE_MIXED_TRAY_INDEX_OFFSET + tray_id_int); + } else { curr_tray->is_exists = DevUtil::get_flag_bits(obj->tray_exist_bits, 16 + (ams_id_int - 128)); diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystem.h b/src/slic3r/GUI/DeviceCore/DevFilaSystem.h index 37a93729c8..27c59183c1 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystem.h +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystem.h @@ -4,11 +4,17 @@ #include "DevDefs.h" #include "DevFilaAmsSetting.h" +#include "DevFilaSwitch.h" #include "DevUtil.h" #include +#include +#include #include #include +#include +#include +#include #include #include @@ -17,6 +23,7 @@ namespace Slic3r { class MachineObject; +struct DevFilamentDryingPreset; /** * DevAmsTray - Represents a single filament tray/slot in an AMS unit or virtual tray. @@ -103,6 +110,8 @@ public: // static static wxColour decode_color(const std::string& color); + + std::optional get_ams_drying_preset() const; }; /** @@ -130,13 +139,67 @@ class DevAms { friend class DevFilaSystemParser; public: - enum AmsType : int + using AmsType = DevAmsType; + static constexpr AmsType EXT_SPOOL = DevAmsType::EXT_SPOOL; + static constexpr AmsType AMS = DevAmsType::AMS; + static constexpr AmsType AMS_LITE = DevAmsType::AMS_LITE; + static constexpr AmsType N3F = DevAmsType::N3F; + static constexpr AmsType N3S = DevAmsType::N3S; + static constexpr AmsType AMS_LITE_MIXED = DevAmsType::AMS_LITE_MIXED; + +public: + + enum class DryCtrlMode : int { - DUMMY = 0, - AMS = 1, // AMS - AMS_LITE = 2, // AMS-Lite - N3F = 3, // N3F - N3S = 4, // N3S + Off = 0, + OnTime = 1, + OnHumidity = 2, + }; + + enum class DryStatus : char + { + Off = 0, + Checking = 1, + Drying = 2, + Cooling = 3, + Stopping = 4, + Error = 5, + CannotStopHeatOutofControl = 6, + PrdTesting = 7, + }; + + enum class DrySubStatus + { + Off = 0, + Heating = 1, + Dehumidify = 2, + }; + + enum class DryFanStatus : char + { + Off = 0, + On = 1, + }; + + enum class CannotDryReason : int + { + TaskOccupied = 0, + InsufficientPower = 1, + AmsBusy = 2, + ConsumableAtAmsOutlet = 3, + InitiatingAmsDrying = 4, + NotSupportedIn2dMode = 5, + DryingInProgress = 6, + Upgrading = 7, + InsufficientPowerNeedPluginPower = 8, + FilamentAtAmsOutletManualUnload = 10, + }; + + struct DrySettings + { + std::string dry_filament; + int dry_temp = -1; // -1 means invalid + int dry_hour = -1; // -1 means invalid, hours }; public: @@ -150,11 +213,16 @@ public: void SetAmsType(int type) { m_ams_type = (AmsType)type; } void SetAmsType(AmsType type) { m_ams_type = type; } - AmsType GetAmsType() const { return m_ams_type; } + // AMS-Lite-mixed (N9) is a variant of AMS-Lite: report AMS_LITE to generic callers so all + // existing AMS_LITE handling applies. Mixed-specific code uses IsAmsLiteMixed(). + AmsType GetAmsType() const { return m_ams_type == AMS_LITE_MIXED ? AMS_LITE : m_ams_type; } // exist or not bool IsExist() const { return m_exist; } + // AMS-Lite-mixed for N9 (A2L) + bool IsAmsLiteMixed() const { return m_ams_type == AMS_LITE_MIXED; } + // slots int GetSlotCount() const; DevAmsTray* GetTray(const std::string& tray_id) const; @@ -163,6 +231,20 @@ public: // installed on the extruder int GetExtruderId() const { return m_ext_id; } + // Extruders this AMS can currently feed. Without a Filament Track Switch installed this + // is the single {m_ext_id}; with the switch installed the device binds it to both extruders. + const std::set& GetBindedExtruderSet() const { return m_binded_extruder_set; } + + // The bound extruder when exactly one is bound, empty otherwise. Used to attribute an AMS + // to a single extruder on printers without the switch. + std::optional GetUniqueBindedExtruderId() const + { + return m_binded_extruder_set.size() == 1 ? std::optional(*m_binded_extruder_set.begin()) : std::nullopt; + } + + // Which switch input track (A/B) feeds this AMS, set only when a Filament Track Switch is installed. + std::optional GetSwitcherPos() const { return m_binded_switcher_pos; } + // temperature and humidity float GetCurrentTemperature() const { return m_current_temperature; } @@ -170,13 +252,30 @@ public: int GetHumidityLevel() const { return m_humidity_level; } int GetHumidityPercent() const { return m_humidity_percent; } - bool SupportDrying() const { return m_ams_type > AMS_LITE; } + bool SupportDrying() const { return m_ams_type == DevAmsType::N3F || m_ams_type == DevAmsType::N3S; } int GetLeftDryTime() const { return m_left_dry_time; } + // remote drying control + bool IsSupportRemoteDry(const MachineObject* obj) const; + std::optional GetDryStatus() const { return m_dry_status; }; + std::optional GetDrySubStatus() const { return m_dry_sub_status; } + std::optional GetFan1Status() const { return m_dry_fan1_status; } + std::optional GetFan2Status() const { return m_dry_fan2_status; } + std::optional> GetCannotDryReason() const { return m_dry_cannot_reasons; } + std::optional GetDrySettings() const { return m_dry_settings; }; + + bool AmsIsDrying(); + private: AmsType m_ams_type = AmsType::AMS; std::string m_ams_id; int m_ext_id;//extruder id + // Orca: keeps the legacy single m_ext_id for existing consumers and carries the + // switch-aware binding alongside it (BambuStudio stores only the set). Without a Filament + // Track Switch the set is {m_ext_id}; with one installed the device binds both extruders and + // records which input track (A/B) feeds this AMS. + std::set m_binded_extruder_set; + std::optional m_binded_switcher_pos; bool m_exist = false; // slots and trays @@ -187,6 +286,14 @@ private: int m_humidity_level = 5; // AmsType::AMS int m_humidity_percent = -1; // N3F N3S, the percentage, -1 means invalid. eg. 100 means 100% int m_left_dry_time = 0; + + // see is_support_remote_dry + std::optional m_dry_status; + std::optional m_dry_sub_status; + std::optional m_dry_fan1_status; + std::optional m_dry_fan2_status; + std::optional> m_dry_cannot_reasons; + std::optional m_dry_settings; }; /** @@ -241,9 +348,16 @@ public: DevAmsTray* GetAmsTray(const std::string& ams_id, const std::string& tray_id) const; void CollectAmsColors(std::vector& ams_colors) const; + // Map a linear tray index -> {ams_id, slot_id}. Includes the two virtual (external-spool) trays, + // N3S single-slot units, and the A2L/N9 AMS-Lite-mixed layout (trays 24-27). + std::map GetTrayIndexMap(); + // extruder int GetExtruderIdByAmsId(const std::string& ams_id) const; + // nozzle: untranslated flow-type string of the extruder bound to this ams (for blacklist matching) + std::string GetNozzleFlowStringByAmsId(const std::string& ams_id) const; + /* AMS settings*/ DevAmsSystemSetting& GetAmsSystemSetting() { return m_ams_system_setting; } std::optional IsDetectOnInsertEnabled() const { return m_ams_system_setting.IsDetectOnInsertEnabled(); }; @@ -253,10 +367,19 @@ public: std::weak_ptr GetAmsFirmwareSwitch() const { return m_ams_firmware_switch;} + // filament change steps + // The exact change-step sequence reported by the AMS (ams.cfs). Empty on current firmware, + // which leaves the legacy hardcoded/ams_status_sub step handling in effect. + const std::vector& GetFilamentChangeSteps() const { return m_filament_change_steps; } + public: // ctrls int CtrlAmsReset() const; - + + // crtl + int CtrlAmsStartDryingHour(int ams_id, std::string filament_type, int tag_temp, int tag_duration_hour, bool rotate_tray, int cooling_temp, bool close_power_conflict = false) const; + int CtrlAmsStopDrying(int ams_id) const; + public: static bool IsBBL_Filament(std::string tag_uid); @@ -266,6 +389,9 @@ private: /* ams properties */ int m_ams_cali_stat = 0; + // Change-step sequence reported by the AMS (ams.cfs); empty when firmware doesn't send it. + std::vector m_filament_change_steps; + std::map amsList;// key: ams[id], start with 0 DevAmsSystemSetting m_ams_system_setting{ this }; @@ -291,4 +417,18 @@ public: static void ParseV1_0(const json& print_json, MachineObject* obj, DevFilaSystem* system, bool key_field_only); }; +struct DevFilamentDryingPreset +{ + std::string filament_id; + + std::unordered_set ams_limitations; // only use ams types in the set + std::unordered_map filament_dev_ams_drying_time_on_idle; // hour + std::unordered_map filament_dev_ams_drying_temperature_on_idle; + std::unordered_map filament_dev_ams_drying_time_on_print; // hour + std::unordered_map filament_dev_ams_drying_temperature_on_print; + float filament_dev_drying_cooling_temperature = 0.0f; + float filament_dev_drying_softening_temperature = 0.0f; + float filament_dev_ams_drying_heat_distortion_temperature = 0.0f; +}; + }// namespace Slic3r \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevFilaSystemCtrl.cpp b/src/slic3r/GUI/DeviceCore/DevFilaSystemCtrl.cpp index f81d6a2835..acdc81dd8c 100644 --- a/src/slic3r/GUI/DeviceCore/DevFilaSystemCtrl.cpp +++ b/src/slic3r/GUI/DeviceCore/DevFilaSystemCtrl.cpp @@ -16,4 +16,44 @@ int DevFilaSystem::CtrlAmsReset() const return m_owner->publish_json(jj_command); } +int DevFilaSystem::CtrlAmsStartDryingHour(int ams_id, + std::string filament_type, + int tag_temp, + int tag_duration_hour, + bool rotate_tray, + int cooling_temp, + bool close_power_conflict) const +{ + json jj_command; + jj_command["print"]["command"] = "ams_filament_drying"; + jj_command["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + jj_command["print"]["ams_id"] = ams_id; + jj_command["print"]["mode"] = static_cast(DevAms::DryCtrlMode::OnTime); + jj_command["print"]["filament"] = filament_type; + jj_command["print"]["temp"] = tag_temp; + jj_command["print"]["duration"] = tag_duration_hour; + jj_command["print"]["humidity"] = 0; + jj_command["print"]["rotate_tray"] = rotate_tray; + jj_command["print"]["cooling_temp"] = cooling_temp; + jj_command["print"]["close_power_conflict"] = close_power_conflict; + return m_owner->publish_json(jj_command); +} + +int DevFilaSystem::CtrlAmsStopDrying(int ams_id) const +{ + json jj_command; + jj_command["print"]["command"] = "ams_filament_drying"; + jj_command["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + jj_command["print"]["ams_id"] = ams_id; + jj_command["print"]["mode"] = static_cast(DevAms::DryCtrlMode::Off); + jj_command["print"]["filament"] = ""; + jj_command["print"]["temp"] = 0; + jj_command["print"]["duration"] = 0; + jj_command["print"]["humidity"] = 0; + jj_command["print"]["rotate_tray"] = false; + jj_command["print"]["cooling_temp"] = 0; + jj_command["print"]["close_power_conflict"] = false; + return m_owner->publish_json(jj_command); +} + } \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevFirmware.h b/src/slic3r/GUI/DeviceCore/DevFirmware.h index 2f45da4f56..eff34db0ea 100644 --- a/src/slic3r/GUI/DeviceCore/DevFirmware.h +++ b/src/slic3r/GUI/DeviceCore/DevFirmware.h @@ -44,6 +44,8 @@ public: bool isLaszer() const { return product_name.Contains("Laser"); } bool isCuttingModule() const { return product_name.Contains("Cutting Module"); } bool isExtinguishSystem() const { return product_name.Contains("Extinguishing System"); } + bool isWTM() const { return name.find("wtm") != std::string::npos; } // nozzle (rack hotend) module firmware + bool isFilaTrackSwitch() const { return product_name.Contains("Filament Track"); } }; diff --git a/src/slic3r/GUI/DeviceCore/DevMapping.cpp b/src/slic3r/GUI/DeviceCore/DevMapping.cpp index af3539f372..5dc16f4250 100644 --- a/src/slic3r/GUI/DeviceCore/DevMapping.cpp +++ b/src/slic3r/GUI/DeviceCore/DevMapping.cpp @@ -95,6 +95,10 @@ namespace Slic3r { result.id = ams_id + slot_id; } + else if (type == DevAms::AMS_LITE_MIXED) + { + result.id = AMS_LITE_MIXED_TRAY_INDEX_OFFSET + slot_id; + } else { result.id = ams_id * 4 + slot_id; @@ -117,6 +121,11 @@ namespace Slic3r { std::string ams_id = ams->second->GetAmsId(); auto ams_type = ams->second->GetAmsType(); + // GetAmsType() maps mixed -> AMS_LITE; recover the mixed type so N9 trays index at 24+slot. + if (ams_type == DevAms::AMS_LITE && ams->second->IsAmsLiteMixed()) + { + ams_type = DevAms::AMS_LITE_MIXED; + } for (auto tray = ams->second->GetTrays().begin(); tray != ams->second->GetTrays().end(); tray++) { int ams_id = atoi(ams->first.c_str()); @@ -126,6 +135,10 @@ namespace Slic3r { tray_index = ams_id * 4 + tray_id; } + else if (ams_type == DevAms::AMS_LITE_MIXED) + { + tray_index = AMS_LITE_MIXED_TRAY_INDEX_OFFSET + tray_id; + } else if (ams_type == DevAms::N3S) { tray_index = ams_id + tray_id; @@ -186,7 +199,7 @@ namespace Slic3r } } FilamentInfo info; - _parse_tray_info(atoi(tray.id.c_str()), 0, DevAms::DUMMY, tray, info); + _parse_tray_info(atoi(tray.id.c_str()), 0, DevAms::EXT_SPOOL, tray, info); tray_filaments.emplace(std::make_pair(info.tray_id, info)); } } diff --git a/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp new file mode 100644 index 0000000000..405a7c4171 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.cpp @@ -0,0 +1,485 @@ +#include "DevMapping.h" +#include "DevMappingNozzle.h" + +#include "DevNozzleRack.h" +#include "DevNozzleSystem.h" + +#include "DevUtil.h" +#include "DevUtilBackend.h" + +#include "libslic3r/MultiNozzleUtils.hpp" +#include "libslic3r/Print.hpp" + +#include "slic3r/GUI/DeviceManager.hpp" +#include "slic3r/GUI/Plater.hpp" +#include "slic3r/GUI/BackgroundSlicingProcess.hpp" + +#include "slic3r/GUI/GUI_App.hpp" + +#include +#include + +#include +#include +#include +using namespace nlohmann; + +namespace Slic3r { + +void MachineObject::clear_auto_nozzle_mapping() +{ + if (m_nozzle_mapping_ptr) { + m_nozzle_mapping_ptr->Clear(); + } +} + +static std::string s_get_diameter_str(float diameter) +{ + return (boost::format("%.2f") % diameter).str(); +} + +static std::string s_get_diameter_str(const std::string& diameter) +{ + try { + float dia = boost::lexical_cast(diameter); + return s_get_diameter_str(dia); + } catch (...) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " failed to boost::lexical_cast: " << diameter; + return diameter; + } + + try { + float dia = std::stof(diameter); + return s_get_diameter_str(dia); + } catch (...) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " std::stof: " << diameter; + return diameter; + } +} + + +// get auto nozzle mapping through AP +// warnings: +// (1) the fila_id here is 1 based index +// (2) the AP wants the diameter string with 2 decimal places +int DevNozzleMappingCtrl::CtrlGetAutoNozzleMappingV0(Slic3r::GUI::Plater* plater, + const std::vector& ams_mapping, + int flow_cali_opt, int pa_value) +{ + Clear(); + + m_plater = plater; + if (!plater) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": plater is nullptr"; + return -1; + } + + GCodeProcessorResult* gcode_result = plater->background_process().get_current_gcode_result(); + if (!gcode_result) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": gcode_result is nullptr"; + return -1; + } + + const auto& result = gcode_result->nozzle_group_result; + if (!result) { + assert(false && "gcode_result->nozzle_group_result"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": gcode_result->nozzle_group_result is NULL"; + return -1; + } + + if (ams_mapping.empty()) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": the ams mapping is empty"; + return -1;// the ams mapping is empty + } + + json command_jj; + command_jj["print"]["command"] = "get_auto_nozzle_mapping"; + m_sequence_id = std::to_string(MachineObject::m_sequence_id++); + command_jj["print"]["sequence_id"] = m_sequence_id; + command_jj["print"]["calibration"] = flow_cali_opt; + command_jj["print"]["extrude_cali_manual_mode"] = pa_value; + + // filament seq + json filament_seq_jj; + int max_fila_id = 0; + std::unordered_set filaid_set; + for (int idx = 0; idx < gcode_result->filament_change_sequence.size(); idx++) { + int fila_id = gcode_result->filament_change_sequence[idx]; + if (filaid_set.count(fila_id) == 0) { + filaid_set.insert(fila_id); + filament_seq_jj[fila_id + 1] = idx; + max_fila_id = std::max(max_fila_id, fila_id + 1); + } + } + + for (int fila_id = 0; fila_id <= max_fila_id; fila_id++) { + if (filament_seq_jj[fila_id].is_null()) { + filament_seq_jj[fila_id] = -1;// fill the used fila_id with -1 + } + } + + command_jj["print"]["filament_seq"] = filament_seq_jj; + + // ams mapping + std::vector ams_mapping_vec(33, 0xFFFF);/* AP ask to fill them*/ + for (auto item : ams_mapping) { + try { + int ams_id = stoi(item.ams_id); + int slot_id = !item.slot_id.empty() ? stoi(item.slot_id) : 0; + ams_mapping_vec[item.id + 1] = (ams_id << 8) | slot_id;/*using ams_id << 8 | slot_id*/ + } catch (std::exception& e) { + assert(false && "invalid ams_id or slot_id"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " exception: " << e.what(); + ams_mapping_vec[item.id + 1] = item.tray_id; + } + } + command_jj["print"]["ams_mapping"] = ams_mapping_vec; + + // filament info + json filament_info_jj; + for (int fila_id = 0; fila_id < ams_mapping.size(); fila_id++) { + const auto& fila = ams_mapping[fila_id]; + const auto& nozzle_list = result->get_nozzles_for_filament(fila.id); + if (nozzle_list.empty()) { + assert(false && "nozzle_list should not be empty"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "nozzle_list should not be nullptr"; + continue; + } + + for (const auto& nozzle_info : nozzle_list) { + json fila_item_jj; + fila_item_jj["id"] = (fila.id + 1); + fila_item_jj["direction"] = (nozzle_info.extruder_id == LOGIC_L_EXTRUDER_ID ? 1 : 2); + fila_item_jj["group"] = nozzle_info.group_id; + fila_item_jj["nozzle_d"] = s_get_diameter_str(nozzle_info.diameter); + fila_item_jj["nozzle_v"] = (nozzle_info.volume_type == NozzleVolumeType::nvtHighFlow) ? "High Flow" : "Standard"; + fila_item_jj["cate"] = fila.filament_id; + fila_item_jj["color"] = fila.color; + filament_info_jj.push_back(fila_item_jj); + } + } + + command_jj["print"]["fila_info"] = filament_info_jj; + + // nozzle info + json nozzle_info_jj; + const auto& nozzle_system = m_obj->GetNozzleSystem(); + const auto& extruder_nozzles = nozzle_system->GetExtNozzles(); + for (const auto& nozzle : extruder_nozzles) { + if (nozzle.second.IsNormal()) { + json nozzle_item_jj; + nozzle_item_jj["pos"] = nozzle.second.GetNozzleId(); + if (nozzle_system->GetReplaceNozzleTar().has_value() && nozzle_item_jj["pos"] == MAIN_EXTRUDER_ID) { + nozzle_item_jj["pos"] = nozzle_system->GetReplaceNozzleTar().value();// special case of tar_id. see protocol definition + } + + nozzle_item_jj["nozzle_d"] = s_get_diameter_str(nozzle.second.GetNozzleDiameter()); + nozzle_item_jj["nozzle_v"] = DevNozzle::ToNozzleFlowString(nozzle.second.GetNozzleFlowType()); + nozzle_item_jj["wear"] = nozzle.second.GetNozzleWear(); + nozzle_item_jj["cate"] = nozzle.second.GetFilamentId(); + nozzle_item_jj["color"] = nozzle.second.GetFilamentColor(); + nozzle_info_jj.push_back(nozzle_item_jj); + } + } + + const auto& rack_nozzles = nozzle_system->GetNozzleRack()->GetRackNozzles(); + for (const auto& nozzle : rack_nozzles) { + if (nozzle.second.IsNormal()) { + json nozzle_item_jj; + nozzle_item_jj["pos"] = (nozzle.second.GetNozzleId() + 0x10); + if (nozzle_system->GetReplaceNozzleTar().has_value() && nozzle_item_jj["pos"] == MAIN_EXTRUDER_ID) { + nozzle_item_jj["pos"] = nozzle_system->GetReplaceNozzleTar().value();// special case of tar_id. see protocol definition + } + + nozzle_item_jj["nozzle_d"] = s_get_diameter_str(nozzle.second.GetNozzleDiameter()); + nozzle_item_jj["nozzle_v"] = DevNozzle::ToNozzleFlowString(nozzle.second.GetNozzleFlowType()); + nozzle_item_jj["wear"] = nozzle.second.GetNozzleWear(); + nozzle_item_jj["cate"] = nozzle.second.GetFilamentId(); + nozzle_item_jj["color"] = nozzle.second.GetFilamentColor(); + nozzle_info_jj.push_back(nozzle_item_jj); + } + } + + command_jj["print"]["nozzle_info"] = nozzle_info_jj; + m_req_version = NozzleMappingVersion::Version_V0; + return m_obj->publish_json(command_jj); +} + +int DevNozzleMappingCtrl::CtrlGetAutoNozzleMappingV1(Slic3r::GUI::Plater* plater) +{ + Clear(); + m_plater = plater; + if (!m_plater) { + return -1; + } + + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(m_plater); + if (!nozzle_group_res) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": gcode_result->nozzle_group_result is NULL"; + return -1; + } + + json command_jj; + command_jj["print"]["command"] = "get_auto_nozzle_mapping"; + m_sequence_id = std::to_string(MachineObject::m_sequence_id++); + command_jj["print"]["sequence_id"] = m_sequence_id; + + json nozzle_group_info_jj; + std::unordered_set used_logic_groups; + const auto& used_logic_nozzles = nozzle_group_res->get_used_nozzles_in_extruder(); + for (const auto& used_logic_nozzle : used_logic_nozzles) { + if (used_logic_groups.count(used_logic_nozzle.group_id) != 0) { + continue; + } + used_logic_groups.insert(used_logic_nozzle.group_id); + + json nozzle_info; + nozzle_info["id"] = used_logic_nozzle.group_id; + nozzle_info["ext"] = (used_logic_nozzle.extruder_id + 1); + + try { + nozzle_info["dia"] = std::stof(used_logic_nozzle.diameter); + } catch(const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": e=" << e.what(); + continue; + } + + if (used_logic_nozzle.volume_type == NozzleVolumeType::nvtHighFlow) { + nozzle_info["vol"] = "High Flow"; + } else if(used_logic_nozzle.volume_type == NozzleVolumeType::nvtStandard){ + nozzle_info["vol"] = "Standard"; + } else if(used_logic_nozzle.volume_type == NozzleVolumeType::nvtTPUHighFlow){ + nozzle_info["vol"] = "TPU Flow"; + } else { + assert(0); + continue; + } + + nozzle_group_info_jj.push_back(nozzle_info); + } + command_jj["print"]["group_info"] = nozzle_group_info_jj; + + + m_req_version = NozzleMappingVersion::Version_V1; + command_jj["print"]["version"] = (int)m_req_version; + return m_obj->publish_json(command_jj); +} + + +void DevNozzleMappingCtrl::ParseAutoNozzleMapping(const json& print_jj) +{ + if (print_jj.contains("command") && print_jj["command"].get() == "get_auto_nozzle_mapping") { + if (print_jj.contains("sequence_id") && print_jj["sequence_id"] == m_sequence_id) { + Clear(); + DevJsonValParser::ParseVal(print_jj, "result", m_result); + DevJsonValParser::ParseVal(print_jj, "reason", m_mqtt_reason); + DevJsonValParser::ParseVal(print_jj, "errno", m_errno); + DevJsonValParser::ParseVal(print_jj, "detail", m_detail_json); + DevJsonValParser::ParseVal(print_jj, "type", m_type); + DevJsonValParser::ParseVal(print_jj, "version", m_ack_version); + + if (print_jj.contains("mapping")) { + m_nozzle_mapping_json = print_jj["mapping"]; + const auto& mapping = print_jj["mapping"].get>(); + for (int fila_id = 0; fila_id < mapping.size(); ++fila_id) { + m_nozzle_mapping[fila_id] = mapping[fila_id]; + } + } + + m_flush_weight_base = GetFlushWeight(m_obj); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": get_auto_nozzle_mapping: " << m_result; + } + } +} + +void DevNozzleMappingCtrl::Clear() +{ + m_sequence_id.clear(); + m_result.clear(); + m_mqtt_reason.clear(); + m_type.clear(); + m_errno = 0; + m_detail_msg.clear(); + m_detail_json.clear(); + m_nozzle_mapping.clear(); + m_nozzle_mapping_json.clear(); + + m_flush_weight_base = -1; + m_flush_weight_current = -1; + m_ack_version = NozzleMappingVersion::Version_V0; +} + + +void DevNozzleMappingCtrl::SetManualNozzleMappingByFila(int fila_id, int nozzle_pos_id) +{ + if (nozzle_pos_id == MAIN_EXTRUDER_ID && m_obj->GetNozzleSystem()->GetReplaceNozzleTar().has_value()){ + nozzle_pos_id = m_obj->GetNozzleSystem()->GetReplaceNozzleTar().value();// special case of tar_id. see protocol definition + } + + if (m_nozzle_mapping[fila_id] != nozzle_pos_id) { + m_nozzle_mapping[fila_id] = nozzle_pos_id; + m_flush_weight_current = GetFlushWeight(m_obj); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": fila_id=" << fila_id << ", nozzle_pos_id=" << nozzle_pos_id; + } + + try { + auto mapping = m_nozzle_mapping_json.get>(); + if (mapping.at(fila_id) != nozzle_pos_id) { + mapping[fila_id] = nozzle_pos_id; + m_nozzle_mapping_json = mapping; + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": updated to " << m_nozzle_mapping_json.dump(); + } + } catch (std::exception& e) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": exception: " << e.what(); + }; +} + +static std::unordered_set sGetLogicExtruders(const std::vector& nozzle_infos) +{ + std::unordered_set extruder_ids; + for (const auto& nozzle : nozzle_infos) { + if (nozzle.extruder_id >= 0) { + extruder_ids.insert(nozzle.extruder_id); + } + } + + return extruder_ids; +}; + + +std::vector DevNozzleMappingCtrl::GetMappedNozzlePosVecByFilaId(int fila_id) const +{ + std::vector physic_nozzle_pos_vec; + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(m_plater); + if (!nozzle_group_res) { + return physic_nozzle_pos_vec; + } + + const auto& used_logic_nozzles = nozzle_group_res->get_nozzles_for_filament(fila_id); + if (m_ack_version == NozzleMappingVersion::Version_V0) { + if (auto iter = m_nozzle_mapping.find(fila_id); iter != m_nozzle_mapping.end()) { + if (m_obj->GetNozzleSystem()->GetReplaceNozzleTar().has_value() && + iter->second == m_obj->GetNozzleSystem()->GetReplaceNozzleTar().value()) { + physic_nozzle_pos_vec.push_back(MAIN_EXTRUDER_ID); + } else { + physic_nozzle_pos_vec.push_back(iter->second); + } + } else { + const auto& used_logic_extruders = sGetLogicExtruders(used_logic_nozzles); + if (used_logic_extruders.size() == 1 && *used_logic_extruders.begin() == LOGIC_L_EXTRUDER_ID) { + physic_nozzle_pos_vec.push_back(1); + return physic_nozzle_pos_vec; // only left extruder is used + } + } + } else if (m_ack_version == NozzleMappingVersion::Version_V1) { + for (const auto& used_logic_nozzle : used_logic_nozzles) { + if (auto iter = m_nozzle_mapping.find(used_logic_nozzle.group_id); iter != m_nozzle_mapping.end()) { + if (m_obj->GetNozzleSystem()->GetReplaceNozzleTar().has_value() && + iter->second == m_obj->GetNozzleSystem()->GetReplaceNozzleTar().value()) { + physic_nozzle_pos_vec.push_back(MAIN_EXTRUDER_ID); + } else { + physic_nozzle_pos_vec.push_back(iter->second); + } + } + } + } + + return physic_nozzle_pos_vec; +} + +wxString DevNozzleMappingCtrl::GetMappedNozzlePosStrByFilaId(int fila_id, const wxString& default_str) const +{ + wxString display_str; + const auto& physic_nozzle_pos_vec = GetMappedNozzlePosVecByFilaId(fila_id); + for (int idx = 0; idx < physic_nozzle_pos_vec.size(); idx++) { + int pos_id = physic_nozzle_pos_vec[idx]; + if (pos_id == MAIN_EXTRUDER_ID) { + display_str += "R"; + } else if (pos_id == DEPUTY_EXTRUDER_ID) { + display_str += "L"; + } else if (pos_id >= 0x10) { + display_str += wxString::Format("R%d", pos_id - 0x10 + 1);// display 1~n for rack hotends + } else { + continue; + } + + if (idx < physic_nozzle_pos_vec.size() - 1) { + display_str += " "; + } + } + + return !display_str.empty() ? display_str : default_str; +} + +// flush weight for multi-nozzle printers: total flush volume across all filament changes +float DevNozzleMappingCtrl::GetFlushWeight(Slic3r::MachineObject* obj) const +{ + auto plater = Slic3r::GUI::wxGetApp().plater(); + if (!plater) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": plater is nullptr"; + return -1; + } + + GCodeProcessorResult* gcode_result = plater->background_process().get_current_gcode_result(); + if (!gcode_result) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": gcode_result is nullptr"; + return -1; + } + + if (gcode_result->filament_change_sequence.empty()) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": filament_change_sequence is empty"; + return -1; + } + + if (!Slic3r::GUI::wxGetApp().preset_bundle) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": preset_bundle is nullptr"; + return -1; + }; + + const std::vector>>& flush_matrix = Slic3r::GUI::wxGetApp().preset_bundle->get_full_flush_matrix(); + + float total_flush_volume = 0; + MultiNozzleUtils::NozzleStatusRecorder recorder; + for (auto filament : gcode_result->filament_change_sequence) { + const auto& nozzle_pos_vec = GetMappedNozzlePosVecByFilaId(filament); + if (nozzle_pos_vec.empty()) { + continue; + } + + auto nozzle_pos = nozzle_pos_vec.at(0); + if (nozzle_pos == -1){ + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": nozzle_pos is -1 for fila_id=" << filament; + continue; + } + + auto nozzle_info = obj->GetNozzleSystem()->GetNozzleByPosId(nozzle_pos); + if (nozzle_info.IsEmpty()) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": nozzle_info IsEmpty for fila_id=" << filament << ", nozzle_pos=" << nozzle_pos; + continue; + } + + int extruder_id = nozzle_info.GetLogicExtruderId(); + int nozzle_id = nozzle_info.GetNozzlePosId(); + int last_filament = recorder.get_filament_in_nozzle(nozzle_id); + + if (last_filament != -1 && last_filament != filament) { + if (flush_matrix.size() > extruder_id && + flush_matrix[extruder_id].size() > last_filament && + flush_matrix[extruder_id][last_filament].size() > filament){ + total_flush_volume += flush_matrix[extruder_id][last_filament][filament]; + } + else{ + assert(false && "missing flush volume"); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": missing flush volume for extruder_id=" << extruder_id + << ", last_filament=" << last_filament << ", filament=" << filament; + } + } + + recorder.set_nozzle_status(nozzle_id, filament); + } + + // estimate the flush weight: total_flush_volume * 1.26 * 0.001 + return total_flush_volume * 1.26 * 0.001; +} + +} // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceCore/DevMappingNozzle.h b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.h new file mode 100644 index 0000000000..9ca306eec9 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevMappingNozzle.h @@ -0,0 +1,108 @@ +/** +* @file DevMappingNozzle.h +* @brief Support nozzle mapping for hotend rack +*/ + +#pragma once +#include +#include +#include + +#include + +namespace Slic3r +{ + +namespace GUI +{ +class Plater; +} + +struct FilamentInfo; // libslic3r/ProjectTask.hpp + +class MachineObject; +class DevNozzleMappingCtrl +{ + friend class MachineObject; +public: + enum class NozzleMappingVersion : int { + Version_V0 = 0, // V0 means support logical fila_id -> physical nozzle_id mapping + Version_V1 = 1, // V1 means support logical nozzle_id -> physical nozzle_id mapping + }; + + enum class ErrNoV1 : int { + Success = 0, + ErrorBadRequest3mf = 1, + ErrorBadRequestVersion = 2, + ErrorBadRequestGroupId = 3, + ErrorNoValidNozzles = 4, + ErrorBadRequestReadFail = 5, + ErrorRackCaliFail = 6, + ErrorRackMoving = 7, + ErrorRackFull = 8, + WarningNotEnoughNozzles = 9 + }; + +public: + DevNozzleMappingCtrl(MachineObject* obj) : m_obj(obj) {}; + +public: + void SetPlater(Slic3r::GUI::Plater* plater) { m_plater = plater; } + void Clear(); + + bool HasResult() const { return !m_result.empty(); } + std::string GetResultStr() const { return m_result; } + + // mqtt error info + std::string GetMqttReason() const { return m_mqtt_reason; } + + // command error info + int GetErrno() const { return m_errno; } + ErrNoV1 GetErrnoV1() const { return static_cast(m_errno); } + std::string GetDetailMsg() const { return m_detail_msg; } + + // nozzle mapping + std::unordered_map GetNozzleMappingMap() const { return m_nozzle_mapping; } + nlohmann::json GetNozzleMappingJson() const { return m_nozzle_mapping_json; } + void SetManualNozzleMappingByFila(int fila_id, int nozzle_pos_id); + + std::vector GetMappedNozzlePosVecByFilaId(int fila_id) const;// return empy if not mapped + wxString GetMappedNozzlePosStrByFilaId(int fila_id, const wxString& default_str = "?") const; + + // flush weight + float GetFlushWeightBase() const { return m_flush_weight_base; } + float GetFlushWeightCurrent() const { return m_flush_weight_current; } + +public: + void ParseAutoNozzleMapping(const nlohmann::json& print_jj); + int CtrlGetAutoNozzleMappingV0(Slic3r::GUI::Plater* plater, const std::vector& ams_mapping, int flow_cali_opt, int pa_value); + int CtrlGetAutoNozzleMappingV1(Slic3r::GUI::Plater* plater); + +private: + float GetFlushWeight(Slic3r::MachineObject* obj) const; + +private: + MachineObject* m_obj; + Slic3r::GUI::Plater* m_plater = nullptr; + + std::string m_sequence_id; + + std::string m_result; + std::string m_mqtt_reason; + std::string m_type; // auto or manual + + int m_errno; + std::string m_detail_msg; + nlohmann::json m_detail_json; + + nlohmann::json m_nozzle_mapping_json; + std::unordered_map m_nozzle_mapping; // v0: fila_id -> physical_nozzle_id, v1: logical_nozzle_id -> physical_nozzle_id + + float m_flush_weight_base = -1;// the base weight for flush + float m_flush_weight_current = -1;// the weight current + + NozzleMappingVersion m_req_version = NozzleMappingVersion::Version_V0; + NozzleMappingVersion m_ack_version = NozzleMappingVersion::Version_V0; +}; + +} diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp b/src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp new file mode 100644 index 0000000000..de372f1ea9 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevNozzleRack.cpp @@ -0,0 +1,112 @@ +#include "DevNozzleRack.h" +#include "DevUtil.h" + +#include "slic3r/GUI/DeviceManager.hpp" + +wxDEFINE_EVENT(DEV_RACK_EVENT_READING_FINISHED, wxCommandEvent); +namespace Slic3r +{ + +DevNozzleRack::DevNozzleRack(DevNozzleSystem* nozzle_system) + : wxEvtHandler(), m_nozzle_system(nozzle_system) +{ + +} + + +void DevNozzleRack::Reset() +{ + m_position = RACK_POS_UNKNOWN; + m_status = RACK_STATUS_UNKNOWN; + m_rack_nozzles.clear(); +} + +void DevNozzleRack::SendReadingFinished() +{ + wxCommandEvent evt(DEV_RACK_EVENT_READING_FINISHED); + evt.SetEventObject(this); + wxPostEvent(this, evt); +} + +DevNozzle DevNozzleRack::GetNozzle(int idx) const +{ + auto iter = m_rack_nozzles.find(idx); + if (iter == m_rack_nozzles.end()) { + DevNozzle nozzle; + nozzle.SetOnRack(true); + return nozzle; + } + + return iter->second; +} + +DevFirmwareVersionInfo DevNozzleRack::GetNozzleFirmwareInfo(int nozzle_id) const +{ + auto iter = m_rack_nozzles_firmware.find(nozzle_id); + return iter != m_rack_nozzles_firmware.end() ? iter->second : DevFirmwareVersionInfo(); +} + + +bool DevNozzleRack::HasUnreliableNozzles() const +{ + for (const auto& nozzle : m_rack_nozzles) + { + if (!nozzle.second.IsInfoReliable()) + { + return true; + } + } + return false; +} + +bool DevNozzleRack::HasUnknownNozzles() const +{ + for (const auto& nozzle : m_rack_nozzles) + { + if (nozzle.second.IsUnknown()) + { + return true; + } + } + return false; +} + +int DevNozzleRack::GetKnownNozzleCount() const +{ + int count = 0; + for (const auto& nozzle : m_rack_nozzles) + { + if (!nozzle.second.IsEmpty() && !nozzle.second.IsUnknown()) + { + count++; + } + } + + return count; +} + +void DevNozzleRack::ParseRackInfo(const nlohmann::json& rack_info) +{ + ParseRackInfoV1_0(rack_info); +} + +void DevNozzleRack::ParseRackInfoV1_0(const nlohmann::json& rack_info) +{ + DevJsonValParser::ParseVal(rack_info, "stat", m_status, RACK_STATUS_UNKNOWN); + if (m_status < RACK_STATUS_UNKNOWN || m_status >= RACK_STATUS_END) + { + m_status = RACK_STATUS_UNKNOWN; // Reset to default if out of range + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Invalid rack status: " << m_status << ", reset"; + } + + DevJsonValParser::ParseVal(rack_info, "pos", m_position, RACK_POS_UNKNOWN); + if (m_position < RACK_POS_UNKNOWN || m_position >= RACK_POS_END) + { + m_position = RACK_POS_UNKNOWN; // Reset to default if out of range + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Invalid rack position: " << m_position << ", reset"; + } + + DevJsonValParser::ParseVal(rack_info, "info", m_cali_status); +} + +}; \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleRack.h b/src/slic3r/GUI/DeviceCore/DevNozzleRack.h new file mode 100644 index 0000000000..34b201c072 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevNozzleRack.h @@ -0,0 +1,134 @@ +#pragma once +#include "libslic3r/CommonDefs.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" +#include "slic3r/Utils/json_diff.hpp" + +#include "DevNozzleSystem.h" +#include "DevFirmware.h" + +#include + +// wx +#include +#include + +wxDECLARE_EVENT(DEV_RACK_EVENT_READING_FINISHED, wxCommandEvent); + +namespace Slic3r +{ + // Previous definitions +class DevNozzleSystem; + +class DevNozzleRack: public wxEvtHandler +{ +public: + enum RackStatus : int + { + RACK_STATUS_UNKNOWN = -1, + RACK_STATUS_IDLE = 0, + RACK_STATUS_HOTEND_CENTRE = 1, + RACK_STATUS_TOOLHEAD_CENTRE = 2, + RACK_STATUS_CALIBRATE_HOTEND_RACK = 3, + RACK_STATUS_CUT_MATERIAL = 4, + RACK_STATUS_UNLOCK_HOTEND = 5, + RACK_STATUS_LIFT_HOTEND_RACK = 6, + RACK_STATUS_PLACE_HOTEND = 7, + RACK_STATUS_PICK_HOTEND = 8, + RACK_STATUS_LOCK_HOTEND = 9, + RACK_STATUS_END, + }; + + enum RackPos : int + { + RACK_POS_UNKNOWN = 0, + RACK_POS_A_TOP = 1, + RACK_POS_B_TOP = 2, + RACK_POS_CENTRE = 3, + RACK_POS_END, + }; + + enum RackCaliStatus + { + Rack_CALI_UNKNOWN = -1, + Rack_CALI_NOT = 0, + Rack_CALI_OK = 1, + }; + +public: + DevNozzleRack(DevNozzleSystem* nozzle_system); + ~DevNozzleRack() = default; + +public: + // Is supported by the printer + bool IsSupported() const { return m_is_supported; }; + void SetSupported(bool supported) { m_is_supported = supported; } + + // getters + DevNozzleSystem* GetNozzleSystem() const { return m_nozzle_system; } + + RackPos GetPosition() const { return m_position; } + RackStatus GetStatus() const { return m_status; } + RackCaliStatus GetCaliStatus() const { return m_cali_status;} + + DevNozzle GetNozzle(int idx) const; + const std::map& GetRackNozzles() const { return m_rack_nozzles; } + + // status + bool HasUnreliableNozzles() const; + bool HasUnknownNozzles() const; + int GetKnownNozzleCount() const; + + // refreshing + int GetReadingIdx() const { return m_nozzle_system->GetReadingIdx(); } + int GetReadingCount() const { return m_nozzle_system->GetReadingCount(); } + void SendReadingFinished(); + + // firmware + void AddNozzleFirmwareInfo(int nozzle_id, const DevFirmwareVersionInfo& info) { m_rack_nozzles_firmware[nozzle_id] = info; } + void ClearNozzleFirmwareInfo() { m_rack_nozzles_firmware.clear(); } + DevFirmwareVersionInfo GetNozzleFirmwareInfo(int nozzle_id) const; + + // setters + void Reset(); + void AddRackNozzle(DevNozzle& nozzle) { nozzle.SetOnRack(true); m_rack_nozzles[nozzle.m_nozzle_id] = nozzle; }; + void ClearRackNozzles() { m_rack_nozzles.clear(); } + +public: + void ParseRackInfo(const nlohmann::json& rack_info); + + void CtrlRackPosMove(RackPos new_pos) const; + void CtrlRackPosGoHome() const; + + void CtrlRackConfirmNozzle(int rack_nozzle_id) const; + void CtrlRackConfirmAll() const; + + void CrtlRackReadNozzle(int rack_nozzle_id) const; + void CtrlRackReadAll(bool gui_check = false) const; + bool CtrlCanReadAll() const; + + // the upgrade is not supported + // the GUI interface is removed + int CtrlRackUpgradeExtruderNozzle() const; + int CtrlRackUpgradeRackNozzle(int rack_nozzle_id) const;; + int CtrlRackUpgradeAll() const;; + bool CtrlCanUpdateAll() const; + +private: + void ParseRackInfoV1_0(const nlohmann::json& rack_info); + + int CtrlRackUpgrade(const std::string& module_str) const; + + bool CheckRackMoveWarningDlg() const; + +private: + DevNozzleSystem* m_nozzle_system = nullptr; + + bool m_is_supported = false; // Indicates if the nozzle rack is supported by the printer + RackPos m_position = RACK_POS_UNKNOWN; + RackStatus m_status = RACK_STATUS_UNKNOWN; + RackCaliStatus m_cali_status = Rack_CALI_UNKNOWN; + + std::map m_rack_nozzles; // Map of nozzle ID to DevNozzle objects + std::map m_rack_nozzles_firmware; +}; +}; \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp b/src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp new file mode 100644 index 0000000000..cb0272dfe8 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevNozzleRackCtrl.cpp @@ -0,0 +1,283 @@ +#include "DevNozzleRack.h" +#include "DevUtil.h" +#include "DevExtruderSystem.h" + +#include "slic3r/GUI/DeviceManager.hpp" +#include "slic3r/GUI/MsgDialog.hpp" +#include "slic3r/GUI/I18N.hpp" + +#include + + +namespace Slic3r +{ + +void DevNozzleRack::CtrlRackPosMove(RackPos new_pos) const +{ + if (!CheckRackMoveWarningDlg()) + { + return; + } + + int action_id = -1; + if (new_pos == RACK_POS_A_TOP) + { + action_id = 1; + } + else if(new_pos == RACK_POS_B_TOP) + { + action_id = 2; + } + + if (action_id != -1) + { + json j; + j["print"]["command"] = "nozzle_holder_ctrl"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["action"] = action_id; + m_nozzle_system->GetOwner()->publish_json(j); + } +} + + +void DevNozzleRack::CtrlRackPosGoHome() const +{ + if (!CheckRackMoveWarningDlg()) + { + return; + } + + json j; + j["print"]["command"] = "nozzle_holder_ctrl"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["action"] = 0; + m_nozzle_system->GetOwner()->publish_json(j); +} + +bool DevNozzleRack::CheckRackMoveWarningDlg() const +{ + if (wxThread::IsMain()) + { + static bool s_show_move_warning = true; + if (s_show_move_warning) + { + Slic3r::GUI::MessageDialog dlg(nullptr, _L("The toolhead and hotend rack may move. Please keep your hands away from the chamber."), + _L("Warning"), wxICON_WARNING | wxOK); + dlg.show_dsa_button(); + if (dlg.ShowModal() != wxID_OK) + { + s_show_move_warning = !dlg.get_checkbox_state(); + return false; + } + + s_show_move_warning = !dlg.get_checkbox_state(); + } + } + + return true; +} + +void DevNozzleRack::CtrlRackConfirmNozzle(int rack_nozzle_id) const +{ + json j; + j["print"]["command"] = "nozzle_info_confirm"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["id"] = (rack_nozzle_id + 16); // from 0x16 + m_nozzle_system->GetOwner()->publish_json(j); +} + +void DevNozzleRack::CtrlRackConfirmAll() const +{ + json j; + j["print"]["command"] = "nozzle_info_confirm"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["id"] = 0xff; + m_nozzle_system->GetOwner()->publish_json(j); +} + +void DevNozzleRack::CrtlRackReadNozzle(int rack_nozzle_id) const +{ + json j; + j["print"]["command"] = "holder_nozzle_refresh"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["id"] = (rack_nozzle_id + 16); // from 0x16 + m_nozzle_system->GetOwner()->publish_json(j); +} + + +bool DevNozzleRack::CtrlCanReadAll() const +{ + //is in print + if (m_nozzle_system->GetOwner()->is_in_printing()) + { + return false; + } + + if (m_nozzle_system->GetOwner()->is_in_upgrading()) { + return false; + } + + //if have nozzle + bool has_nozzle_on_rack = false; + for (const auto &nozzle_pair : m_rack_nozzles) + { + if (!nozzle_pair.second.IsEmpty()) + { + has_nozzle_on_rack = true; + break; + } + } + + bool has_nozzle_on_ext = false; + if (m_nozzle_system->ContainsExtNozzle(MAIN_EXTRUDER_ID)) { + has_nozzle_on_ext = true; + } + + if (!has_nozzle_on_rack && !has_nozzle_on_ext) { + return false; + } + + //if is in loading + if (m_nozzle_system->GetOwner()->ams_status_main == AMS_STATUS_MAIN_FILAMENT_CHANGE) + { + return false; + } + + auto ext = m_nozzle_system->GetOwner()->GetExtderSystem(); + if (ext && ext->IsBusyLoading()) return false; + + if (GetReadingCount() > 0) + { + return false; + } + + return m_status == RACK_STATUS_IDLE; +} + +void DevNozzleRack::CtrlRackReadAll(bool gui_check) const +{ + if (gui_check && wxThread::IsMain()) + { +#if 0 + if (!HasUnknownNozzles()) { + Slic3r::GUI::MessageDialog dlg(nullptr, _L("Hotend information may be inaccurate. " + "Would you like to re-read the hotend? (Hotend information may change during power-off)."), + _L("Warning"), wxICON_WARNING | wxOK | wxYES); + dlg.SetButtonLabel(wxID_OK, _L("I confirm all")); + dlg.SetButtonLabel(wxID_YES, _L("Re-read all")); + + int rtn = dlg.ShowModal(); + if (rtn == wxID_OK) { + CtrlRackConfirmAll(); + } else if (rtn == wxID_YES) { + if (CheckRackMoveWarningDlg()) { + CtrlRackReadAll(false); + } + } + + return; + } +#endif + + if (CheckRackMoveWarningDlg()) { + CtrlRackReadAll(false); + } + + return; + } + + json j; + j["print"]["command"] = "holder_nozzle_refresh"; + j["print"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + j["print"]["id"] = 0xff; + m_nozzle_system->GetOwner()->publish_json(j); +} + + +bool DevNozzleRack::CtrlCanUpdateAll() const +{ + if (m_nozzle_system->GetOwner()->is_in_printing()) + { + return false; + } + + auto ext_nozzle = m_nozzle_system->GetExtNozzle(MAIN_EXTRUDER_ID); + if (ext_nozzle.IsAbnormal()) + { + return true; + } + + auto ext_nozzle_firmware = m_nozzle_system->GetExtruderNozzleFirmware(); + if (!ext_nozzle_firmware.sw_new_ver.empty() && + ext_nozzle_firmware.sw_new_ver != ext_nozzle_firmware.sw_ver) + { + return true; + } + + for (auto val : m_rack_nozzles_firmware) + { + const auto& firmware_info = val.second; + if (!firmware_info.sw_new_ver.empty() && firmware_info.sw_new_ver != firmware_info.sw_ver) + { + return true; + } + else if (GetNozzle(val.first).IsAbnormal()) + { + return true; + } + } + + return false; +} + +int DevNozzleRack::CtrlRackUpgradeExtruderNozzle() const +{ + return CtrlRackUpgrade("wtm"); +} + +int DevNozzleRack::CtrlRackUpgradeRackNozzle(int rack_nozzle_id) const +{ + return CtrlRackUpgrade("wtm/" + std::to_string(0x10 + rack_nozzle_id)); +} + +int DevNozzleRack::CtrlRackUpgradeAll() const +{ + return CtrlRackUpgrade("wtm_all"); +} + +int DevNozzleRack::CtrlRackUpgrade(const std::string& module_str) const +{ + if (wxThread::IsMain()) + { + if (GetReadingCount() > 0) + { + Slic3r::GUI::MessageDialog dlg(nullptr, _L("Reading the hotends, please wait."), _L("Warning"), wxICON_WARNING | wxOK); + dlg.ShowModal(); + return -1; + } + + static bool s_show_upgrade_warning = true; + if (s_show_upgrade_warning) + { + Slic3r::GUI::MessageDialog dlg(nullptr, _L("During the hotend upgrade, the toolhead will move. Don't reach into the chamber."), + _L("Warning"), wxICON_WARNING | wxOK | wxCANCEL); + dlg.show_dsa_button(); + dlg.SetButtonLabel(wxID_OK, _L("Update")); + int rtn = dlg.ShowModal(); + s_show_upgrade_warning = !dlg.get_checkbox_state(); + if (rtn != wxID_OK) + { + return -1; + } + } + } + + json j; + j["upgrade"]["command"] = "wtm_upgrade"; + j["upgrade"]["module"] = module_str; + j["upgrade"]["src_id"] = 1; + j["upgrade"]["sequence_id"] = std::to_string(MachineObject::m_sequence_id++); + return m_nozzle_system->GetOwner()->publish_json(j); +} + +}; \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp index d6c35d06b1..578149b9d3 100644 --- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp +++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.cpp @@ -1,35 +1,413 @@ #include "DevExtruderSystem.h" + +#include "DevNozzleRack.h" #include "DevNozzleSystem.h" #include "DevUtil.h" #include "slic3r/GUI/DeviceManager.hpp" +#include "slic3r/GUI/I18N.hpp" + +#include "libslic3r/libslic3r.h" +#include "libslic3r/Utils.hpp" namespace Slic3r { -DevNozzle DevNozzleSystem::GetNozzle(int id) const +// ---- DevNozzle: flow/volume conversions (Standard / High Flow / TPU High Flow) ---------------------- +// Device-reported U_FLOW nozzles map to nvtTPUHighFlow so a synced TPU-HF rack activates the H2C +// change_filament_gcode TPU-kit branch. nvtHybrid is a slicer-only sentinel with no device +// representation, so ToNozzleFlowType(nvtHybrid) falls through to NONE_FLOWTYPE. + +NozzleFlowType DevNozzle::ToNozzleFlowType(const NozzleVolumeType& type) { - if (m_nozzles.find(id) != m_nozzles.end()) + switch (type) { + case NozzleVolumeType::nvtStandard: return NozzleFlowType::S_FLOW; + case NozzleVolumeType::nvtHighFlow: return NozzleFlowType::H_FLOW; + case NozzleVolumeType::nvtTPUHighFlow: return NozzleFlowType::U_FLOW; + default: return NozzleFlowType::NONE_FLOWTYPE; + } +} + +NozzleVolumeType DevNozzle::ToNozzleVolumeType(const NozzleFlowType& type) +{ + switch (type) { + case NozzleFlowType::S_FLOW: return NozzleVolumeType::nvtStandard; + case NozzleFlowType::H_FLOW: return NozzleVolumeType::nvtHighFlow; + case NozzleFlowType::U_FLOW: return NozzleVolumeType::nvtTPUHighFlow; + default: { + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << "nozzle flow type None convert to nozzle volume type Standard"; + return NozzleVolumeType::nvtStandard; + } + } +} + +wxString DevNozzle::GetNozzleFlowTypeStr(NozzleFlowType type) +{ + switch (type) { + case NozzleFlowType::H_FLOW: return _L("High Flow"); + case NozzleFlowType::S_FLOW: return _L("Standard"); + case NozzleFlowType::U_FLOW: return _L("TPU High Flow"); + default: break; + } + + return _L("Unknown"); +} + +// Untranslated flow-type literal used for filaments_blacklist.json nozzle_flows matching. +// Keep the raw English strings; the translated GetNozzleFlowTypeStr must not be used for JSON matching. +std::string DevNozzle::GetNozzleFlowTypeString(NozzleFlowType type) +{ + switch (type) { + case NozzleFlowType::H_FLOW: return "High Flow"; + case NozzleFlowType::S_FLOW: return "Standard"; + case NozzleFlowType::U_FLOW: return "TPU High Flow"; + default: return "Unknown"; + } +} + +// Untranslated flow-type literal serialized into the get_auto_nozzle_mapping payload. +// Differs from GetNozzleFlowTypeString only in the fallback: "" (empty) rather than "Unknown". +std::string DevNozzle::ToNozzleFlowString(const NozzleFlowType& type) +{ + switch (type) { + case NozzleFlowType::S_FLOW: return "Standard"; + case NozzleFlowType::H_FLOW: return "High Flow"; + case NozzleFlowType::U_FLOW: return "TPU High Flow"; + default: return std::string(); + } +} + +wxString DevNozzle::GetNozzleTypeStr(NozzleType type) +{ + switch (type) { + case Slic3r::ntHardenedSteel: return _L("Hardened Steel"); + case Slic3r::ntStainlessSteel: return _L("Stainless Steel"); + case Slic3r::ntTungstenCarbide: return _L("Tungsten Carbide"); + default: break; + } + + return _L("Unknown"); +} + +// ---- DevNozzle: status ------------------------------------------------------------------------------ + +bool DevNozzle::IsInfoReliable() const +{ + if (IsEmpty()) { return false; } + return DevUtil::get_flag_bits(m_stat, 0, 1) == 0; +} + +bool DevNozzle::IsNormal() const +{ + if (IsEmpty()) { return false; } + return DevUtil::get_flag_bits(m_stat, 1, 2) == 0; +} + +bool DevNozzle::IsAbnormal() const +{ + return DevUtil::get_flag_bits(m_stat, 1, 2) == (1 << 0); +} + +bool DevNozzle::IsUnknown() const +{ + return DevUtil::get_flag_bits(m_stat, 1, 2) == (1 << 1); +} + +int DevNozzle::GetNozzlePosId() const +{ + return IsOnRack() ? (m_nozzle_id + 0x10) : m_nozzle_id; +} + +NozzleDiameterType DevNozzle::GetNozzleDiameterType() const +{ + if (is_approx(m_diameter, 0.2f)) + return NozzleDiameterType::NOZZLE_DIAMETER_0_2; + else if (is_approx(m_diameter, 0.4f)) + return NozzleDiameterType::NOZZLE_DIAMETER_0_4; + else if (is_approx(m_diameter, 0.6f)) + return NozzleDiameterType::NOZZLE_DIAMETER_0_6; + else if (is_approx(m_diameter, 0.8f)) + return NozzleDiameterType::NOZZLE_DIAMETER_0_8; + else + return NozzleDiameterType::NONE_DIAMETER_TYPE; +} + +DevFirmwareVersionInfo DevNozzle::GetFirmwareInfo() const +{ + const auto& nozzle_rack = m_nozzle_rack.lock(); + if (nozzle_rack) { + if (IsOnRack()) { + return nozzle_rack->GetNozzleFirmwareInfo(m_nozzle_id); + } else if (m_nozzle_id == 0) { + return nozzle_rack->GetNozzleSystem()->GetExtruderNozzleFirmware(); + } + } + + return DevFirmwareVersionInfo(); +} + +// ---- DevNozzle: location ---------------------------------------------------------------------------- + +int DevNozzle::GetLogicExtruderId() const +{ + int total_ext_count = GetTotalExtruderCount(); + if (total_ext_count == 1) { + return LOGIC_UNIQUE_EXTRUDER_ID; + } else if (total_ext_count == 2) { + if (AtLeftExtruder()) { + return LOGIC_L_EXTRUDER_ID; + } else if (AtRightExtruder()) { + return LOGIC_R_EXTRUDER_ID; + } + } + + assert(0); + return LOGIC_UNIQUE_EXTRUDER_ID; +} + +int DevNozzle::GetExtruderId() const +{ + int total_ext_count = GetTotalExtruderCount(); + if (total_ext_count == 1) { + return MAIN_EXTRUDER_ID; + } else if (total_ext_count == 2) { + if (AtRightExtruder()) { + return MAIN_EXTRUDER_ID; + } else if (AtLeftExtruder()) { + return DEPUTY_EXTRUDER_ID; + } + } + + return MAIN_EXTRUDER_ID; +} + +bool DevNozzle::AtLeftExtruder() const +{ + assert(GetTotalExtruderCount() == 2); + if (IsOnRack()) { return false; } + return m_nozzle_id == DEPUTY_EXTRUDER_ID; +} + +bool DevNozzle::AtRightExtruder() const +{ + assert(GetTotalExtruderCount() == 2); + if (IsOnRack()) { return true; } + return m_nozzle_id == MAIN_EXTRUDER_ID; +} + +int DevNozzle::GetTotalExtruderCount() const +{ + auto rack = m_nozzle_rack.lock(); + if (rack) { + MachineObject* obj = rack->GetNozzleSystem()->GetOwner(); + return obj->GetExtderSystem()->GetTotalExtderCount(); + } + return 1; +} + +// ---- DevNozzleSystem -------------------------------------------------------------------------------- + +DevNozzleSystem::DevNozzleSystem(MachineObject* owner) + : m_owner(owner), m_nozzle_rack(std::make_shared(this)) +{ +} + +DevNozzle DevNozzleSystem::GetExtNozzle(int id) const +{ + if (m_ext_nozzles.find(id) != m_ext_nozzles.end()) { - return m_nozzles.at(id); + return m_ext_nozzles.at(id); } return DevNozzle(); } -void DevNozzleSystem::Reset() +DevNozzle DevNozzleSystem::GetRackNozzle(int idx) const { - m_nozzles.clear(); - m_extder_exist = 0; - m_state = 0; // idle state + return m_nozzle_rack->GetNozzle(idx); } +const std::map& DevNozzleSystem::GetRackNozzles() const +{ + return m_nozzle_rack->GetRackNozzles(); +} + +void DevNozzleSystem::SetSupportNozzleRack(bool supported) +{ + m_nozzle_rack->SetSupported(supported); +} + +const std::vector DevNozzleSystem::CollectNozzles(int ext_loc, NozzleFlowType flow_type, float diameter) const +{ + auto s_match = [&](const DevNozzle& nozzle) -> bool { + if (nozzle.IsEmpty() || nozzle.IsAbnormal()) { + return false; + } + + if (diameter >= 0.0f && nozzle.m_diameter != diameter) { + return false; + } + + if (m_owner->is_nozzle_flow_type_supported() && flow_type != nozzle.GetNozzleFlowType()) { + return false; + } + + return true; + }; + + std::vector result; + + auto ext_nozzle = GetExtNozzle(ext_loc); + if (s_match(ext_nozzle)) { + result.push_back(ext_nozzle); + } + + if (ext_loc == MAIN_EXTRUDER_ID) { + auto rack_nozzles = m_nozzle_rack->GetRackNozzles(); + for (auto rack_nozzle : rack_nozzles) { + if (s_match(rack_nozzle.second)) { + result.push_back(rack_nozzle.second); + } + } + } + + return result; +} + +std::vector DevNozzleSystem::GetNozzleGroups() const +{ + std::vector nozzle_groups; + + auto nozzle_in_extruder = this->GetExtNozzles(); + for (auto& elem : nozzle_in_extruder) { + auto& nozzle = elem.second; + MultiNozzleUtils::NozzleGroupInfo info; + info.extruder_id = nozzle.GetLogicExtruderId(); + info.diameter = format_diameter_to_str(nozzle.m_diameter); + info.volume_type = DevNozzle::ToNozzleVolumeType(nozzle.m_nozzle_flow); + info.nozzle_count = 1; + nozzle_groups.emplace_back(std::move(info)); + } + + auto nozzle_rack = this->GetNozzleRack(); + if (!nozzle_rack) + return nozzle_groups; + + auto nozzle_in_rack = nozzle_rack->GetRackNozzles(); // nozzles in rack + for (auto& elem : nozzle_in_rack) { + auto& nozzle = elem.second; + if (nozzle.IsUnknown() || nozzle.IsAbnormal()) + continue; + int extruder_id = nozzle.GetLogicExtruderId(); + std::string diameter = format_diameter_to_str(nozzle.m_diameter); + NozzleVolumeType volume_type = DevNozzle::ToNozzleVolumeType(nozzle.m_nozzle_flow); + + bool found = false; + for (auto& group : nozzle_groups) { + if (group.extruder_id == extruder_id && + group.volume_type == volume_type && + group.diameter == diameter) { + found = true; + group.nozzle_count += 1; + break; + } + } + if (!found) + nozzle_groups.emplace_back(diameter, volume_type, extruder_id, 1); + } + return nozzle_groups; +} + +bool DevNozzleSystem::IsRackMaximumInstalled() const +{ + auto ext_nozzle = GetExtNozzle(MAIN_EXTRUDER_ID); + if (ext_nozzle.IsEmpty()) { + return false; + } + + const auto& rack_nozzles = m_nozzle_rack->GetRackNozzles(); + if (rack_nozzles.size() < 6) { + return false; + } + + for (auto item : rack_nozzles) { + if (item.second.IsEmpty()) { + return false; + } + } + + return true; +} + +bool DevNozzleSystem::HasUnreliableNozzles() const +{ + for (auto nozzle : m_ext_nozzles) { + if (!nozzle.second.IsInfoReliable()) { + return true; + } + } + + if (m_nozzle_rack->HasUnreliableNozzles()) { + return true; + } + + return false; +} + +bool DevNozzleSystem::HasUnknownNozzles() const +{ + for (auto nozzle : m_ext_nozzles) { + if (nozzle.second.IsUnknown()) { + return true; + } + } + + if (m_nozzle_rack->HasUnknownNozzles()) { + return true; + } + + return false; +} + +void DevNozzleSystem::AddFirmwareInfoWTM(const DevFirmwareVersionInfo& info) +{ + static const std::string s_wtm_prefix = "wtm/"; + auto pos = info.name.find(s_wtm_prefix); + if (pos == std::string::npos) { + m_ext_nozzle_firmware_info = info; + } else { + try { + auto str = info.name.substr(s_wtm_prefix.size()); // remove "wtm/" prefix + int rack_nozzle_id = std::stoi(str) - 0x10; // rack nozzle IDs start from 0x10 + m_nozzle_rack->AddNozzleFirmwareInfo(rack_nozzle_id, info); + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": Invalid nozzle ID in firmware name: " + << info.name << ", error: " << e.what(); + } + } +} + +void DevNozzleSystem::ClearFirmwareInfoWTM() +{ + m_ext_nozzle_firmware_info = DevFirmwareVersionInfo(); + m_nozzle_rack->ClearNozzleFirmwareInfo(); +} + +void DevNozzleSystem::ClearNozzles() +{ + m_ext_nozzles.clear(); + m_nozzle_rack->ClearRackNozzles(); +} + +// ---- parsing ---------------------------------------------------------------------------------------- static unordered_map _str2_nozzle_flow_type = { {"S", NozzleFlowType::S_FLOW}, {"H", NozzleFlowType::H_FLOW}, {"A", NozzleFlowType::S_FLOW}, - {"X", NozzleFlowType::S_FLOW} + {"X", NozzleFlowType::S_FLOW}, + {"E", NozzleFlowType::H_FLOW}, // E3D high-flow + {"U", NozzleFlowType::U_FLOW}, // TPU 1.75 high-flow -> nvtTPUHighFlow }; static unordered_map _str2_nozzle_type = { @@ -57,6 +435,11 @@ static void s_parse_nozzle_type(const std::string& nozzle_type_str, DevNozzle& n nozzle.m_nozzle_type = _str2_nozzle_type[type_str]; } } + else if (nozzle_type_str == "N/A") + { + nozzle.m_nozzle_type = NozzleType::ntUndefine; + nozzle.m_nozzle_flow = NozzleFlowType::NONE_FLOWTYPE; + } } @@ -66,8 +449,9 @@ void DevNozzleSystemParser::ParseV1_0(const nlohmann::json& nozzletype_json, std::optional flag_e3d) { //Since both the old and new protocols push data. - // assert(system->m_nozzles.size() < 2); + // assert(system->m_ext_nozzles.size() < 2); DevNozzle nozzle; + nozzle.SetRack(system->GetNozzleRack()); nozzle.m_nozzle_id = 0; nozzle.m_nozzle_flow = NozzleFlowType::S_FLOW; // default flow type @@ -112,32 +496,88 @@ void DevNozzleSystemParser::ParseV1_0(const nlohmann::json& nozzletype_json, } } - system->m_nozzles[nozzle.m_nozzle_id] = nozzle; + system->m_ext_nozzles[nozzle.m_nozzle_id] = nozzle; } -void DevNozzleSystemParser::ParseV2_0(const json& nozzle_json, DevNozzleSystem* system) +void DevNozzleSystemParser::ParseV2_0(const json& device_json, DevNozzleSystem* system) { - system->Reset(); - - if (nozzle_json.contains("exist")) + if (device_json.contains("nozzle")) { - system->m_extder_exist = DevUtil::get_flag_bits(nozzle_json["exist"].get(), 0, 16); + const json& nozzle_json = device_json["nozzle"]; + if (nozzle_json.contains("exist")) + { + system->m_extder_exist = DevUtil::get_flag_bits(nozzle_json["exist"].get(), 0, 16); + } + + if (nozzle_json.contains("state")) + { + system->m_state_0_4 = DevUtil::get_flag_bits(nozzle_json["state"].get(), 0, 4); + int new_reading_idx = DevUtil::get_flag_bits(nozzle_json["state"].get(), 8, 4); + int new_reading_count = DevUtil::get_flag_bits(nozzle_json["state"].get(), 4, 4); + if (system->m_reading_count != new_reading_count || system->m_reading_idx != new_reading_idx) + { + system->m_reading_idx = new_reading_idx; + system->m_reading_count = new_reading_count; + if (system->m_reading_count == 0) + { + system->m_nozzle_rack->SendReadingFinished(); + } + } + } + + // replace-nozzle state: a rack nozzle standing in for the toolhead position. + // Absent for every non-rack printer's "nozzle" block => both stay std::nullopt (inert). + if (nozzle_json.contains("src_id")) + { + system->m_replace_nozzle_src = std::make_optional(nozzle_json["src_id"].get()); + } + + if (nozzle_json.contains("tar_id")) + { + system->m_replace_nozzle_tar = std::make_optional(nozzle_json["tar_id"].get()); + } + + system->ClearNozzles(); + for (auto it = nozzle_json["info"].begin(); it != nozzle_json["info"].end(); it++) + { + DevNozzle nozzle_obj; + nozzle_obj.SetRack(system->GetNozzleRack()); + + const auto& njon = it.value(); + nozzle_obj.m_nozzle_id = DevUtil::get_hex_bits(njon["id"].get(), 0); + nozzle_obj.m_diameter = njon["diameter"].get(); + s_parse_nozzle_type(njon["type"].get(), nozzle_obj); + if (njon.contains("stat"))/*maybe not contains*/ + { + nozzle_obj.SetStatus(njon["stat"].get()); + } + + DevJsonValParser::ParseVal(njon, "fila_id", nozzle_obj.m_fila_id); + DevJsonValParser::ParseVal(njon, "wear", nozzle_obj.m_wear); + if (njon.contains("p_t"))/*maybe not contains*/ + { + nozzle_obj.m_nozzle_print_time = njon["p_t"].get(); + } + if (njon.contains("color_m"))/*maybe not contains*/ + { + nozzle_obj.m_filament_clr = njon["color_m"].get(); + } + + if (DevUtil::get_hex_bits(njon["id"].get(), 1) == 1) + { + system->m_nozzle_rack->AddRackNozzle(nozzle_obj); + } + else + { + system->m_ext_nozzles[nozzle_obj.m_nozzle_id] = nozzle_obj; + } + } } - if (nozzle_json.contains("state")) + if (device_json.contains("holder")) { - system->m_state = DevUtil::get_flag_bits(nozzle_json["state"].get(), 0, 4); - } - - for (auto it = nozzle_json["info"].begin(); it != nozzle_json["info"].end(); it++) - { - DevNozzle nozzle_obj; - const auto& njon = it.value(); - nozzle_obj.m_nozzle_id = njon["id"].get(); - nozzle_obj.m_diameter = njon["diameter"].get(); - s_parse_nozzle_type(njon["type"].get(), nozzle_obj); - system->m_nozzles[nozzle_obj.m_nozzle_id] = nozzle_obj; + system->m_nozzle_rack->ParseRackInfo(device_json["holder"]); } } -} \ No newline at end of file +}; diff --git a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h index db786cf966..8603baeaaf 100644 --- a/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h +++ b/src/slic3r/GUI/DeviceCore/DevNozzleSystem.h @@ -1,28 +1,112 @@ #pragma once +#include "DevDefs.h" +#include "DevFirmware.h" + #include "libslic3r/CommonDefs.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" #include "slic3r/Utils/json_diff.hpp" #include #include +#include + +// Device flow-type mapping note (nozzle rack): the device U_FLOW value maps to nvtTPUHighFlow +// (TPU High Flow), so a device-synced TPU-HF rack resolves to nvtTPUHighFlow and the H2C +// change_filament_gcode TPU-kit branch can activate. nvtHybrid is a slicer-only sentinel with no +// device representation, so it stays out of these device flow-type conversions. +// +// GetExtruderNozzleInfo (and its ExtruderNozzleInfos aggregate) is intentionally omitted here; +// the SelectMachine slicing-vs-installed nozzle comparison collects its per-extruder NozzleDef +// entries itself (s_get_slicing_extuder_nozzles). namespace Slic3r { // Previous definitions class MachineObject; + class DevNozzleRack; struct DevNozzle { + friend class DevNozzleSystemParser; + + public: int m_nozzle_id = -1; NozzleFlowType m_nozzle_flow = NozzleFlowType::S_FLOW;// 0-common 1-high flow NozzleType m_nozzle_type = NozzleType::ntUndefine;// 0-stainless_steel 1-hardened_steel 5-tungsten_carbide float m_diameter = 0.0f;// unknown until reported by the printer + + public: + // flow/volume conversions (Standard / High Flow / TPU High Flow) + static NozzleFlowType ToNozzleFlowType(const NozzleVolumeType& type); + static NozzleVolumeType ToNozzleVolumeType(const NozzleFlowType& type); + + static wxString GetNozzleFlowTypeStr(NozzleFlowType type); + static std::string GetNozzleFlowTypeString(NozzleFlowType type);// untranslated literal ("High Flow"/"Standard"/"TPU High Flow") — the filament blacklist JSON matches these raw strings, so it must NOT use the translated GetNozzleFlowTypeStr (would break non-English locales) + static std::string ToNozzleFlowString(const NozzleFlowType& type);// untranslated "Standard"/"High Flow"/"TPU High Flow" ("" for none) — the raw literal serialized into the get_auto_nozzle_mapping payload + static wxString GetNozzleTypeStr(NozzleType type); + + public: + bool IsEmpty() const { return m_nozzle_id < 0; } + + void SetRack(const std::weak_ptr& rack) { m_nozzle_rack = rack; } + + int GetNozzleId() const { return m_nozzle_id; } + int GetNozzlePosId() const;// physical position id: rack nozzle -> id + 0x10, else id + NozzleType GetNozzleType() const { return m_nozzle_type; } + NozzleFlowType GetNozzleFlowType() const { return m_nozzle_flow; } + NozzleDiameterType GetNozzleDiameterType() const; + float GetNozzleDiameter() const { return m_diameter; } + float GetNozzleWear() const { return m_wear; } + int GetNozzlePrintTime() const { return m_nozzle_print_time; } + + // firmware (rack hotend WTM / extruder nozzle firmware) + DevFirmwareVersionInfo GetFirmwareInfo() const; + + // display + wxString GetNozzleDiameterStr() const { return wxString::Format("%.1f mm", m_diameter); } + wxString GetNozzleFlowTypeStr() const { return GetNozzleFlowTypeStr(m_nozzle_flow); } + wxString GetNozzleTypeStr() const { return GetNozzleTypeStr(m_nozzle_type); } + + std::string GetFilamentId() const { return m_fila_id; } + std::string GetFilamentColor() const { return m_filament_clr; } + + // location + bool AtLeftExtruder() const; + bool AtRightExtruder() const; + + int GetLogicExtruderId() const;// warning: logical extruder id + int GetExtruderId() const;// warning: physical extruder id + + /* holder nozzle */ + bool IsOnRack() const { return m_on_rack; } + bool IsInfoReliable() const; + + bool IsNormal() const; + bool IsAbnormal() const; + bool IsUnknown() const; + + void SetOnRack(bool on_rack) { m_on_rack = on_rack; } + void SetStatus(int stat) { m_stat = stat; } + + private: + int GetTotalExtruderCount() const; + + private: + bool m_on_rack = false; + + int m_stat = 0; + float m_wear = 0.0f; + + std::string m_fila_id; // main material + std::string m_filament_clr; // main color + + std::weak_ptr m_nozzle_rack; // weak pointer to the nozzle rack + int m_nozzle_print_time{0}; }; class DevNozzleSystem { friend class DevNozzleSystemParser; - public: - DevNozzleSystem(MachineObject* owner) : m_owner(owner) {} private: enum Status : int { @@ -31,27 +115,81 @@ namespace Slic3r }; public: - bool ContainsNozzle(int id) const { return m_nozzles.find(id) != m_nozzles.end(); } - DevNozzle GetNozzle(int id) const; - const std::map& GetNozzles() const { return m_nozzles;} - bool IsRefreshing() const { return m_state == 1; } + DevNozzleSystem(MachineObject* owner); + ~DevNozzleSystem() = default; + + public: + MachineObject* GetOwner() const { return m_owner; } + + // nozzle by position id: pos_id < 0x10 -> extruder nozzle, else rack nozzle at (pos_id - 0x10) + DevNozzle GetNozzleByPosId(int pos_id) const { return pos_id < 0x10 ? GetExtNozzle(pos_id) : GetRackNozzle(pos_id - 0x10); } + + // nozzles on extruder + bool ContainsExtNozzle(int id) const { return m_ext_nozzles.find(id) != m_ext_nozzles.end(); } + DevNozzle GetExtNozzle(int id) const; + const std::map& GetExtNozzles() const { return m_ext_nozzles; } + int GetExtNozzleCount() const { return (int) m_ext_nozzles.size(); } + + // nozzles on rack + void SetSupportNozzleRack(bool supported); + std::shared_ptr GetNozzleRack() const { return m_nozzle_rack; } + DevNozzle GetRackNozzle(int idx) const; + const std::map& GetRackNozzles() const; + + // nozzles on extruder and rack + bool IsRackMaximumInstalled() const;// true when the main extruder + all 6 rack slots hold nozzles + + // grouping (drives the MultiNozzleSyncDialog options) + const std::vector CollectNozzles(int ext_loc, NozzleFlowType flow_type, float diameter = -1.0f) const; + std::vector GetNozzleGroups() const; + + bool IsIdle() const { return m_state_0_4 == NOZZLE_SYSTEM_IDLE; } + bool IsRefreshing() const { return m_state_0_4 == NOZZLE_SYSTEM_REFRESHING; } + + bool HasUnreliableNozzles() const;// any extruder or rack nozzle whose reported info is not reliable + bool HasUnknownNozzles() const; // any extruder or rack nozzle of unknown state + + /* reading */ + int GetReadingIdx() const { return m_reading_idx; } + int GetReadingCount() const { return m_reading_count; } + + /* firmware */ + void AddFirmwareInfoWTM(const DevFirmwareVersionInfo& info);// route a "wtm/" module version to the rack nozzle, else to the extruder nozzle + void ClearFirmwareInfoWTM(); + DevFirmwareVersionInfo GetExtruderNozzleFirmware() const { return m_ext_nozzle_firmware_info; } + + /* replace nozzle (device reports src/tar position while a rack nozzle stands in for the toolhead) */ + std::optional GetReplaceNozzleSrc() const { return m_replace_nozzle_src; } + std::optional GetReplaceNozzleTar() const { return m_replace_nozzle_tar; } private: - void Reset(); + void ClearNozzles(); private: MachineObject* m_owner = nullptr; - int m_extder_exist = 0; //0- none exist 1-exist, unused - int m_state = 0; //0-idle 1-checking, unused - std::map m_nozzles; + int m_extder_exist = 0; //0- none exist 1-exist, unused + int m_state_0_4 = 0; //0-idle 1-refreshing + std::optional m_replace_nozzle_src; // replace nozzle source position (device-reported) + std::optional m_replace_nozzle_tar; // replace nozzle target position (device-reported) + + /* refreshing */ + int m_reading_idx = 0; + int m_reading_count = 0; + + // nozzles on extruder + std::map m_ext_nozzles; + DevFirmwareVersionInfo m_ext_nozzle_firmware_info; + + // nozzles on rack + std::shared_ptr m_nozzle_rack; }; class DevNozzleSystemParser { public: static void ParseV1_0(const nlohmann::json& nozzletype_json, const nlohmann::json& diameter_json, DevNozzleSystem* system, std::optional flag_e3d); - static void ParseV2_0(const json& nozzle_json, DevNozzleSystem* system); + static void ParseV2_0(const json& device_json, DevNozzleSystem* system); }; -}; \ No newline at end of file +}; diff --git a/src/slic3r/GUI/DeviceCore/DevUtil.h b/src/slic3r/GUI/DeviceCore/DevUtil.h index 4ba309b18c..fcf912b622 100644 --- a/src/slic3r/GUI/DeviceCore/DevUtil.h +++ b/src/slic3r/GUI/DeviceCore/DevUtil.h @@ -28,6 +28,10 @@ public: static int get_flag_bits(std::string str, int start, int count = 1); static int get_flag_bits(int num, int start, int count = 1, int base = 10); + // Extract the hex digit at position `pos` (0 = least-significant). + // eg. get_hex_bits(16, 1, 10) = 1 + static int get_hex_bits(int num, int pos, int input_num_base = 10) { return get_flag_bits(num, pos * 4, 4, input_num_base); } + static float string_to_float(const std::string& str_value); static std::string convertToIp(long long ip); diff --git a/src/slic3r/GUI/DeviceCore/DevUtilBackend.cpp b/src/slic3r/GUI/DeviceCore/DevUtilBackend.cpp new file mode 100644 index 0000000000..32d30379f6 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevUtilBackend.cpp @@ -0,0 +1,86 @@ +#include "DevUtilBackend.h" + +#include "slic3r/GUI/BackgroundSlicingProcess.hpp" + +#include "slic3r/GUI/Plater.hpp" +#include "slic3r/GUI/GUI_App.hpp" + +#include + +namespace Slic3r +{ + +std::shared_ptr DevUtilBackend::GetNozzleGroupResult(Slic3r::GUI::Plater* plater) +{ + if (plater && plater->background_process().get_current_gcode_result()) { + return plater->background_process().get_current_gcode_result()->nozzle_group_result; + } + + return nullptr; +} + +static std::unordered_map s_ams_type_map = { + {"0", DevAmsType::N3F}, + {"1", DevAmsType::N3S}, +}; + +std::optional DevUtilBackend::GetFilamentDryingPreset(const std::string& fila_id) +{ + if (fila_id.empty() || !GUI::wxGetApp().preset_bundle) { + return std::nullopt; + } + + for (auto iter = GUI::wxGetApp().preset_bundle->filaments.begin(); iter != GUI::wxGetApp().preset_bundle->filaments.end(); ++iter) { + const Preset& filament_preset = *iter; + const auto& config = filament_preset.config; + if (filament_preset.filament_id == fila_id) { + DevFilamentDryingPreset info; + info.filament_id = fila_id; + try { + if (config.has("filament_dev_ams_drying_ams_limitations")) { + std::vector types = config.option("filament_dev_ams_drying_ams_limitations")->values; + for (auto type : types) { + if (s_ams_type_map.count(type) == 0) { + continue; + } + info.ams_limitations.insert(s_ams_type_map[type]); + } + } + + if (config.has("filament_dev_ams_drying_temperature")) { + info.filament_dev_ams_drying_temperature_on_idle[DevAmsType::N3F] = config.option("filament_dev_ams_drying_temperature")->get_at(0); + info.filament_dev_ams_drying_temperature_on_idle[DevAmsType::N3S] = config.option("filament_dev_ams_drying_temperature")->get_at(1); + info.filament_dev_ams_drying_temperature_on_print[DevAmsType::N3F] = config.option("filament_dev_ams_drying_temperature")->get_at(2); + info.filament_dev_ams_drying_temperature_on_print[DevAmsType::N3S] = config.option("filament_dev_ams_drying_temperature")->get_at(3); + } + + if (config.has("filament_dev_ams_drying_time")) { + info.filament_dev_ams_drying_time_on_idle[DevAmsType::N3F] = config.option("filament_dev_ams_drying_time")->get_at(0); + info.filament_dev_ams_drying_time_on_idle[DevAmsType::N3S] = config.option("filament_dev_ams_drying_time")->get_at(1); + info.filament_dev_ams_drying_time_on_print[DevAmsType::N3F] = config.option("filament_dev_ams_drying_time")->get_at(2); + info.filament_dev_ams_drying_time_on_print[DevAmsType::N3S] = config.option("filament_dev_ams_drying_time")->get_at(3); + } + + if (config.has("filament_dev_drying_softening_temperature")) { + info.filament_dev_drying_softening_temperature = config.option("filament_dev_drying_softening_temperature")->get_at(0); + } + + if (config.has("filament_dev_ams_drying_heat_distortion_temperature")) { + info.filament_dev_ams_drying_heat_distortion_temperature = config.option("filament_dev_ams_drying_heat_distortion_temperature")->get_at(0); + } + + if (config.has("filament_dev_drying_cooling_temperature")) { + info.filament_dev_drying_cooling_temperature = config.option("filament_dev_drying_cooling_temperature")->get_at(0); + } + + return info; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << " exception: " << e.what(); + } + } + } + + return std::nullopt; +} + +}; // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceCore/DevUtilBackend.h b/src/slic3r/GUI/DeviceCore/DevUtilBackend.h new file mode 100644 index 0000000000..5c7869f1e4 --- /dev/null +++ b/src/slic3r/GUI/DeviceCore/DevUtilBackend.h @@ -0,0 +1,34 @@ +/** + * @file DevUtilBackend.h + * @brief Provides common static utility methods for backend (preset/slicing). + */ + +#pragma once +#include "DevDefs.h" +#include "DevFilaSystem.h" + +#include "libslic3r/MultiNozzleUtils.hpp" +#include +#include + +namespace Slic3r +{ +namespace GUI { class Plater; } + +class DevUtilBackend +{ +public: + DevUtilBackend() = delete; + +public: + + // for rack: the slicer's per-filament -> logical-nozzle grouping for the current plate, read off + // the post-slice GCodeProcessorResult (plater->background_process().get_current_gcode_result()). + // Returns nullptr when there is no plater / no current result. + static std::shared_ptr GetNozzleGroupResult(Slic3r::GUI::Plater* plater); + + // for filament preset + static std::optional GetFilamentDryingPreset(const std::string& fila_id); +}; + +}; // namespace Slic3r diff --git a/src/slic3r/GUI/DeviceManager.cpp b/src/slic3r/GUI/DeviceManager.cpp index 9d7afd13b9..b23528a372 100644 --- a/src/slic3r/GUI/DeviceManager.cpp +++ b/src/slic3r/GUI/DeviceManager.cpp @@ -23,6 +23,7 @@ #include "fast_float/fast_float.h" #include "DeviceCore/DevFilaSystem.h" +#include "DeviceCore/DevFilaSwitch.h" #include "DeviceCore/DevExtensionTool.h" #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevNozzleSystem.h" @@ -39,6 +40,7 @@ #include "DeviceCore/DevHMS.h" #include "DeviceCore/DevMapping.h" +#include "DeviceCore/DevMappingNozzle.h" #include "DeviceCore/DevManager.h" #include "DeviceCore/DevUtil.h" @@ -566,12 +568,15 @@ MachineObject::MachineObject(DeviceManager* manager, NetworkAgent* agent, std::s m_extder_system = new DevExtderSystem(this); m_extension_tool = DevExtensionTool::Create(this); m_nozzle_system = new DevNozzleSystem(this); - m_fila_system = new DevFilaSystem(this); + m_fila_system = std::make_shared(this); + m_fila_switch = new DevFilaSwitch(this); m_hms_system = new DevHMS(this); m_config = new DevConfig(this); m_ctrl = new DevCtrl(this); m_print_options = new DevPrintOptions(this); + + m_nozzle_mapping_ptr = std::make_shared(this); } } @@ -612,8 +617,9 @@ MachineObject::~MachineObject() delete m_ctrl; m_ctrl = nullptr; - delete m_fila_system; - m_fila_system = nullptr; + + delete m_fila_switch; + m_fila_switch = nullptr; delete m_hms_system; m_hms_system = nullptr; @@ -861,7 +867,11 @@ void MachineObject::clear_version_info() laser_version_info = DevFirmwareVersionInfo(); cutting_module_version_info = DevFirmwareVersionInfo(); extinguish_version_info = DevFirmwareVersionInfo(); + filatrack_version_info = DevFirmwareVersionInfo(); module_vers.clear(); + // Drop cached rack-hotend (WTM) firmware alongside the module list. + // Inert for non-rack printers (rack firmware map is empty). + m_nozzle_system->ClearFirmwareInfoWTM(); } void MachineObject::store_version_info(const DevFirmwareVersionInfo& info) @@ -874,6 +884,13 @@ void MachineObject::store_version_info(const DevFirmwareVersionInfo& info) cutting_module_version_info = info; } else if (info.isExtinguishSystem()) { extinguish_version_info = info; + } else if (info.isWTM()) { + // Route rack-hotend / extruder-nozzle firmware into the nozzle system so + // the rack upgrade UI can read per-nozzle versions. isWTM() is false for every non-rack + // printer's modules, so this branch never fires outside H2C. + m_nozzle_system->AddFirmwareInfoWTM(info); + } else if (info.isFilaTrackSwitch()) { + filatrack_version_info = info; } module_vers.emplace(info.name, info); @@ -1556,7 +1573,7 @@ int MachineObject::check_resume_condition() } return 0; } -int MachineObject::command_ams_change_filament(bool load, std::string ams_id, std::string slot_id, int old_temp, int new_temp) +int MachineObject::command_ams_change_filament(bool load, std::string ams_id, std::string slot_id, int old_temp, int new_temp, std::optional extruder_id) { json j; try { @@ -1588,6 +1605,13 @@ int MachineObject::command_ams_change_filament(bool load, std::string ams_id, st j["print"]["slot_id"] = atoi(slot_id.c_str()); } + // Filament Track Switch: route the load to the chosen extruder. Only present when the + // caller supplied a value (FTS-installed+ready path), so every other caller is unchanged. + if (extruder_id.has_value()) + { + j["print"]["extruder_id"] = *extruder_id; + } + } catch (const std::exception &) {} return this->publish_json(j); } @@ -1976,6 +2000,10 @@ int MachineObject::command_set_pa_calibration(const std::vector & j["print"]["filaments"][i]["n_coef"] = std::to_string(pa_calib_values[i].n_coef); else j["print"]["filaments"][i]["n_coef"] = "0.0"; + if (pa_calib_values[i].nozzle_pos_id >= 0) { + j["print"]["filaments"][i]["nozzle_pos"] = pa_calib_values[i].nozzle_pos_id; + j["print"]["filaments"][i]["nozzle_sn"] = pa_calib_values[i].nozzle_sn; + } } BOOST_LOG_TRIVIAL(info) << "extrusion_cali_set: " << j.dump(); @@ -1994,6 +2022,10 @@ int MachineObject::command_delete_pa_calibration(const PACalibIndexInfo& pa_cali j["print"]["nozzle_id"] = _generate_nozzle_id(pa_calib.nozzle_volume_type, to_string_nozzle_diameter(pa_calib.nozzle_diameter)).ToStdString(); j["print"]["filament_id"] = pa_calib.filament_id; j["print"]["cali_idx"] = pa_calib.cali_idx; + if (pa_calib.nozzle_pos_id >= 0) { + j["print"]["nozzle_pos"] = pa_calib.nozzle_pos_id; + j["print"]["nozzle_sn"] = pa_calib.nozzle_sn; + } j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(pa_calib.nozzle_diameter); BOOST_LOG_TRIVIAL(info) << "extrusion_cali_del: " << j.dump(); @@ -2014,6 +2046,11 @@ int MachineObject::command_get_pa_calibration_tab(const PACalibExtruderInfo &cal j["print"]["nozzle_id"] = _generate_nozzle_id(calib_info.nozzle_volume_type, to_string_nozzle_diameter(calib_info.nozzle_diameter)).ToStdString(); j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(calib_info.nozzle_diameter); + if (calib_info.nozzle_pos_id >= 0) { + j["print"]["nozzle_pos"] = calib_info.nozzle_pos_id; + j["print"]["nozzle_sn"] = calib_info.nozzle_sn; + } + BOOST_LOG_TRIVIAL(info) << "extrusion_cali_get: " << j.dump(); request_tab_from_bbs = true; return this->publish_json(j); @@ -2040,6 +2077,10 @@ int MachineObject::commnad_select_pa_calibration(const PACalibIndexInfo& pa_cali j["print"]["slot_id"] = pa_calib_info.slot_id; j["print"]["cali_idx"] = pa_calib_info.cali_idx; j["print"]["filament_id"] = pa_calib_info.filament_id; + if (pa_calib_info.nozzle_pos_id >= 0) { + j["print"]["nozzle_pos"] = pa_calib_info.nozzle_pos_id; + j["print"]["nozzle_sn"] = pa_calib_info.nozzle_sn; + } j["print"]["nozzle_diameter"] = to_string_nozzle_diameter(pa_calib_info.nozzle_diameter); BOOST_LOG_TRIVIAL(info) << "extrusion_cali_sel: " << j.dump(); @@ -2379,6 +2420,7 @@ void MachineObject::reset() jobState_ = 0; m_plate_index = -1; device_cert_installed = false; + clear_auto_nozzle_mapping();// reset nozzle mapping // reset print_json json empty_j; @@ -2896,6 +2938,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ } m_fan->ParseV2_0(jj); + m_fila_switch->ParseFilaSwitchInfo(jj); if (jj.contains("support_filament_backup")) { if (jj["support_filament_backup"].is_boolean()) { @@ -3000,6 +3043,8 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ if (jj.contains("command")) { + m_nozzle_mapping_ptr->ParseAutoNozzleMapping(jj); + if (jj["command"].get() == "ams_change_filament") { if (jj.contains("errno")) { if (jj["errno"].is_number()) { @@ -3723,7 +3768,7 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ update_printer_preset_name(); update_filament_list(); if (jj.contains("ams")) { - DevFilaSystemParser::ParseV1_0(jj, this, m_fila_system, key_field_only); + DevFilaSystemParser::ParseV1_0(jj, this, m_fila_system.get(), key_field_only); } /* vitrual tray*/ @@ -4082,6 +4127,14 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ pa_calib_result.nozzle_volume_type = convert_to_nozzle_type((*it)["nozzle_id"].get()); } + if ((*it).contains("nozzle_pos")) { + pa_calib_result.nozzle_pos_id = (*it)["nozzle_pos"].get(); + } + + if ((*it).contains("nozzle_sn")) { + pa_calib_result.nozzle_sn = (*it)["nozzle_sn"].get(); + } + if (jj["nozzle_diameter"].is_number_float()) { pa_calib_result.nozzle_diameter = jj["nozzle_diameter"].get(); } else if (jj["nozzle_diameter"].is_string()) { @@ -4179,6 +4232,14 @@ int MachineObject::parse_json(std::string tunnel, std::string payload, bool key_ pa_calib_result.nozzle_volume_type = NozzleVolumeType::nvtStandard; } + if (it->contains("nozzle_pos")) { + pa_calib_result.nozzle_pos_id = (*it)["nozzle_pos"].get(); + } + + if (it->contains("nozzle_sn")) { + pa_calib_result.nozzle_sn = (*it)["nozzle_sn"].get(); + } + if ((*it)["k_value"].is_number_float()) pa_calib_result.k_value = (*it)["k_value"].get(); else if ((*it)["k_value"].is_string()) @@ -5004,6 +5065,7 @@ void MachineObject::parse_new_info(json print) is_support_user_preset = get_flag_bits(fun, 11); is_support_door_open_check = get_flag_bits(fun, 12); is_support_nozzle_blob_detection = get_flag_bits(fun, 13); + m_nozzle_system->SetSupportNozzleRack(get_flag_bits(fun, 60)); // H2C hotend rack support (device-side gate for the sync dialog) is_support_upgrade_kit = get_flag_bits(fun, 14); is_support_internal_timelapse = get_flag_bits(fun, 28); m_support_mqtt_homing = get_flag_bits(fun, 32); @@ -5031,6 +5093,8 @@ void MachineObject::parse_new_info(json print) // fun2 may have infinite length, use get_flag_bits_no_border if (!fun2.empty()) { is_support_print_with_emmc = get_flag_bits_no_border(fun2, 0) == 1; + is_support_remote_dry = (get_flag_bits_no_border(fun2, 5) == 1); + is_support_check_track_switch_match_slice_printer = get_flag_bits_no_border(fun2, 19) == 1; } /*aux*/ @@ -5066,7 +5130,10 @@ void MachineObject::parse_new_info(json print) DevBed::ParseV2_0(device,m_bed); - if (device.contains("nozzle")) { DevNozzleSystemParser::ParseV2_0(device["nozzle"], m_nozzle_system); } + // Pass the whole device json: ParseV2_0 reads ext/rack nozzles from device["nozzle"] and the + // hotend-rack state from device["holder"] (rack data lives outside device["nozzle"]). It is a + // no-op for devices that report neither key, so non-rack machines are unaffected. + DevNozzleSystemParser::ParseV2_0(device, m_nozzle_system); if (device.contains("extruder")) { ExtderSystemParser::ParseV2_0(device["extruder"], m_extder_system);} if (device.contains("ext_tool")) { DevExtensionToolParser::ParseV2_0(device["ext_tool"], m_extension_tool); } diff --git a/src/slic3r/GUI/DeviceManager.hpp b/src/slic3r/GUI/DeviceManager.hpp index 0a31c18502..4ce4cad8de 100644 --- a/src/slic3r/GUI/DeviceManager.hpp +++ b/src/slic3r/GUI/DeviceManager.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include "nlohmann/json.hpp" @@ -83,10 +84,12 @@ class DevExtensionTool; class DevExtderSystem; class DevFan; class DevFilaSystem; +class DevFilaSwitch; class DevPrintOptions; class DevHMS; class DevLamp; class DevNozzleSystem; +class DevNozzleMappingCtrl; class DeviceManager; class DevStorage; struct DevPrintTaskRatingInfo; @@ -114,7 +117,8 @@ private: std::shared_ptr m_extension_tool; DevExtderSystem* m_extder_system; DevNozzleSystem* m_nozzle_system; - DevFilaSystem* m_fila_system; + std::shared_ptr m_fila_system; + DevFilaSwitch* m_fila_switch; DevFan* m_fan; DevBed * m_bed; DevStorage* m_storage; @@ -131,6 +135,11 @@ private: /*Config*/ DevConfig* m_config; + /* print-dispatch nozzle mapping (H2C hotend rack). Created unconditionally in the ctor so + get_nozzle_mapping_result() is always valid; stays empty (no result attached) for every + non-rack printer. */ + std::shared_ptr m_nozzle_mapping_ptr; + public: MachineObject(DeviceManager* manager, NetworkAgent* agent, std::string name, std::string id, std::string ip); ~MachineObject(); @@ -329,7 +338,12 @@ public: DevNozzleSystem* GetNozzleSystem() const { return m_nozzle_system;} - DevFilaSystem* GetFilaSystem() const { return m_fila_system;} + /* print-dispatch nozzle mapping (H2C hotend rack); result stays empty for non-rack printers */ + std::shared_ptr get_nozzle_mapping_result() const { return m_nozzle_mapping_ptr; } + void clear_auto_nozzle_mapping();// defined in DevMappingNozzle.cpp + + std::shared_ptr GetFilaSystem() const { return m_fila_system;} + DevFilaSwitch* GetFilaSwitch() const { return m_fila_switch;} bool HasAms() const; DevLamp* GetLamp() const { return m_lamp; } @@ -365,6 +379,7 @@ public: DevFirmwareVersionInfo laser_version_info; DevFirmwareVersionInfo cutting_module_version_info; DevFirmwareVersionInfo extinguish_version_info; + DevFirmwareVersionInfo filatrack_version_info; std::map module_vers; std::map new_ver_list; bool m_new_ver_list_exist = false; @@ -620,6 +635,8 @@ public: // fun2 bool is_support_print_with_emmc{false}; + bool is_support_remote_dry = false; + bool is_support_check_track_switch_match_slice_printer{false}; bool installed_upgrade_kit{false}; int bed_temperature_limit = -1; @@ -733,7 +750,7 @@ public: int check_resume_condition(); // ams controls //int command_ams_switch(int tray_index, int old_temp = 210, int new_temp = 210); - int command_ams_change_filament(bool load, std::string ams_id, std::string slot_id, int old_temp = 210, int new_temp = 210); + int command_ams_change_filament(bool load, std::string ams_id, std::string slot_id, int old_temp = 210, int new_temp = 210, std::optional extruder_id = std::nullopt); int command_ams_user_settings(bool start_read_opt, bool tray_read_opt, bool remain_flag = false); int command_ams_switch_filament(bool switch_filament); int command_ams_air_print_detect(bool air_print_detect); diff --git a/src/slic3r/GUI/DeviceTab/CMakeLists.txt b/src/slic3r/GUI/DeviceTab/CMakeLists.txt index 40f192ef4e..1438bf139b 100644 --- a/src/slic3r/GUI/DeviceTab/CMakeLists.txt +++ b/src/slic3r/GUI/DeviceTab/CMakeLists.txt @@ -4,5 +4,15 @@ list(APPEND SLIC3R_GUI_SOURCES GUI/DeviceTab/uiAmsHumidityPopup.cpp GUI/DeviceTab/uiDeviceUpdateVersion.h GUI/DeviceTab/uiDeviceUpdateVersion.cpp + GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h + GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp + GUI/DeviceTab/wgtDeviceNozzleRack.h + GUI/DeviceTab/wgtDeviceNozzleRack.cpp + GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h + GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp + GUI/DeviceTab/wgtDeviceNozzleSelect.h + GUI/DeviceTab/wgtDeviceNozzleSelect.cpp + GUI/DeviceTab/wgtMsgBox.h + GUI/DeviceTab/wgtMsgBox.cpp ) set(SLIC3R_GUI_SOURCES ${SLIC3R_GUI_SOURCES} PARENT_SCOPE) \ No newline at end of file diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp new file mode 100644 index 0000000000..da8eda24e0 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.cpp @@ -0,0 +1,700 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRack.cpp +* Description: The Device-tab panel with the toolhead nozzle and the H2C induction hotend rack. +* +* \n class wgtDeviceNozzleRack; +* \n class wgtDeviceNozzleRackToolHead; +* \n class wgtDeviceNozzleRackArea; +* \n class wgtDeviceNozzleRackPos; +* +* The wgtDeviceNozzleRackNozzleItem tile and the EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED event live in +* wgtDeviceNozzleRackNozzleItem.{h,cpp}, so they are not redefined here. +//**********************************************************/ + +#include "wgtDeviceNozzleRack.h" +#include "wgtDeviceNozzleRackUpdate.h" + +#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h" + +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/MainFrame.hpp" +#include "slic3r/GUI/wxExtensions.hpp" + +#include "slic3r/GUI/Widgets/Button.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" + +#define WX_DIP_SIZE(x, y) wxSize(FromDIP(x), FromDIP(y)) + +#define L_RAW_A_STR _L("Row A") +#define L_RAW_B_STR _L("Row B") + +// Orca: StateColor lacks these grey constants, so mirror the values here. +static const wxColour WGT_GREY200 = wxColour(248, 248, 248); +static const wxColour WGT_GREY300 = wxColour(238, 238, 238); + +static wxColour s_hgreen_clr("#009688"); + +namespace Slic3r::GUI +{ + +// Tints the "yellow" template pixels of a nozzle bitmap with the loaded filament colour. +// Duplicates the file-local helper of the same purpose in wgtDeviceNozzleRackNozzleItem.cpp. +static wxBitmap SetNozzleBmpColor(const wxBitmap& bmp, const std::string& color_str) { + if(color_str.empty()) return bmp; + + wxImage img = bmp.ConvertToImage(); + wxColour color("#" + color_str); + + for (int y = 0; y < img.GetHeight(); ++y) { + for (int x = 0; x < img.GetWidth(); ++x) { + unsigned char r = img.GetRed(x, y); + unsigned char g = img.GetGreen(x, y); + unsigned char b = img.GetBlue(x, y); + + /*replace yellow with color*/ + if ( r >= 180 && g >= 180 && b <= 150) { + img.SetRGB(x, y, color.Red(), color.Green(), color.Blue()); + } + } + } + + return wxBitmap(img, -1, bmp.GetScaleFactor()); +} + +// Orca: StateColor has no gray button style, so define one file-local. This panel is its only +// consumer, so keeping it here avoids touching the shared StateColor widget. +static StateColor s_button_style_gray() +{ + return StateColor(std::pair(wxColour(206, 206, 206), StateColor::Pressed), + std::pair(*wxWHITE, StateColor::Focused), + std::pair(wxColour(238, 238, 238), StateColor::Hovered), + std::pair(*wxWHITE, StateColor::Normal)); +} + +wgtDeviceNozzleRack::wgtDeviceNozzleRack(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style) + : wxPanel(parent, id, pos, size, style) +{ + CreateGui(); +} + +void wgtDeviceNozzleRack::CreateGui() +{ + m_toolhead_panel = new wgtDeviceNozzleRackToolHead(this); + m_rack_area = new wgtDeviceNozzleRackArea(this); + + wxPanel* separator = new wxPanel(this); + separator->SetMaxSize(wxSize(FromDIP(1), -1)); + separator->SetMinSize(wxSize(FromDIP(1), -1)); + separator->SetBackgroundColour(WGT_GREY300); + + wxSizer* main_sizer = new wxBoxSizer(wxHORIZONTAL); + main_sizer->AddStretchSpacer(); + main_sizer->Add(m_toolhead_panel, 0, wxEXPAND); + main_sizer->Add(separator, 0, wxEXPAND); + main_sizer->Add(m_rack_area, 0, wxEXPAND); + main_sizer->AddStretchSpacer(); + + SetSizer(main_sizer); + SetMaxSize(WX_DIP_SIZE(586, -1)); + SetMinSize(WX_DIP_SIZE(586, -1)); + SetSize(WX_DIP_SIZE(586, -1)); + Layout(); + + wxGetApp().UpdateDarkUIWin(this); +} + +void wgtDeviceNozzleRack::UpdateRackInfo(std::shared_ptr rack) +{ + if (!rack->IsSupported()) { return; } + + m_nozzle_rack = rack; + if (m_nozzle_rack.expired()) { return; } + + DevNozzleSystem* nozzle_system = m_nozzle_rack.lock()->GetNozzleSystem(); + if (nozzle_system) + { + m_toolhead_panel->UpdateToolHeadInfo(nozzle_system->GetExtNozzle(MAIN_EXTRUDER_ID)); + m_rack_area->UpdateRackInfo(m_nozzle_rack); + } +} + +void wgtDeviceNozzleRack::Rescale() +{ + m_toolhead_panel->Rescale(); + m_rack_area->Rescale(); + Layout(); +} + +class wgtDeviceNozzleRackTitle : public StaticBox +{ +public: + wgtDeviceNozzleRackTitle(wxWindow* parent, const wxString& title) : StaticBox(parent) + { + SetBackgroundColour(WGT_GREY200); + SetBorderColor(*wxWHITE); + SetCornerRadius(0); + + m_title_label = new Label(this, title); + m_title_label->SetFont(Label::Body_14); + m_title_label->SetBackgroundColour(WGT_GREY200); + + wxSizer* title_sizer = new wxBoxSizer(wxHORIZONTAL); + title_sizer->AddStretchSpacer(); + title_sizer->Add(m_title_label, 0, wxEXPAND | wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(5)); + title_sizer->AddStretchSpacer(); + SetSizer(title_sizer); + }; + +public: + void SetLabel(const wxString& new_label) { m_title_label->SetLabel(new_label); } + +private: + Label* m_title_label; +}; + + +void wgtDeviceNozzleRackToolHead::CreateGui() +{ + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + // Create Header + wgtDeviceNozzleRackTitle* title_box = new wgtDeviceNozzleRackTitle(this, _L("Toolhead")); + mainSizer->Add(title_box, 0, wxEXPAND | wxTOP); + mainSizer->AddStretchSpacer(); + + // Image + m_extruder_nozzle_empty = new ScalableBitmap(this, "dev_rack_toolhead_empty", 98); + m_extruder_nozzle_normal = new ScalableBitmap(this, "dev_rack_toolhead_normal", 98); + m_toolhead_icon = new wxStaticBitmap(this, wxID_ANY, m_extruder_nozzle_empty->bmp(), wxDefaultPosition, WX_DIP_SIZE(98, 98)); + mainSizer->Add(m_toolhead_icon, 0, wxALIGN_CENTRE_HORIZONTAL | wxTOP, FromDIP(20)); + + // Nozzle info + m_nozzle_diamenter_label = new Label(this); + m_nozzle_diamenter_label->SetFont(Label::Body_13); + m_nozzle_diamenter_label->SetBackgroundColour(*wxWHITE); + mainSizer->Add(m_nozzle_diamenter_label, 0, wxALIGN_CENTRE_HORIZONTAL | wxBOTTOM | wxTOP, FromDIP(5)); + + m_nozzle_flowtype_label = new Label(this); + m_nozzle_flowtype_label->SetFont(Label::Body_13); + m_nozzle_flowtype_label->SetBackgroundColour(*wxWHITE); + mainSizer->Add(m_nozzle_flowtype_label, 0, wxALIGN_CENTRE_HORIZONTAL); + mainSizer->AddStretchSpacer(); + + // Set sizer + SetSizer(mainSizer); + SetMaxSize(WX_DIP_SIZE(132, -1)); + SetMinSize(WX_DIP_SIZE(132, -1)); + SetSize(WX_DIP_SIZE(132, -1)); +} + +void wgtDeviceNozzleRackToolHead::UpdateToolHeadInfo(const DevNozzle& extruder_nozzle) +{ + /* Labels */ + if (extruder_nozzle.IsEmpty()) + { + m_nozzle_diamenter_label->Show(false); + m_nozzle_flowtype_label->SetLabel(_L("Empty")); + } + else if (extruder_nozzle.IsUnknown()) + { + m_nozzle_diamenter_label->Show(false); + m_nozzle_flowtype_label->SetLabel(_L("Unknown")); + } + else if (extruder_nozzle.IsAbnormal()) + { + m_nozzle_diamenter_label->Show(false); + m_nozzle_flowtype_label->SetLabel(_L("Error")); + } + else /*extruder_nozzle.IsNormal()*/ + { + m_nozzle_diamenter_label->Show(true); + m_nozzle_diamenter_label->SetLabel(extruder_nozzle.GetNozzleDiameterStr()); + m_nozzle_flowtype_label->SetLabel(extruder_nozzle.GetNozzleFlowTypeStr()); + } + + /* Icon*/ + bool extruder_exist = !extruder_nozzle.IsEmpty(); + if (m_extruder_nozzle_exist != extruder_exist) + { + m_extruder_nozzle_exist = extruder_exist; + m_filament_color = extruder_nozzle.GetFilamentColor(); + m_toolhead_icon->SetBitmap(m_extruder_nozzle_exist ? SetNozzleBmpColor(m_extruder_nozzle_normal->bmp(), m_filament_color) : m_extruder_nozzle_empty->bmp()); + m_toolhead_icon->Refresh(); + } +} + +void wgtDeviceNozzleRackToolHead::Rescale() +{ + m_extruder_nozzle_normal->msw_rescale(); + m_extruder_nozzle_empty->msw_rescale(); + m_toolhead_icon->SetBitmap(m_extruder_nozzle_exist ? SetNozzleBmpColor(m_extruder_nozzle_normal->bmp(), m_filament_color) : m_extruder_nozzle_empty->bmp()); + + Layout(); + Refresh(); +} + +void wgtDeviceNozzleRackArea::CreateGui() +{ + wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + + // Create Header + m_title_nozzle_rack = new wgtDeviceNozzleRackTitle(this, _L("Induction Hotend Rack")); + main_sizer->Add(m_title_nozzle_rack, 0, wxEXPAND | wxTOP); + + // Create Simple Book + m_simple_book = new wxSimplebook(this, wxID_ANY); + + wxSizer* content_sizer = new wxBoxSizer(wxVERTICAL); + + m_panel_content = new wxPanel(m_simple_book, wxID_ANY); + m_panel_refresh = new wxPanel(m_simple_book, wxID_ANY); + + // Create Hotends ans Rack Position Panel + wxSizer* hotends_rack_sizer = new wxBoxSizer(wxHORIZONTAL); + + // Hotends + m_hotends_sizer = new wxBoxSizer(wxVERTICAL); + m_arow_nozzles_box = CreateNozzleBox( { 0, 2, 4}); + m_brow_nozzles_box = CreateNozzleBox( { 1, 3, 5}); + m_hotends_sizer->Add(m_arow_nozzles_box); + m_hotends_sizer->Add(m_brow_nozzles_box); + hotends_rack_sizer->Add(m_hotends_sizer, 0, wxLEFT, FromDIP(8)); + + // Rack + m_rack_pos_panel = new wgtDeviceNozzleRackPos(m_panel_content); + hotends_rack_sizer->Add(m_rack_pos_panel, 0, wxEXPAND); + content_sizer->Add(hotends_rack_sizer, 0); + + wxSizer* btn_sizer = new wxBoxSizer(wxHORIZONTAL); + m_btn_hotends_infos = new Button(m_panel_content, _L("Hotends Info")); + m_btn_hotends_infos->SetFont(Label::Body_12); + m_btn_hotends_infos->SetBackgroundColor(s_button_style_gray()); + m_btn_hotends_infos->SetBackgroundColour(*wxWHITE); + m_btn_hotends_infos->Bind(wxEVT_BUTTON, &wgtDeviceNozzleRackArea::OnBtnHotendsInfos, this); + + m_btn_read_all = new Button(m_panel_content, _L("Read All")); + m_btn_read_all->SetFont(Label::Body_12); + m_btn_read_all->SetBackgroundColor(s_button_style_gray()); + m_btn_read_all->SetBackgroundColour(*wxWHITE); + m_btn_read_all->Bind(wxEVT_BUTTON, &wgtDeviceNozzleRackArea::OnBtnReadAll, this); + + btn_sizer->Add(m_btn_hotends_infos, 0, wxLEFT); + btn_sizer->Add(m_btn_read_all, 0, wxLEFT, FromDIP(5)); + content_sizer->Add(btn_sizer, 0, wxLEFT, FromDIP(10)); + + /* refresh panel */ + wxSizer* refresh_sizer = CreateRefreshBook(m_panel_refresh); + + m_panel_content->SetSizer(content_sizer); + m_panel_refresh->SetSizer(refresh_sizer); + m_simple_book->AddPage(m_panel_content, "Content"); + m_simple_book->AddPage(m_panel_refresh, "Refresh"); + main_sizer->Add(m_simple_book, 1, wxEXPAND); + + m_simple_book->SetSelection(0); + + SetSizer(main_sizer); + Layout(); + Fit(); +} + +wxSizer* wgtDeviceNozzleRackArea::CreateRefreshBook(wxPanel* parent) +{ + wxSizer* refresh_sizer = new wxBoxSizer(wxVERTICAL); + + std::vector list{"ams_rfid_1", "ams_rfid_2", "ams_rfid_3", "ams_rfid_4"}; + m_refresh_icon = new AnimaIcon(parent, wxID_ANY, list, "refresh_printer", 100); + m_refresh_icon->SetMinSize(wxSize(FromDIP(25), FromDIP(25))); + + wxSizer* progress_sizer = new wxBoxSizer(wxHORIZONTAL); + + Label* progress_prefix = new Label(parent, _L("Reading ")); + progress_prefix->SetBackgroundColour(*wxWHITE); + m_progress_refresh = new Label(parent, "(1/6)"); + m_progress_refresh->SetFont(Label::Body_14); + m_progress_refresh->SetBackgroundColour(*wxWHITE); + m_progress_refresh->SetForegroundColour(*wxGREEN); + Label* progress_suffix = new Label(parent, " ..."); + progress_suffix->SetBackgroundColour(*wxWHITE); + + progress_sizer->Add(progress_prefix, 0, wxLEFT); + progress_sizer->Add(m_progress_refresh, 0, wxLEFT); + progress_sizer->Add(progress_suffix, 0, wxLEFT); + + Label* refresh_tip = new Label(parent, _L("Please wait")); + refresh_tip->SetBackgroundColour(*wxWHITE); + + refresh_sizer->Add(0, 0, 1, wxEXPAND, 0); + refresh_sizer->Add(m_refresh_icon, 0, wxALIGN_CENTER_HORIZONTAL, 0); + refresh_sizer->Add(progress_sizer, 0, wxALIGN_CENTER_HORIZONTAL, FromDIP(0)); + refresh_sizer->Add(refresh_tip, 0, wxALIGN_CENTER_HORIZONTAL, FromDIP(0)); + refresh_sizer->Add(0, 0, 1, wxEXPAND, 0); + + return refresh_sizer; +} + +StaticBox* wgtDeviceNozzleRackArea::CreateNozzleBox(const std::vector nozzle_idxes) +{ + StaticBox* nozzle_box = new StaticBox(m_panel_content); + nozzle_box->SetBackgroundColor(*wxWHITE); + nozzle_box->SetBorderColor(*wxWHITE); + nozzle_box->SetCornerRadius(0); + + wxSizer* h_sizer = new wxBoxSizer(wxHORIZONTAL); + for (auto start_idx : nozzle_idxes) + { + wgtDeviceNozzleRackNozzleItem* nozzle_item = new wgtDeviceNozzleRackNozzleItem(nozzle_box, start_idx); + m_nozzle_items[start_idx] = nozzle_item; + h_sizer->Add(nozzle_item, 0, wxALL, FromDIP(8)); + } + + nozzle_box->SetSizer(h_sizer); + return nozzle_box; +} + +void wgtDeviceNozzleRackArea::UpdateNozzleItems(const std::unordered_map& nozzle_items, + std::shared_ptr nozzle_rack) +{ + for (auto iter : nozzle_items) + { + iter.second->Update(nozzle_rack); + } + + /*update nozzle possition and background*/ + if (nozzle_rack->GetReadingCount() != 0) + { + m_progress_refresh->SetLabel(wxString::Format("(%d/%d)", nozzle_rack->GetReadingIdx(), nozzle_rack->GetReadingCount())); + if(!m_refresh_icon->IsPlaying()) { + m_simple_book->SetSelection(1); + m_refresh_icon->Play(); + } + return; + } else{ + m_refresh_icon->Stop(); + m_simple_book->SetSelection(0); + } + + const DevNozzleRack::RackPos new_pos = nozzle_rack->GetPosition(); + const DevNozzleRack::RackStatus new_status = nozzle_rack->GetStatus(); + if (m_rack_pos != new_pos || m_rack_status != new_status) + { + m_rack_pos = new_pos; + m_rack_status = new_status; + if (m_rack_status == DevNozzleRack::RACK_STATUS_IDLE) + { + m_hotends_sizer->Clear(); + if (m_rack_pos == DevNozzleRack::RACK_POS_B_TOP) + { + m_hotends_sizer->Add(m_brow_nozzles_box); + m_hotends_sizer->Add(m_arow_nozzles_box); + } + else if (m_rack_pos == DevNozzleRack::RACK_POS_A_TOP) + { + m_hotends_sizer->Add(m_arow_nozzles_box); + m_hotends_sizer->Add(m_brow_nozzles_box); + } + else + { + m_hotends_sizer->Add(m_arow_nozzles_box); + m_hotends_sizer->Add(m_brow_nozzles_box); + } + } + } +} + +void wgtDeviceNozzleRackArea::UpdateRackInfo(std::weak_ptr rack) +{ + m_nozzle_rack = rack; + const auto& nozzle_rack = rack.lock(); + if (nozzle_rack) + { + UpdateNozzleItems(m_nozzle_items, nozzle_rack); + m_rack_pos_panel->UpdateRackPos(nozzle_rack); + m_btn_read_all->Enable(nozzle_rack->CtrlCanReadAll()); + } + + if (m_rack_upgrade_dlg && m_rack_upgrade_dlg->IsShown()) + { + m_rack_upgrade_dlg->UpdateRackInfo(nozzle_rack); + } +}; + +void wgtDeviceNozzleRackArea::OnBtnHotendsInfos(wxCommandEvent& evt) +{ + const auto& nozzle_rack = m_nozzle_rack.lock(); + if (nozzle_rack) + { + m_rack_upgrade_dlg = new wgtDeviceNozzleRackUpgradeDlg((wxWindow*)wxGetApp().mainframe, nozzle_rack); + m_rack_upgrade_dlg->ShowModal(); + + delete m_rack_upgrade_dlg; + m_rack_upgrade_dlg = nullptr; + } + + evt.Skip(); +} + +void wgtDeviceNozzleRackArea::OnBtnReadAll(wxCommandEvent& evt) +{ + if (const auto nozzle_rack = m_nozzle_rack.lock()) + { + nozzle_rack->CtrlRackReadAll(true); + } + + evt.Skip(); +} + +void wgtDeviceNozzleRackArea::Rescale() +{ + for (auto item : m_nozzle_items) + { + item.second->Rescale(); + } + + m_rack_pos_panel->Rescale(); + m_btn_hotends_infos->Rescale(); + m_btn_read_all->Rescale(); +} + +static void s_set_bg_style(StaticBox* box, + ScalableButton* btn, + Label* label_row, + Label* label_row_status, + const wxColour& clr) +{ + box->SetBorderColor(clr); + box->SetBackgroundColor(clr); + btn->SetBackgroundColour(clr); + label_row->SetBackgroundColour(clr); + label_row_status->SetBackgroundColour(clr); +} + +void wgtDeviceNozzleRackPos::CreateGui() +{ + // RowA + m_rowup_panel = new StaticBox(this, wxID_ANY); + m_rowup_panel->SetCornerRadius(0); + + wxBoxSizer* rowa_sizer = new wxBoxSizer(wxVERTICAL); + rowa_sizer->AddStretchSpacer(); + m_btn_rowup = new ScalableButton(m_rowup_panel, wxID_ANY, "dev_rack_row_up", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 25); + m_btn_rowup->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); }); + m_btn_rowup->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); }); + m_btn_rowup->Bind(wxEVT_BUTTON, &wgtDeviceNozzleRackPos::OnMoveRackUp, this); + rowa_sizer->Add(m_btn_rowup, 0, wxALIGN_CENTER | wxEXPAND | wxLEFT | wxRIGHT, FromDIP(10)); + + m_label_rowup_status = new Label(m_rowup_panel); + m_label_rowup_status->SetFont(Label::Body_12); + m_label_rowup_status->Show(false); + rowa_sizer->Add(m_label_rowup_status, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + + m_label_rowup = new Label(m_rowup_panel); + m_label_rowup->SetFont(Label::Body_14); + rowa_sizer->Add(m_label_rowup, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + rowa_sizer->AddStretchSpacer(); + + m_rowup_panel->SetSizer(rowa_sizer); + + // homing + m_btn_homing = new ScalableButton(this, wxID_ANY, "dev_rack_home", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 25); + m_btn_homing->SetBackgroundColour(WGT_GREY200); + m_btn_homing->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); }); + m_btn_homing->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); }); + m_btn_homing->Bind(wxEVT_BUTTON, &wgtDeviceNozzleRackPos::OnBtnHomingRack, this); + + // Row B + m_rowbottom_panel = new StaticBox(this, wxID_ANY); + m_rowbottom_panel->SetCornerRadius(0); + + wxBoxSizer* rowb_sizer = new wxBoxSizer(wxVERTICAL); + rowb_sizer->AddStretchSpacer(); + + m_btn_rowbottom_up = new ScalableButton(m_rowbottom_panel, wxID_ANY, "dev_rack_row_up", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, false, 25); + m_btn_rowbottom_up->Bind(wxEVT_BUTTON, &wgtDeviceNozzleRackPos::OnMoveRackDown, this); + m_btn_rowbottom_up->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); }); + m_btn_rowbottom_up->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); }); + rowb_sizer->Add(m_btn_rowbottom_up, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + + m_label_rowbottom_status = new Label(m_rowbottom_panel); + m_label_rowbottom_status->SetFont(Label::Body_12); + m_label_rowbottom_status->Show(false); + rowb_sizer->Add(m_label_rowbottom_status, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + + m_label_rowbottom = new Label(m_rowbottom_panel); + m_label_rowbottom->SetFont(Label::Body_14); + rowb_sizer->Add(m_label_rowbottom, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(10)); + rowb_sizer->AddStretchSpacer(); + + m_rowbottom_panel->SetSizer(rowb_sizer); + + // bg style + SetBackgroundColour(*wxWHITE); + s_set_bg_style(m_rowup_panel, m_btn_rowup, m_label_rowup, m_label_rowup_status, *wxWHITE); + s_set_bg_style(m_rowbottom_panel, m_btn_rowbottom_up, m_label_rowbottom, m_label_rowbottom_status, *wxWHITE); + + // main sizer + wxBoxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(m_rowup_panel, 1, wxALIGN_TOP | wxEXPAND | wxALIGN_CENTER); + main_sizer->Add(m_btn_homing, 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(10)); + main_sizer->Add(m_rowbottom_panel, 1, wxALIGN_BOTTOM | wxEXPAND | wxALIGN_CENTER); + SetSizer(main_sizer); + + SetMinSize(WX_DIP_SIZE(85, -1)); + + Layout(); + Fit(); +} + +void wgtDeviceNozzleRackPos::UpdateRackPos(const std::shared_ptr& rack) +{ + m_rack = rack; + if (rack) + { + UpdateRackPos(rack->GetPosition(), rack->GetStatus(), rack->GetReadingCount() > 0); + } +} + +static void s_show_label(Label* label, const wxString& text) +{ + label->SetLabel(text); + label->Show(); +} + +static void s_show_label(Label* label, const wxString& text, const wxColour& text_color) +{ + label->SetLabel(text); + label->SetForegroundColour(StateColor::darkModeColorFor(text_color)); + label->Show(); +} + +void wgtDeviceNozzleRackPos::UpdateRackPos(DevNozzleRack::RackPos new_pos, + DevNozzleRack::RackStatus new_status, bool is_reading) +{ + // While reading, both rows show a "Running..." status and the move buttons are hidden. + if (is_reading) + { + s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK); + s_show_label(m_label_rowup_status, _L("Running...")); + + s_show_label(m_label_rowbottom, L_RAW_B_STR, *wxBLACK); + s_show_label(m_label_rowbottom_status, _L("Running...")); + + m_btn_rowup->Show(false); + m_btn_rowbottom_up->Show(false); + + m_rack_pos = DevNozzleRack::RACK_POS_UNKNOWN; + m_rack_status = DevNozzleRack::RACK_STATUS_UNKNOWN; + return; + } + + if (new_pos != m_rack_pos || m_rack_status != new_status) + { + m_rack_pos = new_pos; + m_rack_status = new_status; + + if (m_rack_status != DevNozzleRack::RACK_STATUS_IDLE) + { + s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK); + s_show_label(m_label_rowup_status, _L("Running...")); + + s_show_label(m_label_rowbottom, L_RAW_B_STR, *wxBLACK); + s_show_label(m_label_rowbottom_status, _L("Running...")); + + m_btn_rowup->Show(false); + m_btn_rowbottom_up->Show(false); + } + else + { + if (new_pos == DevNozzleRack::RACK_POS_A_TOP) + { + s_show_label(m_label_rowup, L_RAW_A_STR, s_hgreen_clr); + s_show_label(m_label_rowup_status, _L("Raised")); + + m_rowbottom_panel->SetBorderColor(*wxWHITE); + m_rowbottom_panel->SetBackgroundColor(*wxWHITE); + s_show_label(m_label_rowbottom, L_RAW_B_STR, *wxBLACK); + m_label_rowbottom_status->Show(false); + + m_btn_rowup->Show(false); + m_btn_rowbottom_up->Show(true); + } + else if (new_pos == DevNozzleRack::RACK_POS_B_TOP) + { + s_show_label(m_label_rowup, L_RAW_B_STR, s_hgreen_clr); + s_show_label(m_label_rowup_status, _L("Raised")); + s_show_label(m_label_rowbottom, L_RAW_A_STR, *wxBLACK); + m_label_rowbottom_status->Show(false); + + m_btn_rowup->Show(false); + m_btn_rowbottom_up->Show(true); + } + else + { + s_show_label(m_label_rowup, L_RAW_A_STR, *wxBLACK); + m_label_rowup_status->Show(false); + + s_show_label(m_label_rowbottom, L_RAW_B_STR, *wxBLACK); + m_label_rowbottom_status->Show(false); + + m_btn_rowup->Show(true); + m_btn_rowbottom_up->Show(true); + } + } + + Layout(); + Refresh(); + } +}; + +void wgtDeviceNozzleRackPos::OnMoveRackUp(wxCommandEvent& evt) +{ + auto rack = m_rack.lock(); + if (rack) + { + if (m_label_rowup->GetLabel() == L_RAW_A_STR) + { + rack->CtrlRackPosMove(DevNozzleRack::RACK_POS_A_TOP); + } + else if (m_label_rowup->GetLabel() == L_RAW_B_STR) + { + rack->CtrlRackPosMove(DevNozzleRack::RACK_POS_B_TOP); + } + } + evt.Skip(); +} + +void wgtDeviceNozzleRackPos::OnMoveRackDown(wxCommandEvent& evt) +{ + auto rack = m_rack.lock(); + if (rack) + { + if (m_label_rowbottom->GetLabel() == L_RAW_A_STR) + { + rack->CtrlRackPosMove(DevNozzleRack::RACK_POS_A_TOP); + } + else if (m_label_rowbottom->GetLabel() == L_RAW_B_STR) + { + rack->CtrlRackPosMove(DevNozzleRack::RACK_POS_B_TOP); + } + } + evt.Skip(); +} + +void wgtDeviceNozzleRackPos::OnBtnHomingRack(wxCommandEvent& evt) +{ + if (auto rack = m_rack.lock()) + { + rack->CtrlRackPosGoHome(); + } + evt.Skip(); +} + +void wgtDeviceNozzleRackPos::Rescale() +{ + m_btn_rowup->msw_rescale(); + m_btn_rowbottom_up->msw_rescale(); + m_btn_homing->msw_rescale(); +} + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h new file mode 100644 index 0000000000..c4fa464e05 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRack.h @@ -0,0 +1,196 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRack.h +* Description: The Device-tab panel with the toolhead nozzle and the H2C induction hotend rack. +* +* \n class wgtDeviceNozzleRack; // toolhead panel + rack area, side by side +* \n class wgtDeviceNozzleRackToolHead; +* \n class wgtDeviceNozzleRackArea; +* \n class wgtDeviceNozzleRackPos; +* +* The single-nozzle tile class wgtDeviceNozzleRackNozzleItem lives in its own translation unit +* (wgtDeviceNozzleRackNozzleItem.{h,cpp}), so it is included here rather than redeclared. +* The Hotends-Info upgrade dialog (wgtDeviceNozzleRackUpgradeDlg) is intentionally not wired yet +* (see the TODO markers in the .cpp). +//**********************************************************/ + +#pragma once +#include "slic3r/GUI/DeviceCore/DevNozzleRack.h" + +#include "wgtDeviceNozzleRackNozzleItem.h" + +#include "slic3r/GUI/Widgets/StaticBox.hpp" +#include "slic3r/GUI/Widgets/AnimaController.hpp" + +#include +#include +#include +#include +#include + +// Previous definitions +class Button; +class Label; +class ScalableBitmap; +class ScalableButton; +namespace Slic3r +{ + struct DevNozzle; + class DevNozzleRack; +namespace GUI +{ + class wgtDeviceNozzleRackArea; + class wgtDeviceNozzleRackNozzleItem; + class wgtDeviceNozzleRackToolHead; + class wgtDeviceNozzleRackPos; + class wgtDeviceNozzleRackTitle; + class wgtDeviceNozzleRackUpgradeDlg; +} +}; + +namespace Slic3r::GUI +{ +class wgtDeviceNozzleRack : public wxPanel +{ +public: + wgtDeviceNozzleRack(wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL); + ~wgtDeviceNozzleRack() = default; + +public: + void UpdateRackInfo(std::shared_ptr rack); + void Rescale(); + +private: + void CreateGui(); + +private: + std::weak_ptr m_nozzle_rack; + + // GUI + wgtDeviceNozzleRackToolHead* m_toolhead_panel{ nullptr }; + wgtDeviceNozzleRackArea* m_rack_area{ nullptr }; +}; + + +class wgtDeviceNozzleRackToolHead : public wxPanel +{ +public: + wgtDeviceNozzleRackToolHead(wxWindow* parent) : wxPanel(parent) { CreateGui();} + +public: + void UpdateToolHeadInfo(const DevNozzle& extruder_nozzle); + void Rescale(); + +private: + void CreateGui(); + +private: + bool m_extruder_nozzle_exist = false; + std::string m_filament_color; + + // GUI + ScalableBitmap* m_extruder_nozzle_normal = nullptr; + ScalableBitmap* m_extruder_nozzle_empty = nullptr; + wxStaticBitmap* m_toolhead_icon; + + Label* m_nozzle_diamenter_label; + Label* m_nozzle_flowtype_label; +}; + + +class wgtDeviceNozzleRackArea : public wxPanel +{ +public: + wgtDeviceNozzleRackArea(wxWindow* parent) : wxPanel(parent) { CreateGui();} + +public: + void UpdateRackInfo(std::weak_ptr rack); + void Rescale(); + +private: + void CreateGui(); + StaticBox* CreateNozzleBox(const std::vector nozzle_idxes); + wxSizer* CreateRefreshBook(wxPanel* parent); + + // updates + void UpdateNozzleItems(const std::unordered_map& nozzle_items, + std::shared_ptr nozzle_rack); + + // events + void OnBtnHotendsInfos(wxCommandEvent& evt); + void OnBtnReadAll(wxCommandEvent& evt); + +private: + std::weak_ptr m_nozzle_rack; + DevNozzleRack::RackPos m_rack_pos = DevNozzleRack::RACK_POS_UNKNOWN; + DevNozzleRack::RackStatus m_rack_status = DevNozzleRack::RACK_STATUS_UNKNOWN; + + // GUI + wxSimplebook* m_simple_book{ nullptr }; + wxPanel* m_panel_content{ nullptr }; + wxPanel* m_panel_refresh{ nullptr }; + + wgtDeviceNozzleRackTitle* m_title_nozzle_rack; + wxBoxSizer* m_hotends_sizer; + StaticBox* m_arow_nozzles_box; + StaticBox* m_brow_nozzles_box; + std::unordered_map m_nozzle_items; + + wgtDeviceNozzleRackPos* m_rack_pos_panel; + + Button* m_btn_hotends_infos; + Button* m_btn_read_all; + + /* refresh book */ + Label* m_progress_refresh{ nullptr }; + AnimaIcon* m_refresh_icon{ nullptr }; + + // "Hotends Info" upgrade dialog. Owned for its ShowModal lifetime by + // OnBtnHotendsInfos; UpdateRackInfo forwards live device pushes to it while it is shown. + wgtDeviceNozzleRackUpgradeDlg* m_rack_upgrade_dlg = nullptr; +}; + +class wgtDeviceNozzleRackPos : public wxPanel +{ +public: + explicit wgtDeviceNozzleRackPos(wxWindow* parent) : wxPanel(parent) { CreateGui();} + +public: + void UpdateRackPos(const std::shared_ptr& rack); + void Rescale(); + +private: + void CreateGui(); + + void UpdateRackPos(DevNozzleRack::RackPos new_pos, + DevNozzleRack::RackStatus new_status, + bool is_reading); + + // events + void OnMoveRackUp(wxCommandEvent& evt); + void OnMoveRackDown(wxCommandEvent& evt); + void OnBtnHomingRack(wxCommandEvent& evt); + +private: + std::weak_ptr m_rack; + DevNozzleRack::RackPos m_rack_pos = DevNozzleRack::RACK_POS_UNKNOWN; + DevNozzleRack::RackStatus m_rack_status = DevNozzleRack::RACK_STATUS_UNKNOWN; + + // GUI + StaticBox* m_rowup_panel; + ScalableButton* m_btn_rowup; + Label* m_label_rowup_status{ nullptr }; + Label* m_label_rowup{ nullptr }; + + StaticBox* m_rowbottom_panel; + ScalableButton* m_btn_rowbottom_up; + Label* m_label_rowbottom_status{ nullptr }; + Label* m_label_rowbottom{ nullptr }; + + ScalableButton* m_btn_homing{ nullptr }; +}; + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp new file mode 100644 index 0000000000..7dde545f99 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.cpp @@ -0,0 +1,347 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRackNozzleItem.cpp +* Description: One nozzle cell of the H2C hotend rack view. Holds the +* wgtDeviceNozzleRackNozzleItem widget, the SetNozzleBmpColor helper and the layout +* constants it needs. +//**********************************************************/ + +#include "wgtDeviceNozzleRackNozzleItem.h" + +#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h" + +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/MsgDialog.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/wxExtensions.hpp" + +#include "slic3r/GUI/Widgets/Label.hpp" + +#define WX_DIP_SIZE_46 wxSize(FromDIP(46), FromDIP(46)) +#define WX_DIP_SIZE(x, y) wxSize(FromDIP(x), FromDIP(y)) + +#define WGT_RACK_NOZZLE_SIZE WX_DIP_SIZE(88, 100) + +static wxColour s_gray_clr("#B0B0B0"); +static wxColour s_hgreen_clr("#009688"); +static wxColour s_red_clr("#D01B1B"); + +wxDEFINE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent); + +namespace Slic3r::GUI +{ + +static wxBitmap SetNozzleBmpColor(const wxBitmap& bmp, const std::string& color_str) { + if(color_str.empty()) return bmp; + + wxImage img = bmp.ConvertToImage(); + wxColour color("#" + color_str); + + for (int y = 0; y < img.GetHeight(); ++y) { + for (int x = 0; x < img.GetWidth(); ++x) { + unsigned char r = img.GetRed(x, y); + unsigned char g = img.GetGreen(x, y); + unsigned char b = img.GetBlue(x, y); + + /*replace yellow with color*/ + if ( r >= 180 && g >= 180 && b <= 150) { + img.SetRGB(x, y, color.Red(), color.Green(), color.Blue()); + } + } + } + + return wxBitmap(img, -1, bmp.GetScaleFactor()); +} + +wgtDeviceNozzleRackNozzleItem::wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id) + : StaticBox(parent, wxID_ANY), m_nozzle_id(nozzle_id) +{ + CreateGui(); +} + +void wgtDeviceNozzleRackNozzleItem::CreateGui() +{ + // Background + SetCornerRadius(FromDIP(5)); + SetBackgroundColor(*wxWHITE); + + // Top H + wxSizer *top_h_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_nozzle_label_id = new Label(this); + m_nozzle_label_id->SetFont(Label::Body_12); + m_nozzle_label_id->SetBackgroundColour(*wxWHITE); + m_nozzle_label_id->SetLabel(wxString::Format("%d", m_nozzle_id + 1)); + + m_status = NOZZLE_STATUS::NOZZLE_EMPTY; + m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46); + m_nozzle_icon = new wxStaticBitmap(this, wxID_ANY, m_nozzle_empty_image->bmp(), wxDefaultPosition, WX_DIP_SIZE_46); + m_nozzle_icon->SetBackgroundColour(*wxWHITE); + + m_nozzle_selected_bitmap = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, WX_DIP_SIZE(20, 20)); + m_nozzle_selected_bitmap->SetBackgroundColour(*wxWHITE); + + top_h_sizer->Add(m_nozzle_label_id, 0, wxTOP | wxLEFT, FromDIP(6)); + top_h_sizer->AddStretchSpacer(1); + top_h_sizer->Add(m_nozzle_icon, 0, wxTOP, FromDIP(10)); + top_h_sizer->AddStretchSpacer(1); + top_h_sizer->Add(m_nozzle_selected_bitmap, 0, wxTOP | wxRIGHT, FromDIP(2)); + + // Bottom V + wxBoxSizer* bottom_v = new wxBoxSizer(wxVERTICAL); + + wxSizer* label_h_sizer = new wxBoxSizer(wxHORIZONTAL); + m_nozzle_label_1 = new Label(this); + m_nozzle_label_1->SetFont(Label::Body_12); + m_nozzle_label_1->SetBackgroundColour(*wxWHITE); + m_nozzle_label_1->SetLabel(_L("Empty")); + + label_h_sizer->Add(m_nozzle_label_1, 0, wxALIGN_LEFT); + + auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14); + m_nozzle_status_icon = new wxStaticBitmap(this, wxID_ANY, status_icon, wxDefaultPosition, WX_DIP_SIZE(14, 14)); + m_nozzle_status_icon->Bind(wxEVT_LEFT_DOWN, &wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus, this); + m_nozzle_status_icon->Bind(wxEVT_ENTER_WINDOW, [this](auto&) { SetCursor(wxCURSOR_HAND); }); + m_nozzle_status_icon->Bind(wxEVT_LEAVE_WINDOW, [this](auto&) { SetCursor(wxCURSOR_ARROW); }); + m_nozzle_status_icon->SetBackgroundColour(*wxWHITE); + m_nozzle_status_icon->Show(false); + + label_h_sizer->Add(m_nozzle_status_icon, 0, wxALIGN_CENTER | wxLEFT, FromDIP(2)); + bottom_v->Add(label_h_sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP, FromDIP(2)); + + m_nozzle_label_2 = new Label(this); + m_nozzle_label_2->SetFont(Label::Body_12); + m_nozzle_label_2->SetBackgroundColour(*wxWHITE); + bottom_v->Add(m_nozzle_label_2, 0, wxALIGN_CENTER_HORIZONTAL); + + // Main sizer + wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(top_h_sizer, 0, wxEXPAND); + main_sizer->Add(bottom_v, 0, wxALIGN_CENTER_HORIZONTAL); + SetSizer(main_sizer); + + SetMinSize(WGT_RACK_NOZZLE_SIZE); + SetMaxSize(WGT_RACK_NOZZLE_SIZE); + SetSize(WGT_RACK_NOZZLE_SIZE); + Layout(); +}; + +void wgtDeviceNozzleRackNozzleItem::SetSelected(bool selected) +{ + if (!m_enable_select){ + assert(false && "not support select"); + return; + } + + if (m_is_selected != selected) { + m_is_selected = selected; + if (selected) { + if (!m_nozzle_selected_image) { + m_nozzle_selected_image = new ScalableBitmap(this, "dev_rack_nozzle_selected", 20); + } + + m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp()); + SetBorderColor(StateColor::darkModeColorFor(s_hgreen_clr)); + } else { + m_nozzle_selected_bitmap->SetBitmap(wxNullBitmap); + SetBorderColor(StateColor::darkModeColorFor(s_gray_clr)); + } + + Refresh(); + } +} + +void wgtDeviceNozzleRackNozzleItem::Update(const std::shared_ptr rack, bool on_rack /*= true*/) +{ + m_rack = rack; + + if (rack) { + const auto &nozzle_info = on_rack ? rack->GetNozzle(m_nozzle_id) : rack->GetNozzleSystem()->GetExtNozzle(m_nozzle_id); + const wxString &diameter_str = nozzle_info.GetNozzleDiameterStr(); + const wxString &flowtype_str = nozzle_info.GetNozzleFlowTypeStr(); + const std::string &color = nozzle_info.GetFilamentColor(); + + /*check empty first*/ + if (nozzle_info.IsEmpty()) { + SetNozzleStatus(NOZZLE_STATUS::NOZZLE_EMPTY, _L("Empty"), wxEmptyString, color); + } else if (nozzle_info.IsNormal()) { + SetNozzleStatus(NOZZLE_STATUS::NOZZLE_NORMAL, diameter_str, flowtype_str, color); + } else if (nozzle_info.IsAbnormal()) { + SetNozzleStatus(NOZZLE_STATUS::NOZZLE_ERROR, _L("Error"), wxEmptyString, color); + } else if (nozzle_info.IsUnknown()) { + SetNozzleStatus(NOZZLE_STATUS::NOZZLE_UNKNOWN, _L("Unknown"), wxEmptyString, color); + } + } +} + +void wgtDeviceNozzleRackNozzleItem::SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color) +{ + if (m_status != status || m_filament_color != color) + { + m_status = status; + m_filament_color = color; + switch (status) + { + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY: + { + if (!m_nozzle_empty_image) { m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);} + m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp()); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL: + { + if (!m_nozzle_normal_image) { m_nozzle_normal_image = new ScalableBitmap(this, "dev_rack_nozzle_normal", 46);} + m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color)); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN: + { + if (!m_nozzle_unknown_image) { m_nozzle_unknown_image = new ScalableBitmap(this, "dev_rack_nozzle_unknown", 46);} + m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp()); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR: + { + if (!m_nozzle_error_image) { m_nozzle_error_image = new ScalableBitmap(this, "dev_rack_nozzle_error", 46);} + m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp()); + break; + } + default: + { + break; + } + } + + if (status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR) + { + m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(s_red_clr)); + m_nozzle_status_icon->Show(true); + } + else + { + m_nozzle_label_1->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + m_nozzle_status_icon->Show(false); + } + } + + bool update_layout = (m_nozzle_label_1->GetLabel() != str1 || m_nozzle_label_2->GetLabel() != str2); + m_nozzle_label_1->SetLabel(str1); + m_nozzle_label_2->SetLabel(str2); + + if (update_layout) { + Layout(); + } +} + +void wgtDeviceNozzleRackNozzleItem::OnBtnNozzleStatus(wxMouseEvent& evt) +{ + if (m_is_disabled) { + return; + } + + auto rack = m_rack.lock(); + if (rack && m_status == wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR) + { + // Orca: show the abnormal-hotend warning as an informational dialog only, with no + // "Jump to the upgrade page" button, since Orca's MessageDialog and device Upgrade UI + // have no such entry point. Fires when tapping an error-state rack nozzle's status icon. + MessageDialog dlg(nullptr, _L("The hotend is in an abnormal state and currently unavailable. " + "Please go to 'Device -> Upgrade' to upgrade firmware."), _L("Abnormal Hotend"), wxICON_WARNING | wxOK); + dlg.ShowModal(); + } +} + +void wgtDeviceNozzleRackNozzleItem::Rescale() +{ + if (m_nozzle_normal_image) { m_nozzle_normal_image->msw_rescale(); } + if (m_nozzle_empty_image) { m_nozzle_empty_image->msw_rescale(); } + if (m_nozzle_unknown_image) { m_nozzle_unknown_image->msw_rescale(); } + if (m_nozzle_error_image) { m_nozzle_error_image->msw_rescale(); } + + auto status_icon = create_scaled_bitmap("dev_rack_nozzle_error_icon", this, 14); + m_nozzle_status_icon->SetBitmap(status_icon); + m_nozzle_status_icon->Refresh(); + + if (m_nozzle_selected_image) { + m_nozzle_selected_image->msw_rescale(); + if (m_is_selected) { + m_nozzle_selected_bitmap->SetBitmap(m_nozzle_selected_image->bmp()); + } + }; + + switch (m_status) + { + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_EMPTY: + { + m_nozzle_icon->SetBitmap(m_nozzle_empty_image->bmp()); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_NORMAL: + { + m_nozzle_icon->SetBitmap(SetNozzleBmpColor(m_nozzle_normal_image->bmp(), m_filament_color)); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_UNKNOWN: + { + m_nozzle_icon->SetBitmap(m_nozzle_unknown_image->bmp()); + break; + } + case Slic3r::GUI::wgtDeviceNozzleRackNozzleItem::NOZZLE_ERROR: + { + m_nozzle_icon->SetBitmap(m_nozzle_error_image->bmp()); + break; + } + default: + { + break; + } + }; +}; + +void wgtDeviceNozzleRackNozzleItem::EnableSelect() +{ + if (m_enable_select == true) { + return; + }; + + m_enable_select = true; + m_nozzle_icon->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); }); + m_nozzle_label_id->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); }); + m_nozzle_label_1->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); }); + m_nozzle_label_2->Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); }); + Bind(wxEVT_LEFT_DOWN, [this](auto& evt) { OnItemSelected(evt); }); +} + +void wgtDeviceNozzleRackNozzleItem::OnItemSelected(wxMouseEvent& evt) +{ + if (m_enable_select && !m_is_disabled){ + SetSelected(true); + wxCommandEvent command_evt(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, GetId()); + command_evt.SetEventObject(this); + ProcessEvent(command_evt); + } + + evt.Skip(); +} + + +void wgtDeviceNozzleRackNozzleItem::SetDisable(bool disabled) +{ + if (m_is_disabled == disabled) { + return; + } + + m_is_disabled = disabled; + + auto bg_clr = disabled ? StateColor::darkModeColorFor("#E5E7EB") : StateColor::darkModeColorFor(*wxWHITE); + m_nozzle_icon->SetBackgroundColour(bg_clr); + m_nozzle_label_id->SetBackgroundColour(bg_clr); + m_nozzle_label_1->SetBackgroundColour(bg_clr); + m_nozzle_status_icon->SetBackgroundColour(bg_clr); + m_nozzle_label_2->SetBackgroundColour(bg_clr); + m_nozzle_selected_bitmap->SetBackgroundColour(bg_clr); + + SetBackgroundColor(bg_clr); + Refresh(); +}; + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h new file mode 100644 index 0000000000..2ed2b48d66 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h @@ -0,0 +1,99 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRackNozzleItem.h +* Description: One nozzle cell of the H2C hotend rack view. +* +* This header defines only the single-nozzle-cell widget (and the selection event it emits), which +* is the one dependency MultiNozzleSync's HotEndTable needs. The rest of the Device-tab rack panel +* (wgtDeviceNozzleRack / ...Area / ...ToolHead / ...Pos) is not provided here. +//**********************************************************/ + +#pragma once +#include "slic3r/GUI/DeviceCore/DevNozzleRack.h" + +#include "slic3r/GUI/Widgets/StaticBox.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" // complete type required by the inline SetDisplayIdText below + +#include +#include + +// Previous definitions +class ScalableBitmap; +namespace Slic3r +{ + struct DevNozzle; + class DevNozzleRack; +}; + +// Events +wxDECLARE_EVENT(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, wxCommandEvent); + +namespace Slic3r::GUI +{ +class wgtDeviceNozzleRackNozzleItem : public StaticBox +{ +public: + enum NOZZLE_STATUS + { + NOZZLE_EMPTY, + NOZZLE_NORMAL, + NOZZLE_UNKNOWN, + NOZZLE_ERROR + }; + +public: + wgtDeviceNozzleRackNozzleItem(wxWindow* parent, int nozzle_id); + +public: + void Update(const std::shared_ptr rack, bool on_rack = true); // on_rack is false means extruder nozzle + + int GetNozzleId() const { return m_nozzle_id; } + void SetDisplayIdText(const wxString& text) { m_nozzle_label_id->SetLabel(text);}; + + void EnableSelect();; + void SetSelected(bool selected); + bool IsSelected() const { return m_is_selected; } + + bool IsDisabled() const { return m_is_disabled; } + void SetDisable(bool disabled); + + void Rescale(); + +private: + void CreateGui(); + + void SetNozzleStatus(NOZZLE_STATUS status, const wxString& str1, const wxString& str2, const std::string& color); + + void OnBtnNozzleStatus(wxMouseEvent& evt); + void OnItemSelected(wxMouseEvent& evt); + +private: + std::weak_ptr m_rack; + + int m_nozzle_id; // internal id, from 0 to 5 + std::string m_filament_color; + NOZZLE_STATUS m_status = NOZZLE_STATUS::NOZZLE_EMPTY; + + // select + bool m_is_selected = false; + bool m_enable_select = false; + ScalableBitmap* m_nozzle_selected_image{ nullptr }; + wxStaticBitmap* m_nozzle_selected_bitmap{ nullptr }; + + // enable or disable + bool m_is_disabled = false; + + // Images + ScalableBitmap* m_nozzle_normal_image{ nullptr }; + ScalableBitmap* m_nozzle_empty_image{ nullptr }; + ScalableBitmap* m_nozzle_unknown_image{ nullptr }; + ScalableBitmap* m_nozzle_error_image{ nullptr }; + + // GUI + wxStaticBitmap* m_nozzle_icon{ nullptr }; + Label* m_nozzle_label_id { nullptr }; + Label* m_nozzle_label_1{ nullptr }; + wxStaticBitmap* m_nozzle_status_icon = nullptr; + Label* m_nozzle_label_2{ nullptr }; +}; + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp new file mode 100644 index 0000000000..c88bc7c516 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.cpp @@ -0,0 +1,696 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRackUpdate.cpp +* Description: The dialog for reading/upgrading the H2C induction-hotend-rack firmware. +* +* \n class wgtDeviceNozzleRackUpdate +//**********************************************************/ + +#include "wgtDeviceNozzleRackUpdate.h" + +#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h" + +#include "slic3r/GUI/MainFrame.hpp" +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/MsgDialog.hpp" +#include "slic3r/GUI/wxExtensions.hpp" + +#include "slic3r/GUI/Widgets/Button.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" + +#define WX_DIP_SIZE(x, y) wxSize(FromDIP(x), FromDIP(y)) + +static wxColour s_red_clr("#D01B1B"); + +namespace Slic3r::GUI +{ + +wxDEFINE_EVENT(wxEVT_NOZZLE_JUMP_UPGRADE, wxCommandEvent); + +wgtDeviceNozzleRackUpgradeDlg::wgtDeviceNozzleRackUpgradeDlg(wxWindow* parent, const std::shared_ptr rack) + : DPIDialog(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) +{ + m_rack_upgrade_panel = new wgtDeviceNozzleRackUprade(this); + m_rack_upgrade_panel->UpdateRackInfo(rack); + + Bind(wxEVT_NOZZLE_JUMP_UPGRADE, [this](wxCommandEvent&) { + EndModal(wxID_OK); + }); + + auto main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(m_rack_upgrade_panel, 0, wxEXPAND); + SetSizer(main_sizer); + Layout(); + Fit(); + + wxGetApp().UpdateDlgDarkUI(this); +} + +void wgtDeviceNozzleRackUpgradeDlg::UpdateRackInfo(const std::shared_ptr rack) +{ + m_rack_upgrade_panel->UpdateRackInfo(rack); +} + +void wgtDeviceNozzleRackUpgradeDlg::on_dpi_changed(const wxRect& suggested_rect) +{ + m_rack_upgrade_panel->Rescale(); +} + +wgtDeviceNozzleRackUprade::wgtDeviceNozzleRackUprade(wxWindow* parent, + wxWindowID id, + const wxPoint& pos, + const wxSize& size, + long style) + : wxPanel(parent, id, pos, size, style) +{ + CreateGui(); +} + +void wgtDeviceNozzleRackUprade::CreateGui() +{ + SetBackgroundColour(*wxWHITE); + + // Main vertical sizer + auto* main_sizer = new wxBoxSizer(wxVERTICAL); + + // Header: title + buttons + auto* header_sizer = new wxBoxSizer(wxHORIZONTAL); + + // Title label + auto* title_label = new Label(this, _L("Hotends Info")); + title_label->SetFont(Label::Head_14); + header_sizer->Add(title_label, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20)); + + // Spacer + header_sizer->AddStretchSpacer(); + main_sizer->Add(header_sizer, 0, wxEXPAND | wxTOP | wxRIGHT, FromDIP(10)); + + // "Nozzles" + m_extruder_nozzle_item = new wgtDeviceNozzleRackHotendUpdate(this, "R"); + m_extruder_nozzle_item->UpdateColourStyle(wxColour("#F8F8F8")); + m_extruder_nozzle_item->SetExtruderNozzleId(MAIN_EXTRUDER_ID); + + main_sizer->Add(m_extruder_nozzle_item, 0, wxEXPAND | wxALL, FromDIP(12)); + for (int id = 0; id < 6; id ++) + { + auto item = new wgtDeviceNozzleRackHotendUpdate(this, wxString::Format("%d", id + 1)); + item->SetRackNozzleId(id); + m_nozzle_items[id] = item; + + main_sizer->Add(item, 0, wxEXPAND | wxALL, FromDIP(12)); + if (id < 5) + { + wxPanel* separator = new wxPanel(this); + separator->SetMaxSize(wxSize(-1, FromDIP(1))); + separator->SetMinSize(wxSize(-1, FromDIP(1))); + separator->SetBackgroundColour(wxColour(238, 238, 238));// Orca: grey300 spelled out as a literal RGB, since Orca has no equivalent grey-300 colour macro + main_sizer->Add(separator, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(12)); + } + } + + main_sizer->AddSpacer(FromDIP(20)); + + // Set sizer + this->SetSizer(main_sizer); + this->Layout(); +} + +void wgtDeviceNozzleRackUprade::UpdateRackInfo(const std::shared_ptr rack) +{ + m_nozzle_rack = rack; + if (!rack) { return;} + + // update the nozzles + m_extruder_nozzle_item->UpdateExtruderNozzleInfo(rack); + for (auto iter : m_nozzle_items) + { + iter.second->UpdateRackNozzleInfo(rack); + } + + // update layout + Layout(); +} + +void wgtDeviceNozzleRackUprade::OnBtnReadAll(wxCommandEvent& e) +{ + if (auto rack = m_nozzle_rack.lock()) + { + rack->CtrlRackReadAll(true); + } +} + +void wgtDeviceNozzleRackUprade::Rescale() +{ + m_extruder_nozzle_item->Rescale(); + for (auto& iter : m_nozzle_items) + { + iter.second->Rescale(); + } +} + +#define WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG *wxWHITE +wgtDeviceNozzleRackHotendUpdate::wgtDeviceNozzleRackHotendUpdate(wxWindow* parent, const wxString& idx_text) + : StaticBox(parent, wxID_ANY) +{ + CreateGui(); + + m_idx_label->SetLabel(idx_text); +} + +void wgtDeviceNozzleRackHotendUpdate::CreateGui() +{ + SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + SetBorderColor(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + SetCornerRadius(0); + + //load nozzle hs image + for (int i = 1; i <= 4; i++) + { + auto normalImage = new ScalableBitmap(this, "Nozzle_HS_01_0" + std::to_string(i * 2), 46); + auto bigImage = new ScalableBitmap(this, "Big_Nozzle_HS_01_0" + std::to_string(i * 2), 216); + nozzle_hs.push_back({normalImage, bigImage}); + } + for (int i = 2; i <= 4; i++) + { + auto normalImage = new ScalableBitmap(this, "Nozzle_HH_01_0" + std::to_string(i * 2), 46); + auto bigImage = new ScalableBitmap(this, "Big_Nozzle_HH_01_0" + std::to_string(i * 2), 216); + nozzle_hh.push_back({normalImage, bigImage}); + } + + auto* content_sizer = new wxBoxSizer(wxHORIZONTAL); + + // Index + m_idx_label = new Label(this); + m_idx_label->SetFont(Label::Head_14); + m_idx_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + content_sizer->Add(m_idx_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(25)); + + // Icon + wxPanel* imagePanel = new wxPanel(this); + imagePanel->SetMaxSize(WX_DIP_SIZE(46, -1)); + imagePanel->SetMinSize(WX_DIP_SIZE(46, -1)); + imagePanel->SetSize(wxSize(FromDIP(46), FromDIP(-1))); + wxBoxSizer* panelSizer = new wxBoxSizer(wxVERTICAL); + imagePanel->SetSizer(panelSizer); + + m_nozzle_empty_image = new ScalableBitmap(imagePanel, "dev_rack_nozzle_empty", 46); + m_icon_bitmap = new wxStaticBitmap(imagePanel, wxID_ANY, m_nozzle_empty_image->bmp()); + panelSizer->Add(m_icon_bitmap, 0, wxALIGN_CENTER); + content_sizer->Add(imagePanel, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(25)); + m_icon_bitmap->Bind(wxEVT_ENTER_WINDOW, &wgtDeviceNozzleRackHotendUpdate::OnBitmapHoverEnter, this); + m_icon_bitmap->Bind(wxEVT_LEAVE_WINDOW, &wgtDeviceNozzleRackHotendUpdate::OnBitmapHoverLeave, this); + + // Diameter/type (vertical) + wxPanel* type_panel = new wxPanel(this); + auto* main_type_sizer = new wxBoxSizer(wxVERTICAL); + auto* type_sizer_row_1 = new wxBoxSizer(wxHORIZONTAL); + auto* type_sizer_row_2 = new wxBoxSizer(wxHORIZONTAL); + + m_material_label = new Label(type_panel); + m_material_label->SetFont(Label::Body_12); + m_material_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + m_colour_box = new StaticBox(type_panel); + m_colour_box->SetMaxSize(WX_DIP_SIZE(16, 16)); + m_colour_box->SetMinSize(WX_DIP_SIZE(16, 16)); + m_colour_box->SetCornerRadius(FromDIP(2)); + m_colour_box->SetSize(wxSize(FromDIP(16), FromDIP(16))); + + type_sizer_row_1->Add(m_colour_box, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT); + type_sizer_row_1->AddStretchSpacer(1); + type_sizer_row_1->Add(m_material_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2)); + + m_diameter_label = new Label(type_panel); + m_diameter_label->SetFont(Label::Body_12); + m_diameter_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + m_flowtype_label = new Label(type_panel); + m_flowtype_label->SetFont(Label::Body_12); + m_flowtype_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + m_type_label = new Label(type_panel); + m_type_label->SetFont(Label::Body_12); + m_type_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + type_sizer_row_2->Add(m_diameter_label, 0, wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT ); + type_sizer_row_2->Add(m_flowtype_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2)); + type_sizer_row_2->Add(m_type_label, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2)); + + main_type_sizer->Add(type_sizer_row_1, 0, wxALIGN_LEFT); + main_type_sizer->Add(type_sizer_row_2, 1, wxALIGN_LEFT | wxEXPAND | wxTOP, FromDIP(4)); + type_panel->SetSizer(main_type_sizer); + type_panel->SetMaxSize(WX_DIP_SIZE(160, 40)); + type_panel->SetMinSize(WX_DIP_SIZE(160, 40)); + type_panel->SetSize(WX_DIP_SIZE(160, 40)); + + content_sizer->Add(type_panel, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(12)); + + // SN and version (vertical) + wxPanel* info_panel = new wxPanel(this); + auto* info_sizer = new wxBoxSizer(wxVERTICAL); + m_sn_label = new Label(info_panel); + m_sn_label->SetFont(Label::Body_12); + m_sn_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + auto* version_h_sizer = new wxBoxSizer(wxHORIZONTAL); + m_version_label = new Label(info_panel); + m_version_label->SetFont(Label::Body_12); + m_version_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + m_version_new_label = new Label(info_panel); + m_version_new_label->SetFont(Label::Body_12); + m_version_new_label->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + m_version_new_label->SetForegroundColour(wxColour(0, 168, 84)); // Green + + version_h_sizer->Add(m_version_label, 0, wxALIGN_CENTER_VERTICAL); + version_h_sizer->Add(m_version_new_label, 0, wxALIGN_CENTER_VERTICAL); + info_sizer->Add(m_sn_label, 0, wxALIGN_LEFT); + info_sizer->Add(version_h_sizer, 0, wxALIGN_LEFT | wxTOP, FromDIP(4)); + info_panel->SetSizer(info_sizer); + info_panel->SetMaxSize(WX_DIP_SIZE(183, 40)); + info_panel->SetMinSize(WX_DIP_SIZE(183, 40)); + info_panel->SetSize(WX_DIP_SIZE(183, 40)); + + //Used Time + m_used_time = new Label(this); + m_used_time->SetFont(Label::Body_12); + m_used_time->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + + m_refresh_icon = new ScalableBitmap(this, "refresh_printer", 12); + m_error_icon = new ScalableBitmap(this, "error", 14); + m_status_bitmap = new wxStaticBitmap(this, wxID_ANY, m_refresh_icon->bmp()); + m_status_bitmap->Bind(wxEVT_LEFT_UP, &wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick, this); + + std::vector list{"refresh_nozzle_1", "refresh_nozzle_2", "refresh_nozzle_3", "refresh_nozzle_4"}; + // Orca: AnimaIcon has no per-instance size argument (it fixes 25px internally), so no size is + // passed here. + m_refreshing_icon = new AnimaIcon(this, wxID_ANY, list, "refresh_nozzle", 100); + m_refreshing_icon->Show(false); + + + m_status_label = new Label(this); + m_status_label->SetFont(Label::Body_12); + + content_sizer->Add(info_panel, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20)); + content_sizer->Add(m_used_time, 1, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20)); + content_sizer->Add(m_status_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(20)); + content_sizer->Add(m_status_bitmap, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2)); + content_sizer->Add(m_refreshing_icon, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(2)); + content_sizer->AddSpacer(FromDIP(25)); + + auto* main_sizer = new wxBoxSizer(wxHORIZONTAL); + main_sizer->Add(content_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(10)); + + SetSizer(main_sizer); + Layout(); +} + +void wgtDeviceNozzleRackHotendUpdate::OnStatusIconClick(wxMouseEvent& event) +{ + if (m_status_label->GetLabel() == _L("Refresh")) + { + m_status_label->SetForegroundColour(wxColour("#A3A3A3")); + m_status_label->SetLabel(_L("Refreshing")); + m_status_bitmap->Show(false); + if(!m_refreshing_icon->IsPlaying()) + { + m_refreshing_icon->Play(); + m_refreshing_icon->Show(); + } + if (auto shared = m_nozzle_rack.lock()) + { + shared->CrtlRackReadNozzle(m_rack_nozzle_id); + } + Layout(); + } + + if (m_status_label->GetLabel() == _L("Error") /*&& m_nozzle_status == NOZZLE_STATUS_ABNORMAL*/) + { + if (auto shared = m_nozzle_rack.lock()) + { + MessageDialog dlg(nullptr, _L("Hotend status abnormal, unavailable at present. Please upgrade the firmware" + " and try again."), _L("Update"), wxICON_WARNING); + dlg.AddButton(wxID_CANCEL, _L("Cancel"), false); + dlg.AddButton(wxID_OK,_L("Jump to the upgrade page"), true); + + if (dlg.ShowModal() == wxID_OK) + { + wxGetApp().mainframe->m_monitor->jump_to_Upgrade(); + + wxCommandEvent evt(wxEVT_NOZZLE_JUMP_UPGRADE, GetId()); + evt.SetEventObject(this); + wxWindow* target = GetParent(); + if (target) + { + target = target->GetParent(); + if (target) + { + wxPostEvent(target, evt); + } + } + }; + } + } +} + +void wgtDeviceNozzleRackHotendUpdate::OnBitmapHoverEnter(wxMouseEvent& event) +{ + int scaledW = FromDIP(240); + int scaledH = FromDIP(240); + + ScalableBitmap* scaledBmp{nullptr}; + if (m_nozzle_status == NOZZLE_STATUS_EMPTY || m_nozzle_status == NOZZLE_STATUS_UNKNOWN || !findNozzleImage) + { + if (!m_scaled_nozzle_empty_image) {m_scaled_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 216);} + + scaledBmp = m_scaled_nozzle_empty_image; + } + else + { + scaledBmp = m_scaled_nozzle_image; + } + + m_hoverFrame = new wxFrame(nullptr, wxID_ANY, "", + wxDefaultPosition, wxDefaultSize, + wxFRAME_NO_TASKBAR | wxBORDER_NONE | wxTRANSPARENT_WINDOW); + m_hoverFrame->SetBackgroundColour(WGT_DEVICE_NOZZLE_RACK_HOTEND_UPDATE_DEFAULT_BG); + m_hoverFrame->SetSize(scaledW, scaledH); + wxBoxSizer* frameSizer = new wxBoxSizer(wxVERTICAL); + m_hoverFrame->SetSizer(frameSizer); + + wxStaticBitmap* hoverBmp = new wxStaticBitmap(m_hoverFrame, wxID_ANY, scaledBmp->bmp()); + frameSizer->Add(hoverBmp, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxBOTTOM, FromDIP(12)); + + wxPoint mousePos = wxGetMousePosition(); + m_hoverFrame->SetPosition(wxPoint(mousePos.x + 10, mousePos.y)); + m_hoverFrame->Layout(); + m_hoverFrame->Show(true); + + event.Skip(); +} + +void wgtDeviceNozzleRackHotendUpdate::OnBitmapHoverLeave(wxMouseEvent& event) +{ + if (m_hoverFrame) + { + m_hoverFrame->Destroy(); + m_hoverFrame = nullptr; + } + event.Skip(); +} + +void wgtDeviceNozzleRackHotendUpdate::updateNozzleImage(const DevNozzle& nozzle) +{ + if (m_nozzle_status == NOZZLE_STATUS_UNKNOWN || m_nozzle_status == NOZZLE_STATUS_EMPTY) + { + if (!m_nozzle_empty_image) {m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);} + m_icon_bitmap->SetBitmap(m_nozzle_empty_image->bmp()); + m_icon_bitmap->Refresh(); + return; + } + findNozzleImage = false; + int index = -1; + switch (nozzle.GetNozzleDiameterType()) { + case NOZZLE_DIAMETER_0_2: index = 0; break; + case NOZZLE_DIAMETER_0_4: index = 1; break; + case NOZZLE_DIAMETER_0_6: index = 2; break; + case NOZZLE_DIAMETER_0_8: index = 3; break; + default: index = -1; break; + } + NozzleType nozzleType = nozzle.GetNozzleType(); + if (nozzleType == ntHardenedSteel || nozzleType == ntStainlessSteel) + { + if (nozzle.GetNozzleFlowType() == H_FLOW && index >= 1) + { + m_nozzle_image = nozzle_hh[index - 1][0]; + m_icon_bitmap->SetBitmap(m_nozzle_image->bmp()); + m_scaled_nozzle_image = nozzle_hh[index - 1][1]; + findNozzleImage = true; + } + else if (nozzle.GetNozzleFlowType() == S_FLOW && index >= 0) + { + m_nozzle_image = nozzle_hs[index][0]; + m_icon_bitmap->SetBitmap(m_nozzle_image->bmp()); + m_scaled_nozzle_image = nozzle_hs[index][1]; + findNozzleImage = true; + } + } + if (!findNozzleImage) + { + if (!m_nozzle_empty_image) {m_nozzle_empty_image = new ScalableBitmap(this, "dev_rack_nozzle_empty", 46);} + m_icon_bitmap->SetBitmap(m_nozzle_empty_image->bmp()); + } + m_icon_bitmap->Refresh(); +} + +void wgtDeviceNozzleRackHotendUpdate::UpdateColourStyle(const wxColour& clr) +{ + SetBackgroundColour(clr); + SetBorderColor(clr); + + // BFS: Update all children background color + auto children = GetChildren(); + while (!children.IsEmpty()) + { + auto win = children.front(); + children.pop_front(); + win->SetBackgroundColour(clr); + + for (auto child : win->GetChildren()) + { + children.push_back(child); + } + } +} + +void wgtDeviceNozzleRackHotendUpdate::UpdateExtruderNozzleInfo(const std::shared_ptr rack) +{ + m_nozzle_rack = rack; + if (rack) + { + DevNozzleSystem* nozzle_system = rack->GetNozzleSystem(); + if (nozzle_system) + { + UpdateInfo(nozzle_system->GetExtNozzle(m_ext_nozzle_id)); + } + } +} + +void wgtDeviceNozzleRackHotendUpdate::UpdateRackNozzleInfo(const std::shared_ptr rack) +{ + m_nozzle_rack = rack; + if (rack) + { + UpdateInfo(rack->GetNozzle(m_rack_nozzle_id)); + } +} + +void wgtDeviceNozzleRackHotendUpdate::UpdateInfo(const DevNozzle& nozzle) +{ + /*update nozzle possition and background*/ + if (auto share = m_nozzle_rack.lock()) + { + // if (share->GetReadingCount() > 0 && m_status_label->IsShown()) + if (share->GetReadingCount() > 0 && m_status_label->IsShown() && m_status_label->GetLabel() == _L("Refreshing")) + { + m_refreshing_icon->Play(); + m_refreshing_icon->Show(); + m_nozzle_status = NOZZLE_STATUS_DC; + return; + } + else + { + m_refreshing_icon->Stop(); + m_refreshing_icon->Show(false); + } + } + + wxString filamentDisplayName{}; + for (auto iter = GUI::wxGetApp().preset_bundle->filaments.begin(); iter != GUI::wxGetApp().preset_bundle->filaments.end(); ++iter) + { + const Preset& filament_preset = *iter; + // const auto& config = filament_preset.config; + if (filament_preset.filament_id == nozzle.GetFilamentId()) + { + filamentDisplayName = wxString(filament_preset.alias); + } + } + + if (nozzle.IsEmpty() && m_nozzle_status != NOZZLE_STATUS_EMPTY) + { + m_nozzle_status = NOZZLE_STATUS_EMPTY; + + m_material_label->Show(false); + m_colour_box->Show(false); + + m_diameter_label->Show(false); + m_flowtype_label->Show(false); + m_type_label->SetLabel(_L("Empty")); + m_type_label->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + m_sn_label->Show(false); + m_version_label->Show(false); + m_version_new_label->Show(false); + + updateNozzleImage(nozzle); + + m_used_time->Show(false); + m_status_label->Show(false); + m_status_bitmap->Show(false); + + } + else if (nozzle.IsNormal() && m_nozzle_status != NOZZLE_STATUS_NORMAL) + { + m_nozzle_status = NOZZLE_STATUS_NORMAL; + + m_material_label->SetLabel(filamentDisplayName); + m_colour_box->SetBackgroundColour(wxColour("#" + nozzle.GetFilamentColor())); + m_colour_box->SetBorderColor(wxColour("#" + nozzle.GetFilamentColor())); + m_material_label->Show(true); + m_colour_box->Show(true); + + m_diameter_label->Show(true); + m_flowtype_label->Show(true); + m_diameter_label->SetLabel(nozzle.GetNozzleDiameterStr()); + m_flowtype_label->SetLabel(nozzle.GetNozzleFlowTypeStr()); + m_type_label->SetLabel(nozzle.GetNozzleTypeStr()); + m_type_label->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + m_sn_label->Show(true); + m_version_label->Show(true); + + updateNozzleImage(nozzle); + + m_used_time->Show(true); + m_status_label->Show(false); + m_status_bitmap->Show(false); + } + else if (nozzle.IsAbnormal() && m_nozzle_status != NOZZLE_STATUS_ABNORMAL) + { + m_nozzle_status = NOZZLE_STATUS_ABNORMAL; + + m_material_label->SetLabel(filamentDisplayName); + m_colour_box->SetBackgroundColour(wxColour("#" + nozzle.GetFilamentColor())); + m_colour_box->SetBorderColor(wxColour("#" + nozzle.GetFilamentColor())); + m_material_label->Show(true); + m_colour_box->Show(true); + + m_diameter_label->Show(true); + m_flowtype_label->Show(true); + m_diameter_label->SetLabel(nozzle.GetNozzleDiameterStr()); + m_flowtype_label->SetLabel(nozzle.GetNozzleFlowTypeStr()); + m_type_label->SetLabel(nozzle.GetNozzleTypeStr()); + m_type_label->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + updateNozzleImage(nozzle); + + m_status_label->Show(true); + m_status_bitmap->Show(true); + m_status_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#E14747"))); + m_status_label->SetLabel(_L("Error")); + m_status_bitmap->SetBitmap(m_error_icon->bmp()); + m_status_bitmap->Refresh(); + } + else if (nozzle.IsUnknown() && m_nozzle_status != NOZZLE_STATUS_UNKNOWN) + { + m_nozzle_status = NOZZLE_STATUS_UNKNOWN; + + m_colour_box->Show(false); + m_material_label->SetLabel(wxString("--")); + m_material_label->Show(true); + + m_diameter_label->Show(false); + m_flowtype_label->Show(false); + m_type_label->SetLabel(_L("Unknown")); + m_type_label->SetForegroundColour(StateColor::darkModeColorFor(*wxBLACK)); + + m_sn_label->Show(true); + m_version_label->Show(true); + + updateNozzleImage(nozzle); + + m_used_time->Show(true); + m_status_label->Show(true); + m_status_bitmap->Show(true); + m_status_label->SetForegroundColour(wxColour("#009688")); + m_status_label->SetLabel(_L("Refresh")); + m_status_bitmap->SetBitmap(m_refresh_icon->bmp()); + m_status_bitmap->Refresh(); + } + + // Update firmware info + const DevFirmwareVersionInfo& firmware = nozzle.GetFirmwareInfo(); + if (nozzle.IsUnknown()) + { + m_sn_label->SetLabel(wxString::Format("%s: --", _L("SN"))); + m_version_label->SetLabel(wxString::Format("%s: --", _L("Version"))); + m_version_new_label->Show(false); + } + if (nozzle.IsNormal() || nozzle.IsAbnormal()) + { + if (firmware.isValid()) + { + m_sn_label->SetLabel(wxString::Format("%s: %s", _L("SN"), firmware.sn)); + + if (!firmware.sw_new_ver.empty() && firmware.sw_new_ver != firmware.sw_ver) + { + m_version_label->SetLabel(wxString::Format("%s: %s > ", _L("Version"), firmware.sw_ver)); + m_version_new_label->SetLabel(wxString::Format("%s", firmware.sw_new_ver)); + m_version_new_label->Show(true); + } + else + { + m_version_label->SetLabel(wxString::Format("%s:%s", _L("Version"), firmware.sw_ver)); + m_version_new_label->Show(false); + } + } + else + { + m_sn_label->SetLabel(wxString::Format("%s: --", _L("SN"))); + m_version_label->SetLabel(wxString::Format("%s: --", _L("Version"))); + m_version_new_label->Show(false); + } + } + + if (!nozzle.IsEmpty()) + { + if (nozzle.IsUnknown()) + { + m_used_time->SetLabel(wxString::Format(_L("Used Time: %s"), "--h")); + } + else + { + // Update used time + int usedSeconds = nozzle.GetNozzlePrintTime(); + if (usedSeconds < 60) + { + m_used_time->SetLabel(wxString::Format(_L("Used Time: %s"), "0 h")); + } + else + { + int printTime = (usedSeconds >= 3600 ? usedSeconds / 3600 : usedSeconds / 60); + std::string printTimeStr = (usedSeconds >= 3600 ? std::to_string(printTime) + " h" : std::to_string(printTime) + " min"); + m_used_time->SetLabel(wxString::Format(_L("Used Time: %s"), printTimeStr.c_str())); + } + } + + } +} + +void wgtDeviceNozzleRackHotendUpdate::Rescale() +{ + // update images + if (m_nozzle_image) { m_nozzle_image->msw_rescale(); } + if (m_nozzle_empty_image) { m_nozzle_empty_image->msw_rescale(); } + if (m_nozzle_status == NOZZLE_STATUS_EMPTY && m_nozzle_empty_image) + { + m_icon_bitmap->SetBitmap(m_nozzle_empty_image->bmp()); + } + else if (m_nozzle_image != nullptr) + { + m_icon_bitmap->SetBitmap(m_nozzle_image->bmp()); + } + m_icon_bitmap->Refresh(); +} + +};// namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h new file mode 100644 index 0000000000..49df93c2c7 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h @@ -0,0 +1,175 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleRackUpdate.h +* Description: The dialog for reading/upgrading the H2C induction-hotend-rack firmware. +* +* \n class wgtDeviceNozzleRackUpgradeDlg; // modal "Hotends Info" dialog +* \n class wgtDeviceNozzleRackUprade; // the dialog's content panel (per-nozzle rows) +* \n class wgtDeviceNozzleRackHotendUpdate; // one hotend row (toolhead "R" + rack 1..6) +* +* Opened from the Device-tab rack panel's "Hotends Info" button (wgtDeviceNozzleRack.cpp) and +* reused by the Device->Upgrade page "Hotends on Rack" section +* (UpgradePanel::createNozzleRackWidgets). All device data + MQTT commands live in +* DevNozzleRack / DevNozzleSystem, so this is additive GUI gated behind +* DevNozzleRack::IsSupported() — dormant for every non-rack printer. +//**********************************************************/ + +#pragma once +#include "slic3r/GUI/DeviceCore/DevNozzleRack.h" + +#include "slic3r/GUI/GUI_Utils.hpp" +#include "slic3r/GUI/Widgets/StaticBox.hpp" +#include "slic3r/GUI/Widgets/AnimaController.hpp" + +#include +#include +#include +#include + +// Previous definitions +class Button; +class Label; +class ScalableBitmap; +class ScalableButton; +namespace Slic3r +{ + struct DevNozzle; + class DevNozzleRack; +namespace GUI +{ + class wgtDeviceNozzleRackUprade; + class wgtDeviceNozzleRackHotendUpdate; +} +}; + +namespace Slic3r::GUI +{ +class wgtDeviceNozzleRackUpgradeDlg : public DPIDialog +{ +public: + wgtDeviceNozzleRackUpgradeDlg(wxWindow* parent, const std::shared_ptr rack); + +public: + void UpdateRackInfo(const std::shared_ptr rack); + +public: + void on_dpi_changed(const wxRect& suggested_rect) override; + +private: + wgtDeviceNozzleRackUprade* m_rack_upgrade_panel; +}; + + +class wgtDeviceNozzleRackUprade : public wxPanel +{ +public: + wgtDeviceNozzleRackUprade(wxWindow* parent, + wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTAB_TRAVERSAL); + ~wgtDeviceNozzleRackUprade() = default; + +public: + void UpdateRackInfo(const std::shared_ptr rack); + void Rescale(); + +private: + void CreateGui(); + + void OnBtnReadAll(wxCommandEvent& e); + +private: + std::weak_ptr m_nozzle_rack; + + // GUI + wgtDeviceNozzleRackHotendUpdate* m_extruder_nozzle_item; + std::unordered_map m_nozzle_items; +}; + +// Using for rack nozzle id or extruder nozzle id +class wgtDeviceNozzleRackHotendUpdate : public StaticBox +{ +public: + wgtDeviceNozzleRackHotendUpdate(wxWindow* parent, const wxString& idx_text); + +public: + // Color + void UpdateColourStyle(const wxColour& clr); + + // extruder nozzle + int GetExtruderNozzleId() const { return m_ext_nozzle_id; } + void SetExtruderNozzleId(int ext_nozzle_id) { m_ext_nozzle_id = ext_nozzle_id; } + void UpdateExtruderNozzleInfo(const std::shared_ptr rack); + + // rack nozzle + void SetRackNozzleId(int rack_nozzle_id) { m_rack_nozzle_id = rack_nozzle_id; } + int GetRackNozzleId() const { return m_rack_nozzle_id; } + void UpdateRackNozzleInfo(const std::shared_ptr rack); + + // gui + void Rescale(); + +private: + void CreateGui(); + + void UpdateInfo(const DevNozzle& nozzle); + + void OnBitmapHoverEnter(wxMouseEvent& event); + void OnBitmapHoverLeave(wxMouseEvent& event); + void OnStatusIconClick(wxMouseEvent& event); + void updateNozzleImage(const DevNozzle& nozzle); + +private: + enum NozzleStatus : int + { + NOZZLE_STATUS_DC = -1, + NOZZLE_STATUS_EMPTY, + NOZZLE_STATUS_NORMAL, + NOZZLE_STATUS_ABNORMAL, + NOZZLE_STATUS_UNKNOWN, + }; + +private: + int m_ext_nozzle_id = -1; + int m_rack_nozzle_id = -1; + bool m_isRefreshFinish = false; + bool findNozzleImage = false; + + NozzleStatus m_nozzle_status = NOZZLE_STATUS_DC; + std::weak_ptr m_nozzle_rack; + + std::vector> nozzle_hs; + std::vector> nozzle_hh; + // GUI + ScalableBitmap* m_nozzle_image = nullptr; + ScalableBitmap* m_nozzle_empty_image = nullptr; + ScalableBitmap* m_scaled_nozzle_image = nullptr; + ScalableBitmap* m_scaled_nozzle_empty_image = nullptr; + ScalableBitmap* m_refresh_icon = nullptr; + AnimaIcon* m_refreshing_icon = nullptr; + ScalableBitmap* m_error_icon = nullptr; + + Label* m_idx_label; + wxStaticBitmap* m_icon_bitmap{ nullptr }; + wxStaticBitmap* m_status_bitmap{ nullptr }; + + Label* m_material_label{ nullptr }; + StaticBox* m_colour_box{ nullptr }; + wxFrame* m_hoverFrame{ nullptr }; + + Label* m_status_label{ nullptr }; + Label* m_used_time{ nullptr }; + + Label* m_diameter_label; + Label* m_flowtype_label; + Label* m_type_label; + ScalableButton* m_error_button{ nullptr }; + + Label* m_sn_label; + Label* m_version_label; + Label* m_version_new_label; +}; + +wxDECLARE_EVENT(wxEVT_NOZZLE_JUMP_UPGRADE, wxCommandEvent); + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp new file mode 100644 index 0000000000..dda471ac23 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.cpp @@ -0,0 +1,289 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleSelect.cpp +* Description: The panel to select nozzle +* +* \n class wgtDeviceNozzleSelect; +//**********************************************************/ + +#include "wgtDeviceNozzleSelect.h" +#include "wgtDeviceNozzleRackNozzleItem.h" // the nozzle-item widget lives in its own header + +#include "slic3r/GUI/I18N.hpp" +#include "slic3r/GUI/DeviceTab/wgtMsgBox.h" +#include "slic3r/GUI/Widgets/Label.hpp" + +static wxColour s_gray_clr("#B0B0B0"); +static wxColour s_hgreen_clr("#009688"); +static wxColour s_red_clr("#D01B1B"); + +static std::vector a_nozzle_seq = {16, 18, 20, 17, 19, 21}; + +wxDEFINE_EVENT(EVT_NOZZLE_SELECT_CHANGED, wxCommandEvent); +wxDEFINE_EVENT(EVT_NOZZLE_SELECT_CLICKED, wxCommandEvent); + +namespace Slic3r::GUI { + +wgtDeviceNozzleRackSelect::wgtDeviceNozzleRackSelect(wxWindow *parent) : wxPanel(parent, wxID_ANY) { CreateGui(); } + +static wxPanel* s_create_title(wxWindow *parent, const wxString& text) +{ + wxPanel *panel = new wxPanel(parent, wxID_ANY); + + auto title = new Label(panel, text); + title->SetFont(::Label::Body_13); + title->SetBackgroundColour(*wxWHITE); + title->SetForegroundColour(0x909090); + + auto split_line = new wxPanel(panel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); + split_line->SetBackgroundColour(0xeeeeee); + split_line->SetMinSize(wxSize(-1, 1)); + split_line->SetMaxSize(wxSize(-1, 1)); + + wxBoxSizer *sizer = new wxBoxSizer(wxHORIZONTAL); + sizer->Add(0, 0, 0, wxEXPAND, 0); + sizer->Add(title, 0, wxALIGN_CENTER, 0); + sizer->Add(split_line, 1, wxALIGN_CENTER_VERTICAL | wxEXPAND, 0); + panel->SetSizer(sizer); + panel->Layout(); + return panel; +} + +void wgtDeviceNozzleRackSelect::CreateGui() +{ + wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); + + wxColour tip_bg_clr("#FFF0E0"); + m_title_tips_dynamic = new wgtMsgBox(this); + m_title_tips_dynamic->SetBackgroundColour(tip_bg_clr); + m_title_tips_dynamic->SetBorderColor(wxColour("#FF6F00")); + m_title_tips_dynamic->SetCornerRadius(1); + m_title_tips_dynamic->SetBorderWidth(1); + auto text_label = m_title_tips_dynamic->GetTextLabel(); + text_label->SetFont(::Label::Body_12); + text_label->SetForegroundColour("#FF6F00"); + text_label->SetBackgroundColour(tip_bg_clr); + text_label->SetLabel(_L("Dynamic nozzles are allocated on the current plate. Picking hotend is not supported.")); + text_label->Wrap(FromDIP(300)); + text_label->Fit(); + m_title_tips_dynamic->Layout(); + m_title_tips_dynamic->Refresh(); + + // nozzles + wxGridSizer *nozzle_sizer = new wxGridSizer(2, 3, FromDIP(10), FromDIP(10)); + for (auto idx : a_nozzle_seq) { + wgtDeviceNozzleRackNozzleItem *nozzle_item = new wgtDeviceNozzleRackNozzleItem(this, idx - 16); + nozzle_item->EnableSelect(); + nozzle_item->Bind(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, &wgtDeviceNozzleRackSelect::OnNozzleItemSelected, this); + m_nozzle_items[idx] = nozzle_item; + nozzle_sizer->Add(nozzle_item, 0); + } + + // toolhead area + m_toolhead_nozzle_l = new wgtDeviceNozzleRackNozzleItem(this, 1); + m_toolhead_nozzle_l->EnableSelect(); + m_toolhead_nozzle_l->SetDisplayIdText("L"); + m_toolhead_nozzle_l->Bind(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, &wgtDeviceNozzleRackSelect::OnNozzleItemSelected, this); + + m_toolhead_nozzle_r = new wgtDeviceNozzleRackNozzleItem(this, 0); + m_toolhead_nozzle_r->EnableSelect(); + m_toolhead_nozzle_r->SetDisplayIdText("R"); + m_toolhead_nozzle_r->Bind(EVT_NOZZLE_RACK_NOZZLE_ITEM_SELECTED, &wgtDeviceNozzleRackSelect::OnNozzleItemSelected, this); + + wxSizer* toolhead_sizer = new wxBoxSizer(wxHORIZONTAL); + toolhead_sizer->Add(m_toolhead_nozzle_l, 0, wxRIGHT, FromDIP(5)); + toolhead_sizer->Add(m_toolhead_nozzle_r, 0, wxLEFT, FromDIP(5)); + + main_sizer->Add(m_title_tips_dynamic, 0, wxALIGN_CENTRE_VERTICAL | wxBOTTOM, FromDIP(10)); + main_sizer->Add(s_create_title(this, _L("Hotend Rack")), 0, wxEXPAND); + main_sizer->Add(nozzle_sizer, 0, wxTOP | wxBOTTOM | wxALIGN_LEFT, FromDIP(10)); + main_sizer->Add(s_create_title(this, _L("ToolHead")), 0, wxEXPAND); + main_sizer->AddSpacer(FromDIP(10)); + main_sizer->Add(toolhead_sizer, 0, wxALIGN_LEFT); + + SetBackgroundColour(*wxWHITE); + SetSizer(main_sizer); + Layout(); + Fit(); +} + +static void s_update_nozzle_info(wgtDeviceNozzleRackNozzleItem* item, + std::shared_ptr rack, + const DevNozzle& nozzle_info) +{ + item->Update(rack, nozzle_info.IsOnRack()); + if (nozzle_info.IsUnknown()) { + if (item->GetToolTipText() != _L("Nozzle information needs to be read")) { + item->SetToolTip(_L("Nozzle information needs to be read")); + } + } else { + item->SetToolTip(wxEmptyString); + } +} + +void wgtDeviceNozzleRackSelect::UpdateNozzleInfos(std::shared_ptr rack) +{ + m_nozzle_rack = rack; + if (rack) { + s_update_nozzle_info(m_toolhead_nozzle_l, rack, rack->GetNozzleSystem()->GetNozzleByPosId(DEPUTY_EXTRUDER_ID)); + s_update_nozzle_info(m_toolhead_nozzle_r, rack, rack->GetNozzleSystem()->GetNozzleByPosId(MAIN_EXTRUDER_ID)); + for (const auto& item : m_nozzle_items) { + s_update_nozzle_info(item.second, rack, rack->GetNozzleSystem()->GetNozzleByPosId(item.first)); + } + } +} + +static void s_enable_item_if_match(wgtDeviceNozzleRackNozzleItem* item, + const DevNozzle& nozzle_info, + const DevNozzle& selected_nozzle) +{ + if (item) { + if (nozzle_info.GetLogicExtruderId() != selected_nozzle.GetLogicExtruderId()) { + item->SetDisable(true); + return; + } + + if (!nozzle_info.IsEmpty() && !nozzle_info.IsAbnormal() && !nozzle_info.IsUnknown() && + nozzle_info.GetNozzleType() == selected_nozzle.GetNozzleType() && + nozzle_info.GetNozzleDiameter() == selected_nozzle.GetNozzleDiameter() && + nozzle_info.GetNozzleFlowType() == selected_nozzle.GetNozzleFlowType()) { + item->SetDisable(false); + } else { + item->SetDisable(true); + } + } +} + +void wgtDeviceNozzleRackSelect::UpdatSelectedNozzle(std::shared_ptr rack, int selected_nozzle_pos_id) +{ + m_nozzle_rack = rack; + if (rack) { + SetSelectedNozzle(rack->GetNozzleSystem()->GetNozzleByPosId(selected_nozzle_pos_id)); + if (m_enable_manual_nozzle_pick) { + s_enable_item_if_match(m_toolhead_nozzle_r, rack->GetNozzleSystem()->GetNozzleByPosId(MAIN_EXTRUDER_ID), m_selected_nozzle); + s_enable_item_if_match(m_toolhead_nozzle_l, rack->GetNozzleSystem()->GetNozzleByPosId(DEPUTY_EXTRUDER_ID), m_selected_nozzle); + for (auto& item : m_nozzle_items) { + s_enable_item_if_match(item.second, rack->GetNozzleSystem()->GetNozzleByPosId(item.first), m_selected_nozzle); + } + } + } +} + +void wgtDeviceNozzleRackSelect::UpdatSelectedNozzles(std::shared_ptr rack, + std::vector selected_nozzle_pos_vec, + bool use_dynamic_switch, + std::optional /*print_from_type*/) +{ + m_nozzle_rack = rack; + m_enable_manual_nozzle_pick = !use_dynamic_switch; + m_title_tips_dynamic->Show(use_dynamic_switch); + + UpdateNozzleInfos(rack); + if (!use_dynamic_switch) { + if (selected_nozzle_pos_vec.size() > 0) { + return UpdatSelectedNozzle(rack, selected_nozzle_pos_vec.at(0)); + } else { + return ClearSelection(); + } + } + + if (rack) { + ClearSelection(); + for (const auto& pos_id : selected_nozzle_pos_vec) { + if (pos_id == MAIN_EXTRUDER_ID) { + m_toolhead_nozzle_r->SetSelected(true); + } else if (pos_id == DEPUTY_EXTRUDER_ID) { + m_toolhead_nozzle_l->SetSelected(true); + } else if (auto it = m_nozzle_items.find(pos_id); it != m_nozzle_items.end()) { + it->second->SetSelected(true); + } + } + + if (!m_toolhead_nozzle_l->IsSelected()) { + m_toolhead_nozzle_l->SetDisable(true); + } + + if (!m_toolhead_nozzle_r->IsSelected()) { + m_toolhead_nozzle_r->SetDisable(true); + } + + for (const auto& item : m_nozzle_items) { + if (!item.second->IsSelected()) { + item.second->SetDisable(true); + } + } + } +} + +void wgtDeviceNozzleRackSelect::ClearSelection() +{ + m_selected_nozzle = DevNozzle(); + m_toolhead_nozzle_l->SetSelected(false); + m_toolhead_nozzle_r->SetSelected(false); + for (auto &item : m_nozzle_items) { item.second->SetSelected(false); } +} + +void wgtDeviceNozzleRackSelect::SetSelectedNozzle(const DevNozzle &nozzle) +{ + int new_selected_pos_id = nozzle.GetNozzlePosId(); + if (m_selected_nozzle.GetNozzlePosId() != new_selected_pos_id) { + ClearSelection(); + + m_selected_nozzle = nozzle; + if (new_selected_pos_id == MAIN_EXTRUDER_ID) { + m_toolhead_nozzle_r->SetSelected(true); + } else if (new_selected_pos_id == DEPUTY_EXTRUDER_ID) { + m_toolhead_nozzle_l->SetSelected(true); + } else if (auto it = m_nozzle_items.find(m_selected_nozzle.GetNozzlePosId()); it != m_nozzle_items.end()) { + it->second->SetSelected(true); + } + } +} + +volatile int sGetNozzlePosId(wgtDeviceNozzleRackNozzleItem* item, + wgtDeviceNozzleRackNozzleItem* l_item, + wgtDeviceNozzleRackNozzleItem* r_item) +{ + int to_select_pos_id = -1; + if (item == l_item) { + to_select_pos_id = DEPUTY_EXTRUDER_ID; + } else if (item == r_item) { + to_select_pos_id = MAIN_EXTRUDER_ID; + } else { + to_select_pos_id = item->GetNozzleId() + 0x10; + } + + return to_select_pos_id; +} + +void wgtDeviceNozzleRackSelect::OnNozzleItemSelected(wxCommandEvent &evt) +{ + if (!m_enable_manual_nozzle_pick) { + return; + } + + auto *item = dynamic_cast(evt.GetEventObject()); + if (item; auto ptr = m_nozzle_rack.lock()) { + int to_select_pos_id = sGetNozzlePosId(item, m_toolhead_nozzle_l, m_toolhead_nozzle_r); + if (to_select_pos_id > -1 && to_select_pos_id != GetSelectedNozzlePosID()) { + SetSelectedNozzle(ptr->GetNozzleSystem()->GetNozzleByPosId(to_select_pos_id)); + wxCommandEvent change_evt(EVT_NOZZLE_SELECT_CHANGED, GetId()); + change_evt.SetEventObject(this); + ProcessEvent(change_evt); + evt.Skip(); + } else { + wxCommandEvent change_evt(EVT_NOZZLE_SELECT_CLICKED, GetId()); + change_evt.SetEventObject(this); + ProcessEvent(change_evt); + evt.Skip(); + } + } +} + +void wgtDeviceNozzleRackSelect::Rescale() +{ + m_toolhead_nozzle_l->Rescale(); + m_toolhead_nozzle_r->Rescale(); + for (auto &item : m_nozzle_items) { item.second->Rescale(); } +} + +}; // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h new file mode 100644 index 0000000000..43f3378ff2 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtDeviceNozzleSelect.h @@ -0,0 +1,74 @@ +//**********************************************************/ +/* File: wgtDeviceNozzleSelect.h +* Description: The panel to select nozzle +* +* \n class wgtDeviceNozzleSelect; +//**********************************************************/ + +#pragma once + +#include "slic3r/GUI/DeviceCore/DevNozzleSystem.h" // DevNozzle (value member) + DevDefs.h (PrintFromType, MAIN/DEPUTY_EXTRUDER_ID) + +#include + +#include +#include +#include +#include + +// Previous definitions +class Label; +namespace Slic3r +{ + struct DevNozzle; + class DevNozzleRack; +namespace GUI +{ + class wgtDeviceNozzleRackNozzleItem; + class wgtMsgBox; +} +}; + +wxDECLARE_EVENT(EVT_NOZZLE_SELECT_CHANGED, wxCommandEvent); +wxDECLARE_EVENT(EVT_NOZZLE_SELECT_CLICKED, wxCommandEvent); +namespace Slic3r::GUI +{ +class wgtDeviceNozzleRackSelect : public wxPanel +{ +public: + wgtDeviceNozzleRackSelect(wxWindow* parent); + ~wgtDeviceNozzleRackSelect() = default; + +public: + int GetSelectedNozzlePosID() const { return m_selected_nozzle.GetNozzlePosId();} + void UpdatSelectedNozzles(std::shared_ptr rack, std::vector selected_nozzle_pos_vec, bool use_dynamic_switch, std::optional print_from_type);// for slicing with dynamic switch + void Rescale(); + +private: + void CreateGui(); + + void ClearSelection(); + void SetSelectedNozzle(const DevNozzle &nozzle); + void UpdatSelectedNozzle(std::shared_ptr rack, int selected_nozzle_pos_id = -1); // for slicing without dynamic switch + + void UpdateNozzleInfos(std::shared_ptr rack); + + void OnNozzleItemSelected(wxCommandEvent& evt); + +private: + DevNozzle m_selected_nozzle; + std::weak_ptr m_nozzle_rack; + + // pick + bool m_enable_manual_nozzle_pick = true; + + // Label + wgtMsgBox* m_title_tips_dynamic; + + // GUI + wgtDeviceNozzleRackNozzleItem * m_toolhead_nozzle_l{nullptr}; + wgtDeviceNozzleRackNozzleItem * m_toolhead_nozzle_r{nullptr}; + std::unordered_map m_nozzle_items; // from 16 to 21 +}; + +};// end of namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtMsgBox.cpp b/src/slic3r/GUI/DeviceTab/wgtMsgBox.cpp new file mode 100644 index 0000000000..22ee189777 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtMsgBox.cpp @@ -0,0 +1,43 @@ +#include "wgtMsgBox.h" + +#include "slic3r/GUI/GUI_App.hpp" +#include "slic3r/GUI/Widgets/Label.hpp" +#include "slic3r/GUI/wxExtensions.hpp" + +#include + +namespace Slic3r::GUI +{ + +wgtMsgBox::wgtMsgBox(wxWindow* parent) + : StaticBox(parent, wxID_ANY) +{ + CreateGUI(); +} + +void wgtMsgBox::CreateGUI() +{ + wxBoxSizer* mainSizer = new wxBoxSizer(wxHORIZONTAL); + + m_txt_label = new Label(this); + m_txt_label->SetFont(::Label::Body_13); + m_txt_label->SetBackgroundColour(*wxWHITE); + + auto padding_sizer = new wxBoxSizer(wxHORIZONTAL); + padding_sizer->Add(m_txt_label, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5)); + mainSizer->Add(padding_sizer, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1); + + //Button* btnClose = CreateCloseButton(); + //wxButton* btnClose = CreateCloseButton(); + //mainSizer->Add(btnClose, 0, wxALIGN_CENTER_VERTICAL); + + SetSizer(mainSizer); + mainSizer->Fit(this); +} + +void wgtMsgBox::OnCloseClicked(wxCommandEvent& evt) +{ + this->Hide(); +} + +} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DeviceTab/wgtMsgBox.h b/src/slic3r/GUI/DeviceTab/wgtMsgBox.h new file mode 100644 index 0000000000..0668893d09 --- /dev/null +++ b/src/slic3r/GUI/DeviceTab/wgtMsgBox.h @@ -0,0 +1,31 @@ +#ifndef WGTMSGBOX_H +#define WGTMSGBOX_H + +#include +#include +#include +#include + +#include "slic3r/GUI/Widgets/StaticBox.hpp" + +class Label; +namespace Slic3r::GUI +{ +class wgtMsgBox : public StaticBox +{ +public: + wgtMsgBox(wxWindow* parent); + +public: + Label* GetTextLabel() const { return m_txt_label; } + +private: + Label* m_txt_label; + +private: + void CreateGUI(); + void OnCloseClicked(wxCommandEvent& evt); +}; +} + +#endif // WGTMSGBOX_H diff --git a/src/slic3r/GUI/DragDropPanel.cpp b/src/slic3r/GUI/DragDropPanel.cpp index 352880cffb..0c1371c307 100644 --- a/src/slic3r/GUI/DragDropPanel.cpp +++ b/src/slic3r/GUI/DragDropPanel.cpp @@ -1,9 +1,14 @@ #include "DragDropPanel.hpp" +#include "GUI_App.hpp" +#include "I18N.hpp" #include "Widgets/Label.hpp" +#include "Widgets/StateColor.hpp" #include namespace Slic3r { namespace GUI { +wxDEFINE_EVENT(wxEVT_DRAG_DROP_COMPLETED, wxCommandEvent); + struct CustomData { int filament_id; @@ -201,7 +206,7 @@ wxDragResult ColorDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def) /////////////// ColorDropTarget end //////////////////////// -DragDropPanel::DragDropPanel(wxWindow *parent, const wxString &label, bool is_auto) +DragDropPanel::DragDropPanel(wxWindow *parent, const wxString &label, bool is_auto, bool has_title, bool is_sub) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) , m_is_auto(is_auto) { @@ -209,22 +214,31 @@ DragDropPanel::DragDropPanel(wxWindow *parent, const wxString &label, bool is_au m_sizer = new wxBoxSizer(wxVERTICAL); - auto title_panel = new wxPanel(this); - title_panel->SetBackgroundColour(0xEEEEEE); - auto title_sizer = new wxBoxSizer(wxHORIZONTAL); - title_panel->SetSizer(title_sizer); + if (has_title) { + auto title_panel = new wxPanel(this); + title_panel->SetBackgroundColour(is_sub ? wxColour(0xF8F8F8) : wxColour(0xEEEEEE)); + auto title_sizer = new wxBoxSizer(wxHORIZONTAL); + title_panel->SetSizer(title_sizer); - Label* static_text = new Label(this, label); - static_text->SetFont(Label::Head_13); - static_text->SetBackgroundColour(0xEEEEEE); + m_title_label = new Label(this, label); + m_title_label->SetFont(is_sub ? Label::Body_12 : Label::Head_13); + if (is_sub) + m_title_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B"))); + m_title_label->SetBackgroundColour(is_sub ? wxColour(0xF8F8F8) : wxColour(0xEEEEEE)); - title_sizer->Add(static_text, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + title_sizer->Add(m_title_label, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); - m_sizer->Add(title_panel, 0, wxEXPAND); - m_sizer->AddSpacer(10); + m_sizer->Add(title_panel, 0, wxEXPAND); + m_sizer->AddSpacer(10); + } - m_grid_item_sizer = new wxGridSizer(0, 6, FromDIP(8), FromDIP(8)); // row = 0, col = 3, 10 10 is space - m_sizer->Add(m_grid_item_sizer, 1, wxEXPAND | wxALL, FromDIP(8)); + if (is_sub) { + m_grid_item_sizer = new wxGridSizer(0, 3, FromDIP(6), FromDIP(6)); + m_sizer->Add(m_grid_item_sizer, 0, wxEXPAND); + } else { + m_grid_item_sizer = new wxGridSizer(0, 6, FromDIP(8), FromDIP(8)); // row = 0, col = 3, 10 10 is space + m_sizer->Add(m_grid_item_sizer, 1, wxEXPAND | wxALL, FromDIP(8)); + } // set droptarget auto drop_target = new ColorDropTarget(this); @@ -242,20 +256,35 @@ void DragDropPanel::AddColorBlock(const wxColour &color, const std::string &type m_grid_item_sizer->Add(panel, 0); m_filament_blocks.push_back(panel); if (update_ui) { - m_filament_blocks.front()->Refresh(); // FIX BUG: STUDIO-8467 + Freeze(); + + m_grid_item_sizer->Layout(); + Layout(); + Fit(); GetParent()->GetParent()->Layout(); GetParent()->GetParent()->Fit(); + m_filament_blocks.front()->Refresh(); // FIX BUG: STUDIO-8467 + + Thaw(); + NotifyDragDropCompleted(); } } void DragDropPanel::RemoveColorBlock(ColorPanel *panel, bool update_ui) { - m_sizer->Detach(panel); + m_grid_item_sizer->Detach(panel); panel->Destroy(); m_filament_blocks.erase(std::remove(m_filament_blocks.begin(), m_filament_blocks.end(), panel), m_filament_blocks.end()); if (update_ui) { + Freeze(); + + Layout(); + Fit(); GetParent()->GetParent()->Layout(); GetParent()->GetParent()->Fit(); + + Thaw(); + NotifyDragDropCompleted(); } } @@ -270,6 +299,15 @@ void DragDropPanel::DoDragDrop(ColorPanel *panel, const wxColour &color, const s } } +void DragDropPanel::UpdateLabel(const wxString &label) +{ + if (m_title_label) { + m_title_label->SetLabel(label); + m_title_label->Refresh(); + Layout(); + } +} + std::vector DragDropPanel::GetAllFilaments() const { std::vector filaments; @@ -287,4 +325,327 @@ std::vector DragDropPanel::GetAllFilaments() const return filaments; } +void DragDropPanel::NotifyDragDropCompleted() +{ + wxCommandEvent event(wxEVT_DRAG_DROP_COMPLETED); + event.SetEventObject(this); + + wxWindow *parent = GetParent(); + while (parent) { + auto name = parent->GetName(); + if (name == wxT("FilamentMapManualPanel")) { + parent->GetEventHandler()->ProcessEvent(event); + break; + } + parent = parent->GetParent(); + } +} + +class SeparatedColorDropTarget : public wxDropTarget +{ +public: + SeparatedColorDropTarget(SeparatedDragDropPanel *panel) : wxDropTarget(), m_panel(panel) + { + m_data = new ColorDataObject(); + SetDataObject(m_data); + } + + virtual wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult def) override; + virtual bool OnDrop(wxCoord x, wxCoord y) override { return true; } + +private: + SeparatedDragDropPanel *m_panel; + ColorDataObject *m_data; +}; + +wxDragResult SeparatedColorDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult def) +{ + if (!GetData()) return wxDragNone; + + m_panel->AddColorBlock(m_data->GetColor(), m_data->GetType(), m_data->GetFilament(), false); + return wxDragCopy; +} + +SeparatedDragDropPanel::SeparatedDragDropPanel(wxWindow *parent, const wxString &label, bool use_separation) : wxPanel(parent), m_use_separation(use_separation) +{ + SetBackgroundColour(0xF8F8F8); + + m_main_sizer = new wxBoxSizer(wxVERTICAL); + + auto title_panel = new wxPanel(this); + title_panel->SetBackgroundColour(0xEEEEEE); + auto title_sizer = new wxBoxSizer(wxHORIZONTAL); + title_panel->SetSizer(title_sizer); + + m_label = new Label(title_panel, label); + m_label->SetFont(Label::Head_13); + m_label->SetBackgroundColour(0xEEEEEE); + + title_sizer->Add(m_label, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + + m_main_sizer->Add(title_panel, 0, wxEXPAND); + m_main_sizer->AddSpacer(10); + + m_content_panel = new wxPanel(this); + m_content_panel->SetBackgroundColour(0xF8F8F8); + m_content_sizer = new wxBoxSizer(wxHORIZONTAL); + m_content_panel->SetSizer(m_content_sizer); + + m_high_flow_panel = new DragDropPanel(m_content_panel, _L("High Flow"), false, true, true); + m_standard_panel = new DragDropPanel(m_content_panel, _L("Standard"), false, true, true); + m_unified_panel = new DragDropPanel(m_content_panel, wxEmptyString, false, false); + + m_high_flow_panel->SetBackgroundColour(0xF8F8F8); + m_standard_panel->SetBackgroundColour(0xF8F8F8); + m_unified_panel->SetBackgroundColour(0xF8F8F8); + m_unified_panel->SetMinSize({FromDIP(260), -1}); + + m_main_sizer->Add(m_content_panel, 1, wxEXPAND); + + UpdateLayout(); + + auto drop_target = new SeparatedColorDropTarget(this); + SetDropTarget(drop_target); + + SetSizer(m_main_sizer); + Layout(); + wxGetApp().UpdateDarkUIWin(this); +} + +void SeparatedDragDropPanel::UpdateLayout() +{ + m_content_sizer->Clear(false); + + if (m_use_separation) { + m_unified_panel->Hide(); + m_high_flow_panel->Show(); + m_standard_panel->Show(); + + wxSize content_size = m_content_panel->GetSize(); + int panel_width = (content_size.GetWidth() - FromDIP(1) - FromDIP(8)) / 2; + if (panel_width > 0) { + m_high_flow_panel->SetMinSize(wxSize(panel_width, -1)); + m_standard_panel->SetMinSize(wxSize(panel_width, -1)); + } + + m_content_sizer->Add(m_high_flow_panel, 1, wxEXPAND | wxLEFT, FromDIP(8)); + + // Create the separator once and re-attach it on relayout; Clear(false) above only + // detaches, so allocating here would leak a window per relayout. + if (!m_separator) { + m_separator = new wxPanel(m_content_panel, wxID_ANY); + m_separator->SetBackgroundColour(StateColor::darkModeColorFor(wxColour(0xCE, 0xCE, 0xCE))); + m_separator->SetMinSize(wxSize(FromDIP(1), -1)); + } + m_separator->Show(); + m_content_sizer->Add(m_separator, 0, wxEXPAND | wxALL, FromDIP(4)); + + m_content_sizer->Add(m_standard_panel, 1, wxEXPAND | wxRIGHT, FromDIP(8)); + } else { + m_high_flow_panel->Hide(); + m_standard_panel->Hide(); + if (m_separator) + m_separator->Hide(); + m_unified_panel->Show(); + + m_content_sizer->Add(m_unified_panel, 1, wxEXPAND); + } + m_content_sizer->Layout(); + Layout(); + Fit(); + if (GetParent()) { + GetParent()->Layout(); + if (GetParent()->GetParent()) { + GetParent()->GetParent()->Layout(); + } + } +} + +void SeparatedDragDropPanel::UpdateLabel(const wxString &label) +{ + if (m_label) { + m_label->SetLabel(label); + m_label->Refresh(); + Layout(); + } +} + +void SeparatedDragDropPanel::SetUseSeparation(bool use_separation) +{ + if (m_use_separation != use_separation) { + m_use_separation = use_separation; + + if (use_separation) { + auto blocks = m_unified_panel->get_filament_blocks(); + for (auto &block : blocks) { + m_standard_panel->AddColorBlock(block->GetColor(), block->GetType(), block->GetFilamentId(), false); + m_unified_panel->RemoveColorBlock(block, false); + } + } else { + auto high_flow_blocks = m_high_flow_panel->get_filament_blocks(); + auto standard_blocks = m_standard_panel->get_filament_blocks(); + + for (auto &block : high_flow_blocks) { + m_unified_panel->AddColorBlock(block->GetColor(), block->GetType(), block->GetFilamentId(), false); + m_high_flow_panel->RemoveColorBlock(block, false); + } + + for (auto &block : standard_blocks) { + m_unified_panel->AddColorBlock(block->GetColor(), block->GetType(), block->GetFilamentId(), false); + m_standard_panel->RemoveColorBlock(block, false); + } + } + + UpdateLayout(); + } +} + +void SeparatedDragDropPanel::AddColorBlock(const wxColour &color, const std::string &type, int filament_id, bool is_high_flow, bool update_ui) +{ + if (m_use_separation) { + if (is_high_flow) { + m_high_flow_panel->AddColorBlock(color, type, filament_id, update_ui); + } else { + m_standard_panel->AddColorBlock(color, type, filament_id, update_ui); + } + + if (update_ui) { + CallAfter([this]() { + Layout(); + GetParent()->Layout(); + }); + } + } else { + m_unified_panel->AddColorBlock(color, type, filament_id, update_ui); + } +} + +void SeparatedDragDropPanel::RemoveColorBlock(ColorPanel *panel, bool update_ui) +{ + auto high_flow_blocks = m_high_flow_panel->get_filament_blocks(); + auto standard_blocks = m_standard_panel->get_filament_blocks(); + auto unified_blocks = m_unified_panel->get_filament_blocks(); + + if (std::find(high_flow_blocks.begin(), high_flow_blocks.end(), panel) != high_flow_blocks.end()) { + m_high_flow_panel->RemoveColorBlock(panel, update_ui); + } else if (std::find(standard_blocks.begin(), standard_blocks.end(), panel) != standard_blocks.end()) { + m_standard_panel->RemoveColorBlock(panel, update_ui); + } else if (std::find(unified_blocks.begin(), unified_blocks.end(), panel) != unified_blocks.end()) { + m_unified_panel->RemoveColorBlock(panel, update_ui); + } + + if (update_ui && m_use_separation) { + CallAfter([this]() { + Layout(); + GetParent()->Layout(); + }); + } +} + +std::vector SeparatedDragDropPanel::GetAllFilaments() const +{ + if (m_use_separation) { + auto high_flow = m_high_flow_panel->GetAllFilaments(); + auto standard = m_standard_panel->GetAllFilaments(); + + std::vector result; + result.insert(result.end(), high_flow.begin(), high_flow.end()); + result.insert(result.end(), standard.begin(), standard.end()); + return result; + } else { + return m_unified_panel->GetAllFilaments(); + } +} + +std::vector SeparatedDragDropPanel::GetHighFlowFilaments() const +{ + if (m_use_separation) { + return m_high_flow_panel->GetAllFilaments(); + } + auto nozzle_volumes = wxGetApp().preset_bundle->project_config.option("nozzle_volume_type"); + const int right_eid = 1; + if (nozzle_volumes->values.size() > right_eid) { + int volume_type = nozzle_volumes->values[right_eid]; + if (volume_type == static_cast(NozzleVolumeType::nvtHighFlow)) { + return m_unified_panel->GetAllFilaments(); + } + } + return {}; +} + +std::vector SeparatedDragDropPanel::GetStandardFilaments() const +{ + if (m_use_separation) { + return m_standard_panel->GetAllFilaments(); + } + auto nozzle_volumes = wxGetApp().preset_bundle->project_config.option("nozzle_volume_type"); + const int right_eid = 1; + if (nozzle_volumes->values.size() > right_eid) { + int volume_type = nozzle_volumes->values[right_eid]; + if (volume_type == static_cast(NozzleVolumeType::nvtStandard)) { + return m_unified_panel->GetAllFilaments(); + } + } + return {}; +} + +std::vector SeparatedDragDropPanel::GetTPUHighFlowFilaments() const +{ + if (m_use_separation) { + return {}; + } + auto nozzle_volumes = wxGetApp().preset_bundle->project_config.option("nozzle_volume_type"); + const int right_eid = 1; + if (nozzle_volumes->values.size() > right_eid) { + int volume_type = nozzle_volumes->values[right_eid]; + if (volume_type == static_cast(NozzleVolumeType::nvtTPUHighFlow)) { + return m_unified_panel->GetAllFilaments(); + } + } + return {}; +} + +std::vector SeparatedDragDropPanel::get_filament_blocks() const +{ + if (m_use_separation) { + auto high_flow = m_high_flow_panel->get_filament_blocks(); + auto standard = m_standard_panel->get_filament_blocks(); + + std::vector result; + result.insert(result.end(), high_flow.begin(), high_flow.end()); + result.insert(result.end(), standard.begin(), standard.end()); + return result; + } else { + return m_unified_panel->get_filament_blocks(); + } +} + +std::vector SeparatedDragDropPanel::get_high_flow_blocks() const +{ + return m_high_flow_panel->get_filament_blocks(); +} + +std::vector SeparatedDragDropPanel::get_standard_blocks() const +{ + return m_standard_panel->get_filament_blocks(); +} + +void SeparatedDragDropPanel::ClearAllBlocks() +{ + auto high_flow_blocks = m_high_flow_panel->get_filament_blocks(); + for (auto &block : high_flow_blocks) { + m_high_flow_panel->RemoveColorBlock(block, false); + } + + auto standard_blocks = m_standard_panel->get_filament_blocks(); + for (auto &block : standard_blocks) { + m_standard_panel->RemoveColorBlock(block, false); + } + + auto unified_blocks = m_unified_panel->get_filament_blocks(); + for (auto &block : unified_blocks) { + m_unified_panel->RemoveColorBlock(block, false); + } +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/DragDropPanel.hpp b/src/slic3r/GUI/DragDropPanel.hpp index d988164839..4f2a4bced0 100644 --- a/src/slic3r/GUI/DragDropPanel.hpp +++ b/src/slic3r/GUI/DragDropPanel.hpp @@ -3,6 +3,7 @@ #include "GUI.hpp" #include "GUI_Utils.hpp" +#include "Widgets/Label.hpp" #include #include @@ -13,17 +14,20 @@ namespace Slic3r { namespace GUI { +wxDECLARE_EVENT(wxEVT_DRAG_DROP_COMPLETED, wxCommandEvent); + wxColor Hex2Color(const std::string& str); class ColorPanel; class DragDropPanel : public wxPanel { public: - DragDropPanel(wxWindow *parent, const wxString &label, bool is_auto); + DragDropPanel(wxWindow *parent, const wxString &label, bool is_auto, bool has_title = true, bool is_sub = false); void AddColorBlock(const wxColour &color, const std::string &type, int filament_id, bool update_ui = true); void RemoveColorBlock(ColorPanel *panel, bool update_ui = true); void DoDragDrop(ColorPanel *panel, const wxColour &color, const std::string &type, int filament_id); + void UpdateLabel(const wxString &label); std::vector GetAllFilaments() const; @@ -35,9 +39,12 @@ public: private: wxBoxSizer *m_sizer; wxGridSizer *m_grid_item_sizer; + Label *m_title_label = nullptr; bool m_is_auto; std::vector m_filament_blocks; + + void NotifyDragDropCompleted(); private: bool m_is_draging = false; }; @@ -64,6 +71,49 @@ private: int m_filament_id; }; + +// Drop zone for one extruder that can split into two sub-zones (High Flow / Standard) +// when the extruder mixes nozzle volume types (Hybrid flow), and collapses back to a +// single unified zone otherwise. +class SeparatedDragDropPanel : public wxPanel +{ +public: + SeparatedDragDropPanel(wxWindow *parent, const wxString &label, bool use_separation = false); + + void AddColorBlock(const wxColour &color, const std::string &type, int filament_id, bool is_high_flow = false, bool update_ui = true); + void RemoveColorBlock(ColorPanel *panel, bool update_ui = true); + + std::vector GetAllFilaments() const; + std::vector GetHighFlowFilaments() const; + std::vector GetStandardFilaments() const; + std::vector GetTPUHighFlowFilaments() const; + + std::vector get_filament_blocks() const; + std::vector get_high_flow_blocks() const; + std::vector get_standard_blocks() const; + + void SetUseSeparation(bool use_separation); + bool IsUseSeparation() const { return m_use_separation; } + void ClearAllBlocks(); + void UpdateLabel(const wxString &label); + +private: + void UpdateLayout(); + + wxBoxSizer *m_main_sizer; + wxPanel *m_content_panel; + wxBoxSizer *m_content_sizer; + wxPanel *m_separator = nullptr; + Label *m_label; + + DragDropPanel *m_high_flow_panel; + DragDropPanel *m_standard_panel; + + DragDropPanel *m_unified_panel; + + bool m_use_separation; +}; + }} // namespace Slic3r::GUI #endif /* slic3r_DragDropPanel_hpp_ */ diff --git a/src/slic3r/GUI/ExtrusionCalibration.cpp b/src/slic3r/GUI/ExtrusionCalibration.cpp index 28255f37e4..cd3f49e977 100644 --- a/src/slic3r/GUI/ExtrusionCalibration.cpp +++ b/src/slic3r/GUI/ExtrusionCalibration.cpp @@ -239,7 +239,7 @@ void ExtrusionCalibration::create() m_button_save_result->SetStyle(ButtonStyle::Confirm, ButtonType::Choice); m_button_save_result->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_save, this); - m_button_last_step = new Button(m_step_2_panel, _L("Back")); // Back for english + m_button_last_step = new Button(m_step_2_panel, _CTX("Back", "Navigation")); // Back for english m_button_last_step->SetStyle(ButtonStyle::Regular, ButtonType::Choice); m_button_last_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_last, this); diff --git a/src/slic3r/GUI/Field.cpp b/src/slic3r/GUI/Field.cpp index 42fe6b4ce1..1cb0cf6148 100644 --- a/src/slic3r/GUI/Field.cpp +++ b/src/slic3r/GUI/Field.cpp @@ -936,6 +936,7 @@ bool TextCtrl::value_was_changed() case coString: case coStrings: case coFloatOrPercent: + case coFloatsOrPercents: return boost::any_cast(m_value) != boost::any_cast(val); default: return true; diff --git a/src/slic3r/GUI/FilamentGroupPopup.cpp b/src/slic3r/GUI/FilamentGroupPopup.cpp index a29e4537fb..e5e49928dc 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.cpp +++ b/src/slic3r/GUI/FilamentGroupPopup.cpp @@ -174,6 +174,9 @@ FilamentGroupPopup::FilamentGroupPopup(wxWindow *parent) : PopupWindow(parent, w button_labels[idx]->Bind(wxEVT_LEAVE_WINDOW, [this](auto &) { UpdateButtonStatus(); }); } + // Smart filament assign section + MakeSmartFilamentSection(top_sizer, horizontal_margin, vertical_padding); + { wxBoxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL); // ORCA Unified hyperlinks @@ -257,6 +260,7 @@ void FilamentGroupPopup::Init() SetFilamentMapMode(m_mode); } + UpdateSmartFilamentSection(); UpdateButtonStatus(); GUI::wxGetApp().UpdateDarkUIWin(this); } @@ -408,4 +412,65 @@ void FilamentGroupPopup::UpdateButtonStatus(int hover_idx) Fit(); } +void FilamentGroupPopup::MakeSmartFilamentSection(wxSizer *top_sizer, int horizontal_margin, int vertical_padding) +{ + m_smart_filament_panel = new StaticBox(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0); + m_smart_filament_panel->SetCornerRadius(FromDIP(4)); + m_smart_filament_panel->SetBorderWidth(FromDIP(1)); + m_smart_filament_panel->SetBorderColor(wxColour("#CECECE")); + m_smart_filament_panel->SetBackgroundColor(StateColor(std::pair(wxColour("#F8F8F8"), StateColor::Normal))); + + auto *label = new Label(m_smart_filament_panel, _L("Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings")); + label->SetFont(Label::Body_12); + label->SetForegroundColour(GreyColor); + label->SetBackgroundColour(wxColour("#F8F8F8")); + label->Wrap(FromDIP(240)); + + m_smart_filament_switch = new SwitchButton(m_smart_filament_panel); + m_smart_filament_switch->Bind(wxEVT_TOGGLEBUTTON, &FilamentGroupPopup::OnSmartFilamentToggle, this); +#ifdef __WXOSX__ + // wxEVT_TOGGLEBUTTON event not handled well by PopupWindow on MacOS + // we bind a wxEVT_LEFT_DOWN event as a workaround + m_smart_filament_switch->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &) { + wxCommandEvent evt(wxEVT_TOGGLEBUTTON); + evt.SetInt(!m_smart_filament_switch->GetValue()); + m_smart_filament_switch->Command(evt); + }); +#endif + + auto *panel_sizer = new wxBoxSizer(wxHORIZONTAL); + panel_sizer->Add(label, 1, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(10)); + panel_sizer->Add(m_smart_filament_switch, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(10)); + m_smart_filament_panel->SetSizer(panel_sizer); + + top_sizer->Add(m_smart_filament_panel, 0, wxEXPAND | wxLEFT | wxRIGHT, horizontal_margin); + m_smart_filament_spacer = top_sizer->AddSpacer(vertical_padding); + + // Hidden by default; shown in Init() when the filament track switch is ready + m_smart_filament_panel->Show(false); + m_smart_filament_spacer->Show(false); +} + +void FilamentGroupPopup::OnSmartFilamentToggle(wxCommandEvent &event) +{ + auto &config = wxGetApp().preset_bundle->project_config; + auto *dynamic_filament = dynamic_cast(config.option("enable_filament_dynamic_map")); + if (dynamic_filament) { dynamic_filament->value = m_smart_filament_switch->GetValue(); } + plater_ref->update(); + event.Skip(); +} + +void FilamentGroupPopup::UpdateSmartFilamentSection() +{ + bool show = wxGetApp().sidebar().is_fila_switch_ready(); + m_smart_filament_panel->Show(show); + m_smart_filament_spacer->Show(show); + + if (show) { + auto &config = wxGetApp().preset_bundle->project_config; + auto *dynamic_filament = dynamic_cast(config.option("enable_filament_dynamic_map")); + if (dynamic_filament) { m_smart_filament_switch->SetValue(dynamic_filament->value); } + } +} + }} // namespace Slic3r::GUI \ No newline at end of file diff --git a/src/slic3r/GUI/FilamentGroupPopup.hpp b/src/slic3r/GUI/FilamentGroupPopup.hpp index 2355b13e9e..6d0bd43da7 100644 --- a/src/slic3r/GUI/FilamentGroupPopup.hpp +++ b/src/slic3r/GUI/FilamentGroupPopup.hpp @@ -3,10 +3,13 @@ #include #include +#include #include #include "libslic3r/PrintConfig.hpp" #include "Widgets/PopupWindow.hpp" #include "Widgets/Label.hpp" +#include "Widgets/SwitchButton.hpp" +#include "Widgets/StaticBox.hpp" namespace Slic3r { namespace GUI { @@ -42,6 +45,10 @@ private: void Init(); void UpdateButtonStatus(int hover_idx = -1); void DrawRoundedCorner(int radius); + + void MakeSmartFilamentSection(wxSizer *top_sizer, int horizontal_margin, int vertical_padding); + void UpdateSmartFilamentSection(); + void OnSmartFilamentToggle(wxCommandEvent &event); private: FilamentMapMode GetFilamentMapMode() const; void SetFilamentMapMode(const FilamentMapMode mode); @@ -75,6 +82,10 @@ private: wxStaticText *wiki_link; wxStaticText *video_link; + StaticBox *m_smart_filament_panel{nullptr}; + wxSizerItem *m_smart_filament_spacer{nullptr}; + SwitchButton *m_smart_filament_switch{nullptr}; + PartPlate* partplate_ref{ nullptr }; Plater* plater_ref{ nullptr }; }; diff --git a/src/slic3r/GUI/FilamentMapDialog.cpp b/src/slic3r/GUI/FilamentMapDialog.cpp index a514494af1..12ca3a2965 100644 --- a/src/slic3r/GUI/FilamentMapDialog.cpp +++ b/src/slic3r/GUI/FilamentMapDialog.cpp @@ -36,9 +36,78 @@ static std::vector get_applied_map(DynamicConfig& proj_config, const Plater return plater_ref->get_global_filament_map(); } +static std::vector get_applied_volume_map(DynamicConfig& proj_config, const Plater* plater_ref, const PartPlate* partplate_ref, const bool sync_plate) +{ + if (sync_plate) + return partplate_ref->get_real_filament_volume_maps(proj_config); + return plater_ref->get_global_filament_volume_map(); +} + extern std::string& get_left_extruder_unprintable_text(); extern std::string& get_right_extruder_unprintable_text(); +// Orca: minimal smart-filament toggle. When a filament track switch is ready every AMS filament is +// reachable from both nozzles, so one filament can be assigned to multiple nozzles to maximize +// savings. The checkbox drives the enable_filament_dynamic_map project flag. +class SmartFilamentPanel : public wxPanel +{ + static constexpr int spacing = 20; + +public: + SmartFilamentPanel(wxWindow *parent) : wxPanel(parent) + { + SetBackgroundColour(*wxWHITE); + wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); + + main_sizer->AddSpacer(FromDIP(spacing)); + + auto *separator = new wxPanel(this); + separator->SetBackgroundColour(wxColour("#EEEEEE")); + main_sizer->Add(separator, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(15)); + + main_sizer->AddSpacer(FromDIP(spacing)); + + m_smart_filament_checkbox = new CheckBox(this); + if (auto *opt = enable_filament_dynamic_map()) + m_smart_filament_checkbox->SetValue(opt->value); + m_smart_filament_checkbox->Bind(wxEVT_TOGGLEBUTTON, &SmartFilamentPanel::on_smart_filament_checkbox, this); + + auto *label = new Label(this, _L("Enable smart filament assign: Assign one filament to multiple nozzles to maximize savings")); + label->SetFont(Label::Body_12); + + // Orca: dropped the vendor "Learn more" tracking link (no Orca help page for this feature). + + auto *smart_sizer = new wxBoxSizer(wxHORIZONTAL); + smart_sizer->Add(m_smart_filament_checkbox, 0, wxALIGN_CENTER_VERTICAL); + smart_sizer->Add(label, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(3)); + + main_sizer->Add(smart_sizer, 0, wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(15)); + + SetSizer(main_sizer); + Layout(); + Fit(); + wxGetApp().UpdateDarkUIWin(this); + } + +private: + static ConfigOptionBool *enable_filament_dynamic_map() + { + auto &config = wxGetApp().preset_bundle->project_config; + return dynamic_cast(config.option("enable_filament_dynamic_map")); + } + + void on_smart_filament_checkbox(wxCommandEvent &event) + { + if (auto *opt = enable_filament_dynamic_map()) + opt->value = m_smart_filament_checkbox->GetValue(); + wxGetApp().plater()->update(); + event.Skip(); + } + +private: + CheckBox *m_smart_filament_checkbox{nullptr}; +}; + bool try_pop_up_before_slice(bool is_slice_all, Plater* plater_ref, PartPlate* partplate_ref, bool force_pop_up) { @@ -61,7 +130,9 @@ bool try_pop_up_before_slice(bool is_slice_all, Plater* plater_ref, PartPlate* p std::vector filament_types = full_config.option("filament_type")->values; FilamentMapMode applied_mode = get_applied_map_mode(full_config, plater_ref,partplate_ref, sync_plate); std::vector applied_maps = get_applied_map(full_config, plater_ref, partplate_ref, sync_plate); + std::vector applied_volume_maps = get_applied_volume_map(full_config, plater_ref, partplate_ref, sync_plate); applied_maps.resize(filament_colors.size(), 1); + applied_volume_maps.resize(filament_colors.size(), 0); if (!force_pop_up && applied_mode != fmmManual) return true; @@ -79,6 +150,7 @@ bool try_pop_up_before_slice(bool is_slice_all, Plater* plater_ref, PartPlate* p filament_colors, filament_types, applied_maps, + applied_volume_maps, filament_lists, applied_mode, plater_ref->get_machine_sync_status(), @@ -90,25 +162,32 @@ bool try_pop_up_before_slice(bool is_slice_all, Plater* plater_ref, PartPlate* p if (ret == wxID_OK) { FilamentMapMode new_mode = map_dlg.get_mode(); std::vector new_maps = map_dlg.get_filament_maps(); + std::vector new_volume_maps = map_dlg.get_filament_volume_maps(); if (sync_plate) { if (is_slice_all) { auto plate_list = plater_ref->get_partplate_list().get_plate_list(); for (int i = 0; i < plate_list.size(); ++i) { plate_list[i]->set_filament_map_mode(new_mode); - if(new_mode == fmmManual) + if (new_mode == fmmManual) { plate_list[i]->set_filament_maps(new_maps); + plate_list[i]->set_filament_volume_maps(new_volume_maps); + } } } else { partplate_ref->set_filament_map_mode(new_mode); - if (new_mode == fmmManual) + if (new_mode == fmmManual) { partplate_ref->set_filament_maps(new_maps); + partplate_ref->set_filament_volume_maps(new_volume_maps); + } } } else { plater_ref->set_global_filament_map_mode(new_mode); - if (new_mode == fmmManual) + if (new_mode == fmmManual) { plater_ref->set_global_filament_map(new_maps); + plater_ref->set_global_filament_volume_map(new_volume_maps); + } } plater_ref->update(); // check whether able to slice, if not, return false @@ -124,21 +203,35 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, const std::vector &filament_color, const std::vector &filament_type, const std::vector &filament_map, + const std::vector &filament_volume_map, const std::vector &filaments, const FilamentMapMode mode, bool machine_synced, bool show_default, bool with_checkbox) - : wxDialog(parent, wxID_ANY, _L("Filament grouping"), wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE), m_filament_color(filament_color), m_filament_type(filament_type), m_filament_map(filament_map) + : wxDialog(parent, wxID_ANY, _L("Filament grouping"), wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE) + , m_filament_color(filament_color) + , m_filament_type(filament_type) + , m_filament_map(filament_map) + , m_filament_volume_map(filament_volume_map) { SetBackgroundColour(*wxWHITE); SetMinSize(wxSize(FromDIP(580), -1)); SetMaxSize(wxSize(FromDIP(580), -1)); + // Orca: when a filament track switch is ready, every AMS filament reaches both nozzles, so the + // Match/Convenience sub-mode is dropped and Auto is presented purely as a filament-saving mode. + // Orca has no fmmAutoForQuality, so "only saving" collapses to "switch ready" and the remaining + // auto mode set is { fmmAutoForFlush }. + m_fila_switch_ready = wxGetApp().sidebar().is_fila_switch_ready(); + const bool only_saving_mode = m_fila_switch_ready; + const bool auto_match_available = machine_synced && !m_fila_switch_ready; + if (mode < fmmManual) m_page_type = PageType::ptAuto; - else if (mode == fmmManual) + else if (mode == fmmManual || mode == fmmNozzleManual) + // Orca: there is no dedicated nozzle-manual page, so treat an fmmNozzleManual plate as a manual variant and show the Custom page instead of misfiling it as "Same as Global". m_page_type = PageType::ptManual; else m_page_type = PageType::ptDefault; @@ -148,7 +241,7 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, wxBoxSizer *mode_sizer = new wxBoxSizer(wxHORIZONTAL); - m_auto_btn = new CapsuleButton(this, PageType::ptAuto, _L("Auto"), false); + m_auto_btn = new CapsuleButton(this, PageType::ptAuto, only_saving_mode ? _L("Fila Saving") : _L("Auto"), false); m_manual_btn = new CapsuleButton(this, PageType::ptManual, _L("Custom"), false); if (show_default) m_default_btn = new CapsuleButton(this, PageType::ptDefault, _L("Same as Global"), true); @@ -167,12 +260,27 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, auto panel_sizer = new wxBoxSizer(wxHORIZONTAL); + // Orca: fall back to the saving mode whenever Match is unavailable, which now also covers the + // filament-track-switch-ready case (auto_match_available folds in !m_fila_switch_ready). FilamentMapMode default_auto_mode = mode >= fmmManual ? fmmAutoForFlush : - mode == fmmAutoForMatch && !machine_synced ? fmmAutoForFlush : + mode == fmmAutoForMatch && !auto_match_available ? fmmAutoForFlush : mode; - m_manual_map_panel = new FilamentMapManualPanel(this, m_filament_color, m_filament_type, filaments, filament_map); - m_auto_map_panel = new FilamentMapAutoPanel(this, default_auto_mode, machine_synced); + m_manual_map_panel = new FilamentMapManualPanel(this, m_filament_color, m_filament_type, filaments, filament_map, filament_volume_map); + // A manual grouping can point filaments at a nozzle volume the extruder does not physically + // carry; the panel's validation timer reports that here so OK is gated on a printable map. + m_manual_map_panel->Bind(wxEVT_INVALID_MANUAL_MAP, [this](wxCommandEvent &event) { + if (m_page_type != PageType::ptManual) { + if (!m_ok_btn->IsEnabled()) { m_ok_btn->Enable(); } + return; + } + if (event.GetInt()) { + if (!m_ok_btn->IsEnabled()) { m_ok_btn->Enable(); } + } else { + if (m_ok_btn->IsEnabled()) { m_ok_btn->Disable(); } + } + }); + m_auto_map_panel = new FilamentMapAutoPanel(this, default_auto_mode, auto_match_available); if (show_default) m_default_map_panel = new FilamentMapDefaultPanel(this); else @@ -183,6 +291,13 @@ FilamentMapDialog::FilamentMapDialog(wxWindow *parent, if (show_default) panel_sizer->Add(m_default_map_panel, 0, wxEXPAND); main_sizer->Add(panel_sizer, 0, wxEXPAND); + // Smart filament section, shown only in filament-saving (flush) mode when the switch is ready. + if (m_fila_switch_ready) { + m_smart_filament = new SmartFilamentPanel(this); + m_smart_filament->Show(get_mode() == fmmAutoForFlush); + main_sizer->Add(m_smart_filament, 0, wxEXPAND); + } + wxPanel* bottom_panel = new wxPanel(this); bottom_panel->SetBackgroundColour(*wxWHITE); wxBoxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -271,16 +386,8 @@ void FilamentMapDialog::on_checkbox(wxCommandEvent &event) void FilamentMapDialog::on_ok(wxCommandEvent &event) { if (m_page_type == PageType::ptManual) { - std::vector left_filaments = m_manual_map_panel->GetLeftFilaments(); - std::vector right_filaments = m_manual_map_panel->GetRightFilaments(); - - for (int i = 0; i < m_filament_map.size(); ++i) { - if (std::find(left_filaments.begin(), left_filaments.end(), i + 1) != left_filaments.end()) { - m_filament_map[i] = 1; - } else if (std::find(right_filaments.begin(), right_filaments.end(), i + 1) != right_filaments.end()) { - m_filament_map[i] = 2; - } - } + m_filament_map = m_manual_map_panel->GetFilamentMaps(); + m_filament_volume_map = m_manual_map_panel->GetFilamentVolumeMaps(); } EndModal(wxID_OK); @@ -318,6 +425,14 @@ void FilamentMapDialog::update_panel_status(PageType page) m_auto_map_panel->Show(); } + // The nozzle-availability gate only constrains manual grouping; every other page must + // leave OK usable even if the manual page had disabled it. + if (page != PageType::ptManual && m_ok_btn && !m_ok_btn->IsEnabled()) + m_ok_btn->Enable(); + + if (m_smart_filament) + m_smart_filament->Show(get_mode() == fmmAutoForFlush); + Layout(); Fit(); } diff --git a/src/slic3r/GUI/FilamentMapDialog.hpp b/src/slic3r/GUI/FilamentMapDialog.hpp index 3272f203b3..fd1b056347 100644 --- a/src/slic3r/GUI/FilamentMapDialog.hpp +++ b/src/slic3r/GUI/FilamentMapDialog.hpp @@ -15,6 +15,7 @@ namespace GUI { class DragDropPanel; class Plater; class PartPlate; +class SmartFilamentPanel; /** * @brief Try to pop up the filament map dialog before slicing. @@ -42,6 +43,7 @@ public: const std::vector& filament_color, const std::vector& filament_type, const std::vector &filament_map, + const std::vector &filament_volume_map, const std::vector &filaments, const FilamentMapMode mode, bool machine_synced, @@ -56,6 +58,12 @@ public: return {}; } + std::vector get_filament_volume_maps() const { + if (m_page_type == PageType::ptManual) + return m_filament_volume_map; + return {}; + } + int ShowModal(); void set_modal_btn_labels(const wxString& left_label, const wxString& right_label); private: @@ -78,11 +86,15 @@ private: Button* m_ok_btn; Button* m_cancel_btn; CheckBox* m_checkbox; + SmartFilamentPanel* m_smart_filament{nullptr}; + + bool m_fila_switch_ready{false}; PageType m_page_type; private: std::vector m_filament_map; + std::vector m_filament_volume_map; std::vector m_filament_color; std::vector m_filament_type; }; diff --git a/src/slic3r/GUI/FilamentMapPanel.cpp b/src/slic3r/GUI/FilamentMapPanel.cpp index 59f6e5be6e..136258bc8e 100644 --- a/src/slic3r/GUI/FilamentMapPanel.cpp +++ b/src/slic3r/GUI/FilamentMapPanel.cpp @@ -1,5 +1,8 @@ #include "FilamentMapPanel.hpp" #include "GUI_App.hpp" +#include "Plater.hpp" +#include "Widgets/MultiNozzleSync.hpp" // manuallySetNozzleCount producer for extruder_nozzle_stats +#include #include #include #include "wx/graphics.h" @@ -17,28 +20,278 @@ static const wxColour BorderDisableColor = wxColour("#EEEEEE"); static const wxColour TextNormalBlackColor = wxColour("#262E30"); static const wxColour TextNormalGreyColor = wxColour("#6B6B6B"); static const wxColour TextDisableColor = wxColour("#CECECE"); +static const wxColour TextErrorColor = wxColour("#E14747"); + +wxDEFINE_EVENT(wxEVT_INVALID_MANUAL_MAP, wxCommandEvent); + +// Orca: whether the edited printer has an extruder that can physically carry several nozzles +// (only such extruders track a per-volume-type nozzle inventory worth validating against). +static bool printer_has_multi_nozzle_extruder() +{ + auto *max_nozzle_counts_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("extruder_max_nozzle_count"); + // Skip nil entries: a nullable-int nil is INT_MAX (> 1) and would otherwise falsely pass the gate. + return max_nozzle_counts_opt && + std::any_of(max_nozzle_counts_opt->values.begin(), max_nozzle_counts_opt->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); }); +} + +void FilamentMapManualPanel::OnTimer(wxTimerEvent &) +{ + bool valid = true; + int invalid_eid = -1; + NozzleVolumeType invalid_nozzle = NozzleVolumeType::nvtStandard; + auto preset_bundle = wxGetApp().preset_bundle; + auto proj_config = preset_bundle->project_config; + auto nozzle_volume_values = proj_config.option("nozzle_volume_type")->values; + std::vector filament_map = GetFilamentMaps(); + std::vector filament_volume_map = GetFilamentVolumeMaps(); + // Orca: only multi-nozzle extruders carry a meaningful nozzle inventory; validating a plain + // dual-extruder printer against it would flag every grouping whenever the stats are stale. + if (printer_has_multi_nozzle_extruder()) { + for (size_t eid = 0; eid < nozzle_volume_values.size(); ++eid) { + NozzleVolumeType extruder_volume_type = NozzleVolumeType(nozzle_volume_values[eid]); + bool extruder_used = std::find_if(m_filament_list.begin(), m_filament_list.end(), + [&filament_map, eid](int fid) { + return fid - 1 < (int) filament_map.size() && (filament_map[fid - 1] - 1) == (int) eid; + }) != m_filament_list.end(); + + if (!extruder_used) { + continue; + } + + if (extruder_volume_type == nvtHybrid) { + int standard_count = getExtruderNozzleCount(preset_bundle, eid, NozzleVolumeType::nvtStandard); + int highflow_count = getExtruderNozzleCount(preset_bundle, eid, NozzleVolumeType::nvtHighFlow); + + auto has_material_of_type = [this, eid, &filament_map, &filament_volume_map](NozzleVolumeType volume_type) { + return std::find_if(m_filament_list.begin(), m_filament_list.end(), + [eid, &filament_map, &filament_volume_map, volume_type](int fid) { + return fid - 1 < (int) filament_map.size() && (filament_map[fid - 1] - 1) == (int) eid && + fid - 1 < (int) filament_volume_map.size() && + filament_volume_map[fid - 1] == static_cast(volume_type); + }) != m_filament_list.end(); + }; + + bool has_standard = has_material_of_type(NozzleVolumeType::nvtStandard); + bool has_highflow = has_material_of_type(NozzleVolumeType::nvtHighFlow); + + if ((has_standard && standard_count == 0) || + (has_highflow && highflow_count == 0)) { + valid = false; + invalid_eid = eid; + invalid_nozzle = (has_standard && standard_count == 0) ? NozzleVolumeType::nvtStandard : NozzleVolumeType::nvtHighFlow; + break; + } + } else { + int count = getExtruderNozzleCount(preset_bundle, eid, extruder_volume_type); + if (count == 0) { + valid = false; + invalid_eid = eid; + invalid_nozzle = extruder_volume_type; + break; + } + } + } + } + + bool update_ui = m_invalid_id != invalid_eid; + bool send_event = update_ui || m_force_validation; + + m_invalid_id = invalid_eid; + + if (update_ui) { + if (valid) { + m_errors->Hide(); + m_suggestion_panel->Hide(); + } else { + m_errors->SetLabel(wxString::Format(_L("Error: %s extruder has no available %s nozzle, current group result is invalid."), + invalid_eid == 0 ? _L("Left") : _L("Right"), + invalid_nozzle == NozzleVolumeType::nvtStandard ? _L("Standard") : _L("High Flow"))); + // Re-wrap: wrapping only applies to the label text present when Wrap is called, + // and the label was empty at construction time. + m_errors->Wrap(FromDIP(520)); + m_errors->Show(); + m_suggestion_panel->Show(); + } + m_left_panel->Freeze(); + m_right_panel->Freeze(); + m_tips->Freeze(); + m_description->Freeze(); + Layout(); + Fit(); + this->GetParent()->Layout(); + this->GetParent()->Fit(); + m_left_panel->Thaw(); + m_right_panel->Thaw(); + m_tips->Thaw(); + m_description->Thaw(); + } + + if (send_event) { + wxCommandEvent event(wxEVT_INVALID_MANUAL_MAP); + event.SetInt(valid); + ProcessEvent(event); + m_force_validation = false; + } +} + +void FilamentMapManualPanel::OnSuggestionClicked(wxCommandEvent &event) +{ + wxWindow *current = this; + while (current && !wxDynamicCast(current, wxDialog)) { + current = current->GetParent(); + } + + if (current) { + wxDialog *dlg = wxDynamicCast(current, wxDialog); + if (dlg) { + int invalid_eid = m_invalid_id; + dlg->EndModal(wxID_CANCEL); + + if (invalid_eid >= 0) { + manuallySetNozzleCount(invalid_eid); + } + wxGetApp().plater()->update(); + } + } +} + +std::vector FilamentMapManualPanel::GetFilamentMaps() const +{ + std::vector new_filament_map = m_filament_map; + std::vector left_filaments = this->GetLeftFilaments(); + std::vector right_filaments = this->GetRightFilaments(); + + for (int i = 0; i < (int) new_filament_map.size(); ++i) { + if (std::find(left_filaments.begin(), left_filaments.end(), i + 1) != left_filaments.end()) { + new_filament_map[i] = 1; + } else if (std::find(right_filaments.begin(), right_filaments.end(), i + 1) != right_filaments.end()) { + new_filament_map[i] = 2; + } + } + return new_filament_map; +} + +std::vector FilamentMapManualPanel::GetFilamentVolumeMaps() const +{ + std::vector volume_map(m_filament_map.size(), 0); + + std::vector left_filaments = this->GetLeftFilaments(); + std::vector right_high_flow_filaments = this->GetRightHighFlowFilaments(); + std::vector right_standard_filaments = this->GetRightStandardFilaments(); + std::vector right_tpu_high_flow_filaments = this->GetRightTPUHighFlowFilaments(); + + auto preset_bundle = wxGetApp().preset_bundle; + auto proj_config = preset_bundle->project_config; + auto nozzle_volume_values = proj_config.option("nozzle_volume_type")->values; + + for (int i = 0; i < (int) volume_map.size(); ++i) { + int filament_id = i + 1; + + if (std::find(left_filaments.begin(), left_filaments.end(), filament_id) != left_filaments.end()) { + if (nozzle_volume_values.size() > 0) { + // Orca: never emit the Hybrid marker as a per-filament value; on a Hybrid + // extruder each filament prints with a concrete flow, defaulting to Standard. + volume_map[i] = nozzle_volume_values[0] == static_cast(NozzleVolumeType::nvtHybrid) ? + static_cast(NozzleVolumeType::nvtStandard) : + nozzle_volume_values[0]; + } + } + else if (std::find(right_high_flow_filaments.begin(), right_high_flow_filaments.end(), filament_id) != right_high_flow_filaments.end()) { + volume_map[i] = static_cast(NozzleVolumeType::nvtHighFlow); + } + else if (std::find(right_standard_filaments.begin(), right_standard_filaments.end(), filament_id) != right_standard_filaments.end()) { + volume_map[i] = static_cast(NozzleVolumeType::nvtStandard); + } + else if (std::find(right_tpu_high_flow_filaments.begin(), right_tpu_high_flow_filaments.end(), filament_id) != right_tpu_high_flow_filaments.end()) { + volume_map[i] = static_cast(NozzleVolumeType::nvtTPUHighFlow); + } + } + + return volume_map; +} + +void FilamentMapManualPanel::SyncPanelHeights() +{ + if (!m_left_panel || !m_right_panel) return; + + auto curr_left = m_left_panel->GetMinSize(); + auto curr_right = m_right_panel->GetMinSize(); + + m_left_panel->SetMinSize(wxSize(FromDIP(260), FromDIP(110))); + m_right_panel->SetMinSize(wxSize(FromDIP(260), FromDIP(110))); + + m_left_panel->Layout(); + m_left_panel->Fit(); + m_right_panel->Layout(); + m_right_panel->Fit(); + + wxSize left_best_size = m_left_panel->GetBestSize(); + wxSize right_best_size = m_right_panel->GetBestSize(); + + int max_height = std::max(left_best_size.GetHeight(), right_best_size.GetHeight()); + bool height_changed = curr_left.GetHeight() != max_height || curr_right.GetHeight() != max_height; + if (!height_changed) { + if (curr_left.GetHeight() > 0) + m_left_panel->SetMinSize(curr_left); + if (curr_right.GetHeight() > 0) + m_right_panel->SetMinSize(curr_right); + if (GetParent()) { + GetParent()->Layout(); + GetParent()->Fit(); + } + return; + } + + m_left_panel->SetMinSize(wxSize(FromDIP(260), max_height)); + m_right_panel->SetMinSize(wxSize(FromDIP(260), max_height)); + + Layout(); + Fit(); + + if (GetParent()) { + GetParent()->Layout(); + GetParent()->Fit(); + } +} + +void FilamentMapManualPanel::OnDragDropCompleted(wxCommandEvent &event) +{ + SyncPanelHeights(); + event.Skip(); +} FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *parent, const std::vector &color, const std::vector &type, const std::vector &filament_list, - const std::vector &filament_map) - : wxPanel(parent), m_filament_map(filament_map), m_filament_color(color), m_filament_type(type), m_filament_list(filament_list) + const std::vector &filament_map, + const std::vector &filament_volume_map) + : wxPanel(parent) + , m_filament_map(filament_map) + , m_filament_volume_map(filament_volume_map) + , m_filament_list(filament_list) + , m_filament_color(color) + , m_filament_type(type) { + SetName(wxT("FilamentMapManualPanel")); SetBackgroundColour(BgNormalColor); auto top_sizer = new wxBoxSizer(wxVERTICAL); m_description = new Label(this, _L("We will slice according to this grouping method:")); top_sizer->Add(m_description, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15)); + m_description->Wrap(FromDIP(520)); top_sizer->AddSpacer(FromDIP(8)); auto drag_sizer = new wxBoxSizer(wxHORIZONTAL); m_left_panel = new DragDropPanel(this, _L("Left Nozzle"), false); - m_right_panel = new DragDropPanel(this, _L("Right Nozzle"), false); + m_right_panel = new SeparatedDragDropPanel(this, _L("Right Nozzle"), false); m_switch_btn = new ScalableButton(this, wxID_ANY, "switch_filament_maps"); + UpdateNozzleVolumeType(); + for (size_t idx = 0; idx < m_filament_map.size(); ++idx) { auto iter = std::find(m_filament_list.begin(), m_filament_list.end(), idx + 1); if (iter == m_filament_list.end()) continue; @@ -48,43 +301,155 @@ FilamentMapManualPanel::FilamentMapManualPanel(wxWindow *p m_left_panel->AddColorBlock(color, type, idx + 1); } else { assert(m_filament_map[idx] == 2); - m_right_panel->AddColorBlock(color, type, idx + 1); + bool is_high_flow = (idx < m_filament_volume_map.size()) && (m_filament_volume_map[idx] == static_cast(NozzleVolumeType::nvtHighFlow)); + m_right_panel->AddColorBlock(color, type, idx + 1, is_high_flow); } } - m_left_panel->SetMinSize({ FromDIP(260),-1 }); - m_right_panel->SetMinSize({ FromDIP(260),-1 }); + m_left_panel->SetMinSize({FromDIP(260), FromDIP(110)}); + m_right_panel->SetMinSize({FromDIP(260), FromDIP(110)}); - drag_sizer->AddStretchSpacer(); drag_sizer->Add(m_left_panel, 1, wxEXPAND); - drag_sizer->AddSpacer(FromDIP(7)); - drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(1)); - drag_sizer->AddSpacer(FromDIP(7)); + drag_sizer->Add(m_switch_btn, 0, wxALIGN_CENTER | wxLEFT | wxRIGHT, FromDIP(8)); drag_sizer->Add(m_right_panel, 1, wxEXPAND); - drag_sizer->AddStretchSpacer(); top_sizer->Add(drag_sizer, 0, wxEXPAND); m_tips = new Label(this, _L("Tip: You can drag the filaments to reassign them to different nozzles.")); m_tips->SetFont(Label::Body_14); m_tips->SetForegroundColour(TextNormalGreyColor); + m_tips->Wrap(FromDIP(520)); top_sizer->AddSpacer(FromDIP(20)); top_sizer->Add(m_tips, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15)); + m_errors = new Label(this, ""); + m_errors->SetFont(Label::Body_13); + m_errors->SetForegroundColour(TextErrorColor); + m_errors->Wrap(FromDIP(520)); + top_sizer->AddSpacer(FromDIP(10)); + top_sizer->Add(m_errors, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15)); + + m_errors->Hide(); + + m_suggestion_panel = new wxPanel(this, wxID_ANY); + m_suggestion_panel->SetBackgroundColour(*wxWHITE); + auto suggestion_sizer = new wxBoxSizer(wxHORIZONTAL); + auto suggestion_text = new Label(m_suggestion_panel, _L("Please adjust your grouping or click ")); + suggestion_text->SetFont(Label::Body_13); + suggestion_text->SetForegroundColour(TextErrorColor); + suggestion_text->SetBackgroundColour(*wxWHITE); + auto suggestion_btn = new ScalableButton(m_suggestion_panel, wxID_ANY, "edit", wxEmptyString, wxDefaultSize, wxDefaultPosition, wxBU_EXACTFIT | wxNO_BORDER, true, 14); + suggestion_btn->SetBackgroundColour(*wxWHITE); + auto suggestion_text2 = new Label(m_suggestion_panel, _L(" to set nozzle count")); + suggestion_text2->SetFont(Label::Body_13); + suggestion_text2->SetForegroundColour(TextErrorColor); + suggestion_text2->SetBackgroundColour(*wxWHITE); + suggestion_sizer->Add(suggestion_text, 0, wxALIGN_CENTER_VERTICAL); + suggestion_sizer->Add(suggestion_btn, 0, wxALIGN_CENTER_VERTICAL); + suggestion_sizer->Add(suggestion_text2, 0, wxALIGN_CENTER_VERTICAL); + m_suggestion_panel->SetSizer(suggestion_sizer); + top_sizer->Add(m_suggestion_panel, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15)); + m_suggestion_panel->Hide(); + suggestion_btn->Bind(wxEVT_BUTTON, &FilamentMapManualPanel::OnSuggestionClicked, this); + + // Multi-nozzle: give the user a reachable way to declare, per extruder, how many + // physical nozzles of each volume type a multi-nozzle extruder carries. This is the + // fallback "manual" producer of the extruder_nozzle_stats config (the full device nozzle-rack + // auto-sync is deferred). Gated on the edited printer preset having an extruder with + // extruder_max_nozzle_count > 1, so the trigger is not even created for any single-nozzle or + // dual-extruder ({1,1}, H2D) printer - zero UI change for every existing profile. + if (printer_has_multi_nozzle_extruder()) { + auto *max_nozzle_counts_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("extruder_max_nozzle_count"); + auto *set_count_link = new Label(this, _L("Set the physical nozzle count...")); + set_count_link->SetFont(Label::Body_14); + set_count_link->SetForegroundColour(BorderSelectedColor); + set_count_link->SetCursor(wxCursor(wxCURSOR_HAND)); + top_sizer->AddSpacer(FromDIP(8)); + top_sizer->Add(set_count_link, 0, wxALIGN_LEFT | wxLEFT, FromDIP(15)); + const std::vector max_counts = max_nozzle_counts_opt->values; + set_count_link->Bind(wxEVT_LEFT_DOWN, [max_counts](wxMouseEvent &evt) { + for (int extruder_id = 0; extruder_id < (int) max_counts.size(); ++extruder_id) { + if (max_counts[extruder_id] > 1 && max_counts[extruder_id] != ConfigOptionIntsNullable::nil_value()) + GUI::manuallySetNozzleCount(extruder_id); + } + evt.Skip(); + }); + } + + m_timer = new wxTimer(this); + Bind(wxEVT_TIMER, &FilamentMapManualPanel::OnTimer, this); + Bind(wxEVT_DRAG_DROP_COMPLETED, &FilamentMapManualPanel::OnDragDropCompleted, this); + m_switch_btn->Bind(wxEVT_BUTTON, &FilamentMapManualPanel::OnSwitchFilament, this); SetSizer(top_sizer); + SetMinSize(wxSize(FromDIP(580), -1)); Layout(); Fit(); GUI::wxGetApp().UpdateDarkUIWin(this); } +void FilamentMapManualPanel::UpdateNozzleVolumeType() +{ + auto check_separation = []() { + auto preset_bundle = wxGetApp().preset_bundle; + auto nozzle_volume_values = preset_bundle->project_config.option("nozzle_volume_type")->values; + if (nozzle_volume_values.size() <= 1) + return false; + + return nozzle_volume_values[1] == static_cast(NozzleVolumeType::nvtHybrid); + }; + bool should_separate = check_separation(); + m_right_panel->SetUseSeparation(should_separate); + + UpdateNozzleCountDisplay(); + + Layout(); + Fit(); +} + +void FilamentMapManualPanel::UpdateNozzleCountDisplay() +{ + auto preset_bundle = wxGetApp().preset_bundle; + + // Orca: nozzle counts are only tracked (and only meaningful) for multi-nozzle extruders; + // plain dual-extruder printers keep their unadorned zone titles. + if (!printer_has_multi_nozzle_extruder()) { + m_left_panel->UpdateLabel(_L("Left Nozzle")); + m_right_panel->UpdateLabel(_L("Right Nozzle")); + return; + } + + // Format the count suffix separately so a translation containing '%' cannot + // corrupt the wxString::Format output. + int left_count = getExtruderNozzleCountTotal(preset_bundle, 0); + wxString left_title = _L("Left Nozzle") + wxString::Format("(%d)", left_count); + m_left_panel->UpdateLabel(left_title); + + if (m_right_panel->IsUseSeparation()) { + int standard_count = getExtruderNozzleCount(preset_bundle, 1, NozzleVolumeType::nvtStandard); + int highflow_count = getExtruderNozzleCount(preset_bundle, 1, NozzleVolumeType::nvtHighFlow); + wxString right_title = _L("Right Nozzle") + wxString::Format("(Std: %d, HF: %d)", standard_count, highflow_count); + m_right_panel->UpdateLabel(right_title); + } else { + int right_count = getExtruderNozzleCountTotal(preset_bundle, 1); + wxString right_title = _L("Right Nozzle") + wxString::Format("(%d)", right_count); + m_right_panel->UpdateLabel(right_title); + } +} + +FilamentMapManualPanel::~FilamentMapManualPanel() +{ + m_timer->Stop(); + delete m_timer; +} + void FilamentMapManualPanel::OnSwitchFilament(wxCommandEvent &) { auto left_blocks = m_left_panel->get_filament_blocks(); auto right_blocks = m_right_panel->get_filament_blocks(); for (auto &block : left_blocks) { - m_right_panel->AddColorBlock(block->GetColor(), block->GetType(), block->GetFilamentId(), false); + m_right_panel->AddColorBlock(block->GetColor(), block->GetType(), block->GetFilamentId(), false, false); m_left_panel->RemoveColorBlock(block, false); } @@ -94,22 +459,27 @@ void FilamentMapManualPanel::OnSwitchFilament(wxCommandEvent &) } this->GetParent()->Layout(); this->GetParent()->Fit(); + + if (m_right_panel->IsUseSeparation()) { + m_left_panel->Layout(); + m_left_panel->Fit(); + m_right_panel->Layout(); + m_right_panel->Fit(); + SyncPanelHeights(); + } } -void FilamentMapManualPanel::Hide() +bool FilamentMapManualPanel::Show(bool show) { - m_left_panel->Hide(); - m_right_panel->Hide(); - m_switch_btn->Hide(); - wxPanel::Hide(); -} + m_force_validation = show; + if (show) { + m_timer->Start(500); + SyncPanelHeights(); + } else { + m_timer->Stop(); + } -void FilamentMapManualPanel::Show() -{ - m_left_panel->Show(); - m_right_panel->Show(); - m_switch_btn->Show(); - wxPanel::Show(); + return wxPanel::Show(show); } GUI::FilamentMapBtnPanel::FilamentMapBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon) : wxPanel(parent) diff --git a/src/slic3r/GUI/FilamentMapPanel.hpp b/src/slic3r/GUI/FilamentMapPanel.hpp index ad5cefa459..a0caf8e78b 100644 --- a/src/slic3r/GUI/FilamentMapPanel.hpp +++ b/src/slic3r/GUI/FilamentMapPanel.hpp @@ -9,32 +9,60 @@ namespace Slic3r { namespace GUI { +// Fired by the manual panel's validation timer: the event int is 1 when the current manual +// grouping is printable with the installed nozzles, 0 when some zone has no matching nozzle. +wxDECLARE_EVENT(wxEVT_INVALID_MANUAL_MAP, wxCommandEvent); + class FilamentMapManualPanel : public wxPanel { public: - FilamentMapManualPanel(wxWindow *parent, const std::vector &color, const std::vector &type, const std::vector &filament_list, const std::vector &filament_map); + FilamentMapManualPanel(wxWindow *parent, + const std::vector &color, + const std::vector &type, + const std::vector &filament_list, + const std::vector &filament_map, + const std::vector &filament_volume_map); + ~FilamentMapManualPanel(); - std::vector GetFilamentMaps() const { return m_filament_map; } + std::vector GetFilamentMaps() const; + std::vector GetFilamentVolumeMaps() const; std::vector GetLeftFilaments() const { return m_left_panel->GetAllFilaments(); } std::vector GetRightFilaments() const { return m_right_panel->GetAllFilaments(); } - void Hide(); - void Show(); + std::vector GetRightHighFlowFilaments() const { return m_right_panel->GetHighFlowFilaments(); } + std::vector GetRightStandardFilaments() const { return m_right_panel->GetStandardFilaments(); } + std::vector GetRightTPUHighFlowFilaments() const { return m_right_panel->GetTPUHighFlowFilaments(); } + void UpdateNozzleVolumeType(); + void UpdateNozzleCountDisplay(); + + bool Show(bool show = true) override; private: - void OnSwitchFilament(wxCommandEvent &); - DragDropPanel *m_left_panel; - DragDropPanel *m_right_panel; + void OnTimer(wxTimerEvent &evt); + void OnSwitchFilament(wxCommandEvent &); + void SyncPanelHeights(); + void OnDragDropCompleted(wxCommandEvent &evt); + void OnSuggestionClicked(wxCommandEvent &event); - Label *m_description; - Label *m_tips; + DragDropPanel *m_left_panel; + SeparatedDragDropPanel *m_right_panel; + + Label *m_description; + Label *m_tips; + Label *m_errors; + wxPanel *m_suggestion_panel; ScalableButton *m_switch_btn; std::vector m_filament_map; + std::vector m_filament_volume_map; std::vector m_filament_list; std::vector m_filament_color; std::vector m_filament_type; + + wxTimer *m_timer; + int m_invalid_id{-1}; + bool m_force_validation{false}; }; class FilamentMapBtnPanel : public wxPanel diff --git a/src/slic3r/GUI/FileArchiveDialog.cpp b/src/slic3r/GUI/FileArchiveDialog.cpp index 18c804196f..982187211c 100644 --- a/src/slic3r/GUI/FileArchiveDialog.cpp +++ b/src/slic3r/GUI/FileArchiveDialog.cpp @@ -221,16 +221,7 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar std::vector> filtered_entries; // second is unzipped size for (mz_uint i = 0; i < num_entries; ++i) { if (mz_zip_reader_file_stat(archive, i, &stat)) { - std::string extra(1024, 0); - boost::filesystem::path path; - size_t extra_size = mz_zip_reader_get_filename_from_extra(archive, i, extra.data(), extra.size()); - if (extra_size > 0) { - path = boost::filesystem::path(extra.substr(0, extra_size)); - } else { - wxString wname = boost::nowide::widen(stat.m_filename); - std::string name = into_u8(wname); - path = boost::filesystem::path(name); - } + boost::filesystem::path path = Slic3r::decode_archive_entry_path(archive, stat); assert(!path.empty()); if (!path.has_extension()) continue; diff --git a/src/slic3r/GUI/GCodeViewer.cpp b/src/slic3r/GUI/GCodeViewer.cpp index 150a40dc0d..3b3d4248e3 100644 --- a/src/slic3r/GUI/GCodeViewer.cpp +++ b/src/slic3r/GUI/GCodeViewer.cpp @@ -445,7 +445,7 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode add_row(_u8L("Flow rate"), buff); sprintf(buff, "%.0f %%", vertex.fan_speed); add_row(_u8L("Fan speed"), buff); - sprintf(buff, ("%.0f " + _u8L("°C")).c_str(), vertex.temperature); + sprintf(buff, ("%.0f " + _u8L("\u2103" /* °C */)).c_str(), vertex.temperature); add_row(_u8L("Temperature"), buff); sprintf(buff, "%.4f", vertex.pressure_advance); add_row(_u8L("Pressure Advance"), buff); @@ -489,7 +489,7 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode const float main_row_h = 2.0f * text_h + item_spacing_y; // Two lines of text (position and detail) + spacing between them const float properties_h = static_cast(properties_rows.size()) * (text_h + 2.0f * cell_pad_y) + 2.0f * cell_pad_y + 1.0f + item_spacing_y // table rows + item_spacing_y + show_button_h // Spacing() + Show/Hide button row - + item_spacing_y + 1.0f + style.FramePadding.y; // Spacing() + Separator() + Dummy() + + item_spacing_y + 1.0f + style.WindowPadding.y; // Spacing() + Separator() + Dummy() const float folded_window_h = std::ceil(window_pad_h + main_row_h); // Height of the window when properties are hidden, with padding, rounded up for better look const float unfolded_window_h = std::ceil(folded_window_h + properties_h); // Height of the window when properties are shown, with padding, rounded up for better look const float window_h = properties_shown ? unfolded_window_h : folded_window_h; // Final window height depending on whether properties are shown or not @@ -615,9 +615,12 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode ImGui::Spacing(); ImGui::Separator(); - ImGui::Dummy({0, style.FramePadding.y}); + ImGui::Dummy({0, style.WindowPadding.y}); } + float draw_area_height = ImGui::GetTextLineHeight() * 2.f + style.ItemSpacing.y; + ImGui::Dummy({10.f, draw_area_height}); // reserve area + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding , 3.f * m_scale); ImGui::PushStyleVar(ImGuiStyleVar_FramePadding , ImVec2(2.f, 2.f) * m_scale); ImGui::PushStyleColor(ImGuiCol_Button , ImVec4(0, 0, 0, 0)); @@ -625,6 +628,10 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode ImGui::PushStyleColor(ImGuiCol_ButtonActive , ImVec4(84 / 255.f, 84 / 255.f, 90 / 255.f, 1.f)); const float main_wnd_height = ImGui::GetWindowHeight(); + const float draw_start_y = main_wnd_height - draw_area_height - style.WindowPadding.y; + + ImGui::SetCursorPos(ImVec2(style.WindowPadding.x, draw_start_y)); + // 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)) { @@ -640,10 +647,7 @@ void GCodeViewer::SequentialView::Marker::render_position_window(const libvgcode ImGui::PopStyleColor(3); ImGui::PopStyleVar(2); - ImGui::SameLine(); - - if(!properties_shown) - ImGui::SetCursorPosY(ImGui::GetCursorPosY() - style.FramePadding.y); // aligns button with next group + ImGui::SetCursorPos(ImVec2(style.WindowPadding.x + style.ItemSpacing.x + 24.f * m_scale, draw_start_y - 1.f * m_scale)); ImGui::BeginGroup(); // group contents to make information area more compact @@ -2911,8 +2915,11 @@ void GCodeViewer::render_legend_color_arr_recommen(float window_padding) float delta_weight_to_single_ext = stats_by_extruder.stats_by_single_extruder.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_curr.filament_flush_weight; float delta_weight_to_best = stats_by_extruder.stats_by_multi_extruder_curr.filament_flush_weight - stats_by_extruder.stats_by_multi_extruder_best.filament_flush_weight; - int delta_change_to_single_ext = stats_by_extruder.stats_by_single_extruder.filament_change_count - stats_by_extruder.stats_by_multi_extruder_curr.filament_change_count; - int delta_change_to_best = stats_by_extruder.stats_by_multi_extruder_curr.filament_change_count - stats_by_extruder.stats_by_multi_extruder_best.filament_change_count; + // The displayed "hand changes" delta uses the per-nozzle flush_filament_change_count. + // For single-nozzle-per-extruder printers it equals the per-extruder filament_change_count, + // so the shown value is unchanged. + int delta_change_to_single_ext = stats_by_extruder.stats_by_single_extruder.flush_filament_change_count - stats_by_extruder.stats_by_multi_extruder_curr.flush_filament_change_count; + int delta_change_to_best = stats_by_extruder.stats_by_multi_extruder_curr.flush_filament_change_count - stats_by_extruder.stats_by_multi_extruder_best.flush_filament_change_count; bool any_less_to_single_ext = delta_weight_to_single_ext > EPSILON || delta_change_to_single_ext > 0; bool any_more_to_best = delta_weight_to_best > EPSILON || delta_change_to_best > 0; @@ -3704,7 +3711,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv break; } case libvgcode::EViewType::FanSpeed: { imgui.title(_u8L("Fan speed (%)")); break; } - case libvgcode::EViewType::Temperature: { imgui.title(_u8L("Temperature (°C)")); break; } + case libvgcode::EViewType::Temperature: { imgui.title(_u8L("Temperature (℃)")); break; } // ORCA: Add Pressure Advance visualization support case libvgcode::EViewType::PressureAdvance:{ imgui.title(_u8L("Pressure Advance")); break; } case libvgcode::EViewType::VolumetricFlowRate: @@ -4258,7 +4265,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv }; auto append_print = [&imgui, imperial_units](const ColorRGBA& color, const std::array& offsets, const Times& times, std::pair used_filament) { - imgui.text(_u8L("Print")); + imgui.text(_CTX_utf8("Print", "Noun")); ImGui::SameLine(); float icon_size = ImGui::GetTextLineHeight(); @@ -4292,7 +4299,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv for (const PartialTime& item : partial_times) { switch (item.type) { - case PartialTime::EType::Print: { labels.push_back(_u8L("Print")); break; } + case PartialTime::EType::Print: { labels.push_back(_CTX_utf8("Print", "Noun")); break; } case PartialTime::EType::Pause: { labels.push_back(_u8L("Pause")); break; } case PartialTime::EType::ColorChange: { labels.push_back(_u8L("Color change")); break; } } diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index 4237632393..ceb09426a3 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -1231,6 +1231,14 @@ GLCanvas3D::~GLCanvas3D() glsafe(::glDeleteTextures(1, &m_ssao_depth_texture_id)); m_ssao_depth_texture_id = 0; } + if (m_shadow_map_texture_id != 0) { + glsafe(::glDeleteTextures(1, &m_shadow_map_texture_id)); + m_shadow_map_texture_id = 0; + } + if (m_shadow_map_fbo != 0) { + glsafe(::glDeleteFramebuffers(1, &m_shadow_map_fbo)); + m_shadow_map_fbo = 0; + } m_plate_shadow_mask.reset(); } m_plate_shadow_mask_key.clear(); @@ -2033,6 +2041,9 @@ void GLCanvas3D::render(bool only_init) // draw scene glsafe(::glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)); + // Invalidate the shadow map each frame; only the View3D path below rebuilds it. This keeps + // the Preview / Assemble canvases from sampling a stale map with an outdated light matrix. + m_shadow_map_valid = false; _render_background(); //BBS add partplater rendering logic @@ -2057,7 +2068,8 @@ void GLCanvas3D::render(bool only_init) _render_platelist(camera.get_view_matrix(), camera.get_projection_matrix(), !camera.is_looking_downward(), only_current, only_body, hover_id, true, show_grid); //BBS: add outline logic - _render_cast_shadows_on_plate(camera.get_view_matrix(), camera.get_projection_matrix()); + // Depth pass for object-on-object and self shadows; consumed by the gouraud shader below. + _render_shadows(camera.get_view_matrix(), camera.get_projection_matrix()); _render_objects(GLVolumeCollection::ERenderType::Opaque, !m_gizmos.is_running()); _render_sla_slices(); _render_selection(); @@ -2326,11 +2338,6 @@ void GLCanvas3D::remove_curr_plate_all() m_dirty = true; } -void GLCanvas3D::update_plate_thumbnails() -{ - _update_imgui_select_plate_toolbar(); -} - void GLCanvas3D::select_all() { if (!m_gizmos.is_allow_select_all()) { @@ -3211,7 +3218,6 @@ void GLCanvas3D::on_idle(wxIdleEvent& evt) // BBS //m_dirty |= wxGetApp().plater()->get_view_toolbar().update_items_state(); m_dirty |= wxGetApp().plater()->get_collapse_toolbar().update_items_state(); - _update_imgui_select_plate_toolbar(); bool mouse3d_controller_applied = wxGetApp().plater()->get_mouse3d_controller().apply(wxGetApp().plater()->get_camera()); m_dirty |= mouse3d_controller_applied; m_dirty |= wxGetApp().plater()->get_notification_manager()->update_notifications(*this); @@ -4821,11 +4827,6 @@ void GLCanvas3D::force_set_focus() { void GLCanvas3D::on_set_focus(wxFocusEvent& evt) { m_tooltip_enabled = false; - if (m_canvas_type == ECanvasType::CanvasPreview) { - // update thumbnails and update plate toolbar - wxGetApp().plater()->update_all_plate_thumbnails(); - _update_imgui_select_plate_toolbar(); - } _refresh_if_shown_on_screen(); m_tooltip_enabled = true; m_is_touchpad_navigation = wxGetApp().app_config->get_bool("camera_navigation_style"); @@ -6036,11 +6037,11 @@ void GLCanvas3D::_render_3d_navigator() strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Y], "Z"); // ORCA use uppercase to match text on tranform widgets strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Z], "X"); // ORCA use uppercase to match text on tranform widgets strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_FRONT], _utf8("Front").c_str()); - strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BACK], _utf8("Back").c_str()); + strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BACK], _CTX_utf8("Back", "Camera View").c_str()); strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_TOP], _utf8("Top").c_str()); strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BOTTOM], _utf8("Bottom").c_str()); - strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_LEFT], _CTX_utf8(L_CONTEXT("Left", "Camera"), "Camera").c_str()); - strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_RIGHT], _CTX_utf8(L_CONTEXT("Right", "Camera"), "Camera").c_str()); + strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_LEFT], _CTX_utf8("Left", "Camera View").c_str()); + strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_RIGHT], _CTX_utf8("Right", "Camera View").c_str()); float sc = get_scale(); #ifdef WIN32 @@ -6908,13 +6909,28 @@ void GLCanvas3D::_update_select_plate_toolbar_stats_item(bool force_selected) { bool GLCanvas3D::_update_imgui_select_plate_toolbar() { bool result = true; - if (!m_sel_plate_toolbar.is_enabled() || m_sel_plate_toolbar.is_render_finish) return false; + if (!m_sel_plate_toolbar.is_enabled()) { + return false; + } + + const auto& p_plater = wxGetApp().plater(); + if (!p_plater) { + return false; + } + + if (!p_plater->is_plate_toolbar_image_dirty()) { + return false; + } + + if (!p_plater->is_gcode_3mf()) { + p_plater->update_all_plate_thumbnails(true); + } _update_select_plate_toolbar_stats_item(); m_sel_plate_toolbar.del_all_item(); - PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); + PartPlateList& plate_list = p_plater->get_partplate_list(); for (int i = 0; i < plate_list.get_plate_count(); i++) { IMToolbarItem* item = new IMToolbarItem(); PartPlate* plate = plate_list.get_plate(i); @@ -6927,7 +6943,7 @@ bool GLCanvas3D::_update_imgui_select_plate_toolbar() } m_sel_plate_toolbar.m_items.push_back(item); } - + p_plater->clear_plate_toolbar_image_dirty(); m_sel_plate_toolbar.is_display_scrollbar = false; return result; } @@ -7858,9 +7874,8 @@ void GLCanvas3D::_render_platelist(const Transform3d& view_matrix, const Transfo wxGetApp().plater()->get_partplate_list().render(view_matrix, projection_matrix, bottom, only_current, only_body, hover_id, render_cali, show_grid); } -void GLCanvas3D::_render_cast_shadows_on_plate(const Transform3d& view_matrix, const Transform3d& projection_matrix) +void GLCanvas3D::_render_shadows(const Transform3d& view_matrix, const Transform3d& projection_matrix) { - // Check if shadow rendering is enabled in configuration if (wxGetApp().app_config == nullptr) return; if (!wxGetApp().app_config->get_bool(SETTING_OPENGL_REALISTIC_MODE)) @@ -7874,54 +7889,181 @@ void GLCanvas3D::_render_cast_shadows_on_plate(const Transform3d& view_matrix, c if (shader == nullptr) return; - // Fixed light direction (pointing downward at an angle) - // Drive shadow direction from current view angle: define light in eye-space, - // then transform it to world-space with inverse view rotation. - const Vec3d light_dir_eye = Vec3d(-0.4574957, 0.4574957, 0.7624929).normalized(); - const Matrix3d view_rot = view_matrix.matrix().block<3, 3>(0, 0); - const Vec3d light_dir_to_light = (view_rot.transpose() * light_dir_eye).normalized(); - const Vec3d ray_dir = -light_dir_to_light; // Direction of shadow projection - - if (std::abs(ray_dir.z()) < 1e-6) + if (OpenGLManager::get_framebuffers_type() == OpenGLManager::EFramebufferType::Arb) { + + // Light direction (same as used in shading and plate shading) + const Vec3d light_dir_eye = Vec3d(-0.4574957, 0.4574957, 0.7624929).normalized(); + const Matrix3d view_rot = view_matrix.matrix().block<3, 3>(0, 0); + const Vec3d dir_to_light = (view_rot.transpose() * light_dir_eye).normalized(); + + // Bounding box of the printable objects (the shadow casters). + BoundingBoxf3 obj_bb; + for (const GLVolume* volume : m_volumes.volumes) { + if (volume == nullptr || !volume->is_active || !volume->printable || volume->is_modifier || volume->is_wipe_tower) + continue; + obj_bb.merge(volume->transformed_bounding_box()); + } + if (!obj_bb.defined) + return; // no objects to cast shadows + + // Orthographic light-space basis (z points toward the light). + const Vec3d up = (std::abs(dir_to_light.z()) > 0.99) ? Vec3d::UnitY() : Vec3d::UnitZ(); + const Vec3d z_axis = dir_to_light; + const Vec3d x_axis = up.cross(z_axis).normalized(); + const Vec3d y_axis = z_axis.cross(x_axis).normalized(); + + // Fit the frustum to the object AABB *and* the object's shadow projected onto the plate + // (clamped to the plate footprint). This keeps the map tight/high-res for short shadows + // while still covering long shadows at grazing light angles, which previously fell outside + // the map and were clipped. + const Vec3d ray_dir = -dir_to_light; // direction the shadow travels + const BoundingBoxf3 plate_bb = m_bed.build_volume().valid() ? m_bed.build_volume().bounding_volume() : obj_bb; + + Vec3d lmin(DBL_MAX, DBL_MAX, DBL_MAX); + Vec3d lmax(-DBL_MAX, -DBL_MAX, -DBL_MAX); + auto enclose = [&](const Vec3d& p) { + const Vec3d lp(x_axis.dot(p), y_axis.dot(p), z_axis.dot(p)); + lmin = lmin.cwiseMin(lp); + lmax = lmax.cwiseMax(lp); + }; + for (int i = 0; i < 8; ++i) { + const Vec3d corner((i & 1) ? obj_bb.max.x() : obj_bb.min.x(), + (i & 2) ? obj_bb.max.y() : obj_bb.min.y(), + (i & 4) ? obj_bb.max.z() : obj_bb.min.z()); + enclose(corner); + // Where this corner's shadow lands on z = 0, clamped to the plate so a grazing angle + // (t -> infinity) stays bounded. + if (ray_dir.z() < -1e-6) { + const double t = -corner.z() / ray_dir.z(); + Vec3d s = corner + t * ray_dir; + s.x() = std::min(std::max(s.x(), plate_bb.min.x()), plate_bb.max.x()); + s.y() = std::min(std::max(s.y(), plate_bb.min.y()), plate_bb.max.y()); + s.z() = 0.0; + enclose(s); + } + } + + // Light "camera" placed just past the nearest enclosed point, looking toward the scene. + const double range = lmax.z() - lmin.z(); + const double margin = std::max(1.0, 0.05 * range); + const double cx = 0.5 * (lmin.x() + lmax.x()); + const double cy = 0.5 * (lmin.y() + lmax.y()); + const Vec3d eye = x_axis * cx + y_axis * cy + z_axis * (lmax.z() + margin); + + Matrix4d light_view = Matrix4d::Identity(); + light_view.block<1, 3>(0, 0) = x_axis.transpose(); + light_view.block<1, 3>(1, 0) = y_axis.transpose(); + light_view.block<1, 3>(2, 0) = z_axis.transpose(); + light_view(0, 3) = -x_axis.dot(eye); + light_view(1, 3) = -y_axis.dot(eye); + light_view(2, 3) = -z_axis.dot(eye); + + // Ortho fit to the light-space extent (symmetric in X/Y around cx,cy; +2% edge padding). + const double halfx = std::max(0.5 * (lmax.x() - lmin.x()), 1.0) * 1.02; + const double halfy = std::max(0.5 * (lmax.y() - lmin.y()), 1.0) * 1.02; + const double near_z = margin * 0.5; + const double far_z = range + margin * 1.5; + Matrix4d light_proj = Matrix4d::Identity(); + light_proj(0, 0) = 1.0 / halfx; + light_proj(1, 1) = 1.0 / halfy; + light_proj(2, 2) = -2.0 / (far_z - near_z); + light_proj(2, 3) = -(far_z + near_z) / (far_z - near_z); + + m_shadow_light_vp = Transform3d(light_proj * light_view); + + // Create / resize the depth texture and FBO + const unsigned int size = 2048; + if (m_shadow_map_texture_id == 0) { + glsafe(::glGenTextures(1, &m_shadow_map_texture_id)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_shadow_map_texture_id)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)); + glsafe(::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)); + const float border[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + glsafe(::glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border)); + m_shadow_map_size = 0; + } + if (m_shadow_map_size != size) { + glsafe(::glBindTexture(GL_TEXTURE_2D, m_shadow_map_texture_id)); + glsafe(::glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, size, size, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr)); + m_shadow_map_size = size; + } + if (m_shadow_map_fbo == 0) + glsafe(::glGenFramebuffers(1, &m_shadow_map_fbo)); + + // Save OpenGL state that we will modify + GLint prev_viewport[4] = { 0, 0, 0, 0 }; + glsafe(::glGetIntegerv(GL_VIEWPORT, prev_viewport)); + GLint prev_fbo = 0; + glsafe(::glGetIntegerv(GL_FRAMEBUFFER_BINDING, &prev_fbo)); + GLboolean prev_color_mask[4] = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; + glsafe(::glGetBooleanv(GL_COLOR_WRITEMASK, prev_color_mask)); + const GLboolean prev_cull = ::glIsEnabled(GL_CULL_FACE); + GLint prev_depth_func = GL_LESS; + glsafe(::glGetIntegerv(GL_DEPTH_FUNC, &prev_depth_func)); + GLboolean prev_depth_mask = GL_TRUE; + glsafe(::glGetBooleanv(GL_DEPTH_WRITEMASK, &prev_depth_mask)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, m_shadow_map_fbo)); + glsafe(::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_shadow_map_texture_id, 0)); + glsafe(::glDrawBuffer(GL_NONE)); + glsafe(::glReadBuffer(GL_NONE)); + + if (::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) { + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, static_cast(prev_fbo))); + m_shadow_map_valid = false; + } else { + glsafe(::glViewport(0, 0, size, size)); + glsafe(::glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)); + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glDepthMask(GL_TRUE)); + glsafe(::glDepthFunc(GL_LESS)); + glsafe(::glClear(GL_DEPTH_BUFFER_BIT)); + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(4.0f, 4.0f)); + glsafe(::glDisable(GL_CULL_FACE)); + + shader->start_using(); + shader->set_uniform("projection_matrix", Transform3d(light_proj)); + for (GLVolume* volume : m_volumes.volumes) { + if (volume == nullptr || !volume->is_active || !volume->printable || volume->is_modifier || volume->is_wipe_tower) + continue; + const Transform3d view_model = Transform3d(light_view) * volume->world_matrix(); + shader->set_uniform("view_model_matrix", view_model); + volume->model.render(shader); + } + shader->stop_using(); + + // Restore state + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glColorMask(prev_color_mask[0], prev_color_mask[1], prev_color_mask[2], prev_color_mask[3])); + if (prev_cull) + glsafe(::glEnable(GL_CULL_FACE)); + else + glsafe(::glDisable(GL_CULL_FACE)); + glsafe(::glDepthFunc(prev_depth_func)); + glsafe(::glDepthMask(prev_depth_mask)); + glsafe(::glBindFramebuffer(GL_FRAMEBUFFER, static_cast(prev_fbo))); + glsafe(::glViewport(prev_viewport[0], prev_viewport[1], prev_viewport[2], prev_viewport[3])); + + m_shadow_map_valid = true; + } + } else { + m_shadow_map_valid = false; + } + + // ---------------------------------------------------------------------------------- + // Unified plate shadow: draw the build-plate footprint and darken it wherever the same + // depth shadow map (built above) says the light is occluded. This replaces the old planar + // stencil projection so plate, object and self shadows all come from one technique. + // ---------------------------------------------------------------------------------- + if (!m_shadow_map_valid) return; - // Shadow projection matrix - flattens geometry onto Z=0 plane along light direction - Matrix4d shadow_proj = Matrix4d::Identity(); - shadow_proj(0, 2) = -ray_dir.x() / ray_dir.z(); - shadow_proj(1, 2) = -ray_dir.y() / ray_dir.z(); - shadow_proj(2, 0) = 0.0; - shadow_proj(2, 1) = 0.0; - shadow_proj(2, 2) = 0.0; - shadow_proj(2, 3) = 0.01; // Bias to prevent shadow acne + GLShaderProgram* plate_shader = wxGetApp().get_shader("printbed_shadow"); + if (plate_shader == nullptr) + return; - // Save OpenGL state - GLint prev_depth_func = GL_LESS; - glsafe(::glGetIntegerv(GL_DEPTH_FUNC, &prev_depth_func)); - GLboolean prev_depth_mask = GL_TRUE; - glsafe(::glGetBooleanv(GL_DEPTH_WRITEMASK, &prev_depth_mask)); - GLint prev_stencil_mask = 0xFF; - glsafe(::glGetIntegerv(GL_STENCIL_WRITEMASK, &prev_stencil_mask)); - GLboolean prev_stencil_test = GL_FALSE; - glsafe(::glGetBooleanv(GL_STENCIL_TEST, &prev_stencil_test)); - - // ============================================================ - // PASS 0: Create stencil mask for the build plate (value = 1) - // ============================================================ - glsafe(::glEnable(GL_STENCIL_TEST)); - glsafe(::glStencilMask(0xFF)); - glsafe(::glClearStencil(0)); - glsafe(::glClear(GL_STENCIL_BUFFER_BIT)); - - glsafe(::glStencilFunc(GL_ALWAYS, 1, 0xFF)); - glsafe(::glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE)); - - glsafe(::glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)); - glsafe(::glDisable(GL_DEPTH_TEST)); - - shader->start_using(); - shader->set_uniform("projection_matrix", projection_matrix); - - // Draw the build plate (cached model to avoid per-frame uploads) if (const BuildVolume& build_volume = m_bed.build_volume(); build_volume.valid()) { const std::string mask_key = build_volume.type() == BuildVolume_Type::Rectangle ? (boost::format("rect|%1$.5f|%2$.5f|%3$.5f|%4$.5f") @@ -7977,87 +8119,49 @@ void GLCanvas3D::_render_cast_shadows_on_plate(const Transform3d& view_matrix, c } if (m_plate_shadow_mask.is_initialized()) { - shader->set_uniform("view_model_matrix", view_matrix); - m_plate_shadow_mask.render(shader); + // Blend the shadow over the already-drawn plate. Depth test keeps it behind anything + // already in front; depth writes are off, and a small negative polygon offset lifts it + // just above the bed to avoid z-fighting. + GLboolean prev_depth_mask = GL_TRUE; + glsafe(::glGetBooleanv(GL_DEPTH_WRITEMASK, &prev_depth_mask)); + GLint prev_depth_func = GL_LESS; + glsafe(::glGetIntegerv(GL_DEPTH_FUNC, &prev_depth_func)); + + glsafe(::glEnable(GL_DEPTH_TEST)); + glsafe(::glDepthMask(GL_FALSE)); + glsafe(::glDepthFunc(GL_LEQUAL)); + glsafe(::glEnable(GL_BLEND)); + glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); + glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glPolygonOffset(-1.0f, -1.0f)); + + glsafe(::glActiveTexture(GL_TEXTURE4)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_shadow_map_texture_id)); + glsafe(::glActiveTexture(GL_TEXTURE0)); + + plate_shader->start_using(); + plate_shader->set_uniform("view_model_matrix", view_matrix); + plate_shader->set_uniform("projection_matrix", projection_matrix); + plate_shader->set_uniform("shadow_map", 4); + plate_shader->set_uniform("shadow_light_vp", m_shadow_light_vp); + plate_shader->set_uniform("shadow_intensity", 0.35f); + plate_shader->set_uniform("shadow_map_texel", 1.0f / static_cast(m_shadow_map_size)); + m_plate_shadow_mask.render(plate_shader); + plate_shader->stop_using(); + + glsafe(::glActiveTexture(GL_TEXTURE4)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); + glsafe(::glActiveTexture(GL_TEXTURE0)); + + glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); + glsafe(::glDisable(GL_BLEND)); + glsafe(::glDepthFunc(prev_depth_func)); + glsafe(::glDepthMask(prev_depth_mask)); } } - - // ============================================================ - // PASS 1: Project object shadows onto plate (increment stencil to 2) - // ============================================================ - // Only render where plate exists (stencil == 1), then increment to 2 - glsafe(::glStencilFunc(GL_EQUAL, 1, 0xFF)); - glsafe(::glStencilOp(GL_KEEP, GL_KEEP, GL_INCR)); - - glsafe(::glDepthMask(GL_FALSE)); - glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glDepthFunc(GL_ALWAYS)); // Shadows don't need depth testing - glsafe(::glEnable(GL_POLYGON_OFFSET_FILL)); - glsafe(::glPolygonOffset(-2.0f, -2.0f)); - glsafe(::glDisable(GL_CULL_FACE)); - - // Render projected shadow geometry - for (GLVolume* volume : m_volumes.volumes) { - if (volume == nullptr || !volume->is_active || !volume->printable || volume->is_modifier || volume->is_wipe_tower) - continue; - - // CRITICAL FIX: Apply shadow projection in object's local space, then to world, then to view - // This ensures shadows are cast from the object's actual position - Matrix4d world_matrix = volume->world_matrix().matrix(); - - // Project the shadow - this flattens the geometry onto Z=0 in WORLD space - Matrix4d shadow_world_matrix = shadow_proj * world_matrix; - - // Transform to view space for rendering - Matrix4d view_shadow_matrix = view_matrix.matrix() * shadow_world_matrix; - - shader->set_uniform("view_model_matrix", view_shadow_matrix); - shader->set_uniform("projection_matrix", projection_matrix); - - volume->model.render(shader); - } - - // ============================================================ - // PASS 2: Draw shadow color where stencil == 2 - // ============================================================ - glsafe(::glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)); - glsafe(::glStencilFunc(GL_EQUAL, 2, 0xFF)); - glsafe(::glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP)); - glsafe(::glStencilMask(0x00)); - - glsafe(::glDepthFunc(GL_ALWAYS)); - glsafe(::glEnable(GL_BLEND)); - glsafe(::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); - - // Draw shadow fill - shader->set_uniform("view_model_matrix", Transform3d::Identity()); - shader->set_uniform("projection_matrix", Transform3d::Identity()); - - const ColorRGBA shadow_fill_color(0.0f, 0.0f, 0.0f, 0.4f); // Darker shadow for visibility - const ColorRGBA prev_bg_color = m_background.get_geometry().color; - m_background.set_color(shadow_fill_color); - shader->set_uniform("uniform_color", shadow_fill_color); - m_background.render(shader); - m_background.set_color(prev_bg_color); - shader->set_uniform("uniform_color", prev_bg_color); - - shader->stop_using(); - - // ============================================================ - // RESTORE STATE - // ============================================================ - glsafe(::glEnable(GL_DEPTH_TEST)); - glsafe(::glDepthMask(prev_depth_mask)); - glsafe(::glDepthFunc(prev_depth_func)); - glsafe(::glEnable(GL_CULL_FACE)); - glsafe(::glDisable(GL_POLYGON_OFFSET_FILL)); - glsafe(::glDisable(GL_BLEND)); - - if (!prev_stencil_test) - glsafe(::glDisable(GL_STENCIL_TEST)); - glsafe(::glStencilMask(prev_stencil_mask)); } + void GLCanvas3D::_render_plane() const { ;//TODO render assemble plane @@ -8136,12 +8240,31 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with shader = wxGetApp().get_shader("gouraud"); ECanvasType canvas_type = this->m_canvas_type; bool partly_inside_enable = canvas_type == ECanvasType::CanvasAssembleView ? false : true; + // The edited printer's per-extruder printable heights feed the object shader's + // extruder_printable_heights uniform. Empty for single-extruder printers, so the shader flag stays + // 0.0 and rendering is pixel-identical there (see GLVolumeCollection::render). + auto printable_height_option = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("extruder_printable_height"); + std::vector* printable_heights = printable_height_option ? &printable_height_option->values : nullptr; if (shader != nullptr) { shader->start_using(); const bool phong_ssao = wxGetApp().app_config != nullptr && wxGetApp().app_config->get_bool(SETTING_OPENGL_PHONG_SSAO); shader->set_uniform("enable_ssao", phong_ssao); + // Object-on-object and self shadows: sample the depth map built in _render_shadow_map_pass(). + // shadow_intensity == 0 disables the effect entirely (unchanged behavior when off / unsupported). + if (m_shadow_map_valid && m_shadow_map_texture_id != 0) { + glsafe(::glActiveTexture(GL_TEXTURE4)); + glsafe(::glBindTexture(GL_TEXTURE_2D, m_shadow_map_texture_id)); + glsafe(::glActiveTexture(GL_TEXTURE0)); + shader->set_uniform("shadow_map", 4); + shader->set_uniform("shadow_light_vp", m_shadow_light_vp); + shader->set_uniform("shadow_map_texel", 1.0f / static_cast(m_shadow_map_size)); + shader->set_uniform("shadow_intensity", 0.35f); + } + else + shader->set_uniform("shadow_intensity", 0.0f); + const Size& cvn_size = get_canvas_size(); { const Camera& camera = wxGetApp().plater()->get_camera(); @@ -8183,7 +8306,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with return (m_render_sla_auxiliaries || volume.composite_id.volume_id >= 0); } }, - partly_inside_enable); + partly_inside_enable, printable_heights); } } else { @@ -8218,7 +8341,7 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with return true; } }, - partly_inside_enable); + partly_inside_enable, printable_heights); if (m_canvas_type == CanvasAssembleView && m_gizmos.m_assemble_view_data->model_objects_clipper()->get_position() > 0) { const GLGizmosManager& gm = get_gizmos_manager(); shader->stop_using(); @@ -8233,6 +8356,12 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type, bool with shader->set_uniform("show_wireframe", false); }*/ + if (m_shadow_map_valid && m_shadow_map_texture_id != 0) { + glsafe(::glActiveTexture(GL_TEXTURE4)); + glsafe(::glBindTexture(GL_TEXTURE_2D, 0)); + glsafe(::glActiveTexture(GL_TEXTURE0)); + } + shader->stop_using(); } @@ -8672,6 +8801,8 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() return; } + _update_imgui_select_plate_toolbar(); + IMToolbarItem* all_plates_stats_item = m_sel_plate_toolbar.m_all_plates_stats_item; PartPlateList& plate_list = wxGetApp().plater()->get_partplate_list(); @@ -9088,7 +9219,6 @@ void GLCanvas3D::_render_imgui_select_plate_toolbar() m_sel_plate_toolbar.is_display_scrollbar = is_win_hovered; imgui.end(); - m_sel_plate_toolbar.is_render_finish = true; } //BBS: GUI refactor: GLToolbar adjust @@ -9324,7 +9454,7 @@ void GLCanvas3D::_render_canvas_toolbar() ); create_menu_item( _utf8(L("Realistic View")), - true, + m_canvas_type != ECanvasType::CanvasPreview, // not work on preview cfg->get_bool(SETTING_OPENGL_REALISTIC_MODE), [this, &cfg]{ cfg->set_bool(SETTING_OPENGL_REALISTIC_MODE, !cfg->get_bool(SETTING_OPENGL_REALISTIC_MODE)); @@ -10169,6 +10299,9 @@ void GLCanvas3D::_set_warning_notification_if_needed(EWarning warning) void GLCanvas3D::_set_warning_notification(EWarning warning, bool state) { + // Skip on shutdown: Plater's pImpl is already freed, so get_notification_manager() would use-after-free. + if (wxGetApp().is_closing()) + return; using NotificationLevel = NotificationManager::NotificationLevel; enum ErrorType{ PLATER_WARNING, diff --git a/src/slic3r/GUI/GLCanvas3D.hpp b/src/slic3r/GUI/GLCanvas3D.hpp index a3209dcc1c..55e118fa4c 100644 --- a/src/slic3r/GUI/GLCanvas3D.hpp +++ b/src/slic3r/GUI/GLCanvas3D.hpp @@ -732,6 +732,12 @@ public: std::array m_ssao_texture_size{ { 0, 0 } }; GLModel m_plate_shadow_mask; std::string m_plate_shadow_mask_key; + // Depth-based shadow map used to cast object shadows onto other objects and themselves. + unsigned int m_shadow_map_fbo{ 0 }; + unsigned int m_shadow_map_texture_id{ 0 }; + unsigned int m_shadow_map_size{ 0 }; + Transform3d m_shadow_light_vp{ Transform3d::Identity() }; + bool m_shadow_map_valid{ false }; public: explicit GLCanvas3D(wxGLCanvas* canvas, Bed3D &bed); ~GLCanvas3D(); @@ -991,7 +997,6 @@ public: void select_curr_plate_all(); void select_object_from_idx(std::vector& object_idxs); void remove_curr_plate_all(); - void update_plate_thumbnails(); void select_all(); void deselect_all(); @@ -1251,7 +1256,9 @@ private: void _render_ssao_pass(unsigned int width, unsigned int height); void _render_background(); void _render_bed(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool show_axes); - void _render_cast_shadows_on_plate(const Transform3d& view_matrix, const Transform3d& projection_matrix); + // Build the light-space depth shadow map (consumed by gouraud/phong for object & self shadows) + // and cast it onto the build plate. Realistic view only. + void _render_shadows(const Transform3d& view_matrix, const Transform3d& projection_matrix); //BBS: add part plate related logic void _render_platelist(const Transform3d& view_matrix, const Transform3d& projection_matrix, bool bottom, bool only_current, bool only_body = false, int hover_id = -1, bool render_cali = false, bool show_grid = true); //BBS: add outline drawing logic diff --git a/src/slic3r/GUI/GLModel.cpp b/src/slic3r/GUI/GLModel.cpp index f7fab43817..3dd15c3fdd 100644 --- a/src/slic3r/GUI/GLModel.cpp +++ b/src/slic3r/GUI/GLModel.cpp @@ -457,10 +457,9 @@ void GLModel::init_from(const indexed_triangle_set& its) data.reserve_indices(3 * its.indices.size()); // Read user preference: smooth normals enabled - const bool realistic_mode = wxGetApp().app_config != nullptr && wxGetApp().app_config->get_bool(SETTING_OPENGL_REALISTIC_MODE); const bool smooth_normals_enabled = wxGetApp().app_config != nullptr && wxGetApp().app_config->get_bool(SETTING_OPENGL_PHONG_SMOOTH_NORMALS); - if (realistic_mode && smooth_normals_enabled) { + if (smooth_normals_enabled) { // Use per-corner smooth normals (via IGL) using MapMatrixXfUnaligned = Eigen::Map>; using MapMatrixXiUnaligned = Eigen::Map>; diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index 5e85154677..374dc2884f 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -68,6 +68,10 @@ std::pair GLShadersManager::init() valid &= append_shader("thumbnail", { prefix + "thumbnail.vs", prefix + "thumbnail.fs"}); // used to render printbed valid &= append_shader("printbed", { prefix + "printbed.vs", prefix + "printbed.fs" }); +#if !SLIC3R_OPENGL_ES + // used to cast the object shadow map onto the build plate (realistic view) + valid &= append_shader("printbed_shadow", { prefix + "printbed_shadow.vs", prefix + "printbed_shadow.fs" }); +#endif // !SLIC3R_OPENGL_ES valid &= append_shader("hotbed", {prefix + "hotbed.vs", prefix + "hotbed.fs"}); // used to render options in gcode preview if (GUI::wxGetApp().is_gl_version_greater_or_equal_to(3, 3)) { diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index 121acdb947..1478bc3596 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -3633,8 +3633,24 @@ void GUI_App::switch_printer_agent() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ": printer agent switched to " << effective_agent_id; - // Auto-switch MachineObject + // Auto-switch MachineObject (new agent has empty device_info, so always re-select) select_machine(effective_agent_id); + } else if (effective_agent_id != BBL_PRINTER_AGENT_ID) { + // Orca: the agent type is unchanged (e.g. switching between two Moonraker/Klipper + // printer presets), so the selected machine and the agent's cached device_info still + // point at the previously active printer preset. Re-select the machine when the new + // preset targets a different host, otherwise filament sync keeps hitting the old + // printer. (#12506) + if (m_device_manager && preset_bundle) { + const DynamicPrintConfig& cfg = preset_bundle->printers.get_edited_preset().config; + const std::string print_host = cfg.opt_string("print_host"); + if (!print_host.empty()) { + const std::string dev_id = MachineObject::dev_id_from_address(print_host, cfg.opt_string("printhost_port")); + MachineObject* sel = m_device_manager->get_selected_machine(); + if (!sel || sel->get_dev_id() != dev_id) + select_machine(effective_agent_id); + } + } } } @@ -6965,6 +6981,10 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg) // finishFn tears down the progress dialog (and clears the re-entrancy guard), so it // must run on every exit path — otherwise an early bail-out would leak the modal // dialog and leave the guard stuck, blocking all later manual syncs. + // Guard the whole thread body: an uncaught exception here (e.g. a transient + // boost::filesystem error while scanning the preset folder) would otherwise + // propagate out of the thread and terminate the entire application. + try { if (!m_agent) { finishFn(false); return; } // One-time scan for orphaned .info files left over from offline deletions; queues HTTP DELETEs. @@ -7140,7 +7160,7 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg) .plater() ->get_notification_manager() ->push_notification(NotificationType::CustomNotification, - NotificationManager::NotificationLevel::RegularNotificationLevel, "There is an update available. Open the preset bundle dialog to update it."); + NotificationManager::NotificationLevel::RegularNotificationLevel, _u8L("There is an update available. Open the preset bundle dialog to update it.")); update_available = false; } @@ -7206,6 +7226,11 @@ void GUI_App::start_sync_user_preset(bool with_progress_dlg) boost::this_thread::sleep_for(boost::chrono::milliseconds(500)); } } + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << "user preset sync thread terminated by exception: " << e.what(); + } catch (...) { + BOOST_LOG_TRIVIAL(error) << "user preset sync thread terminated by unknown exception"; + } }); } @@ -7713,14 +7738,14 @@ bool GUI_App::load_language(wxString language, bool initial) if (!wxLocale::IsAvailable(locale_language_info->Language)) { // Loading the language dictionary failed. - wxString message = "Switching Orca Slicer to language " + requested_language_code + " failed."; + wxString message = wxString::Format(_L("Switching Orca Slicer to language %s failed."), requested_language_code); #if !defined(_WIN32) && !defined(__APPLE__) // likely some linux system - message += "\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n"; + message += _L("\nYou may need to reconfigure the missing locales, likely by running the \"locale-gen\" and \"dpkg-reconfigure locales\" commands.\n"); #endif if (initial) message + "\n\nApplication will close."; - wxMessageBox(message, "Orca Slicer - Switching language failed", wxOK | wxICON_ERROR); + wxMessageBox(message, _L("Orca Slicer - Switching language failed"), wxOK | wxICON_ERROR); if (initial) std::exit(EXIT_FAILURE); else @@ -8526,8 +8551,13 @@ void GUI_App::scan_orphaned_info_files() if (!fs::exists(type_dir)) continue; - // Iterate through all .info files - for (auto& entry : boost::filesystem::directory_iterator(type_dir)) { + // Iterate through all .info files. Use the error_code-based iterator so a transient + // directory-read failure (e.g. macOS readdir returning ENOTSUP) is logged and skipped + // instead of throwing an uncaught exception that would terminate the app from the + // background sync thread this runs on. + boost::system::error_code ec; + for (boost::filesystem::directory_iterator it(type_dir, ec), end; !ec && it != end; it.increment(ec)) { + const auto& entry = *it; if (entry.path().extension() != ".info") continue; @@ -8546,6 +8576,8 @@ void GUI_App::scan_orphaned_info_files() } } } + if (ec) + BOOST_LOG_TRIVIAL(warning) << "scan_orphaned_info_files: failed to scan " << type_dir.string() << ": " << ec.message(); } } diff --git a/src/slic3r/GUI/GUI_Factories.cpp b/src/slic3r/GUI/GUI_Factories.cpp index ccb6dedd29..75dc44add6 100644 --- a/src/slic3r/GUI/GUI_Factories.cpp +++ b/src/slic3r/GUI/GUI_Factories.cpp @@ -132,6 +132,9 @@ std::map> SettingsFactory::PART_CATE {"infill_anchor", "", 1}, {"infill_anchor_max", "", 1}, {"top_surface_pattern", "", 1}, + {"top_surface_expansion", "", 1}, + {"top_surface_expansion_margin", "", 1}, + {"top_surface_expansion_direction", "", 1}, {"bottom_surface_pattern", "", 1}, {"internal_solid_infill_pattern", "", 1}, {"align_infill_direction_to_model", "", 1}, @@ -187,7 +190,7 @@ std::vector SettingsFactory::get_visible_options(const std::s //Quality "wall_infill_order", "ironing_type", "inner_wall_line_width", "outer_wall_line_width", "top_surface_line_width", //Shell - "wall_loops", "top_shell_layers", "bottom_shell_layers", "top_shell_thickness", "bottom_shell_thickness", + "wall_loops", "top_shell_layers", "bottom_shell_layers", "top_shell_thickness", "bottom_shell_thickness", "top_surface_expansion", "top_surface_expansion_margin", "top_surface_expansion_direction", //Infill "sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern", "infill_combination", "infill_direction", "infill_wall_overlap", //speed diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index fcdf005aad..b23b554a74 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -38,6 +38,7 @@ #include "slic3r/Utils/FixModelByCgal.hpp" #include "libslic3r/Format/bbs_3mf.hpp" +#include "libslic3r/Orient.hpp" #include "libslic3r/PrintConfig.hpp" #ifdef __WXMSW__ @@ -1154,7 +1155,7 @@ void ObjectList::update_filament_in_config(const wxDataViewItem& item) m_config = config; - take_snapshot("Change Filament"); + take_snapshot(_u8L("Change Filament")); const int extruder = m_objects_model->GetExtruderNumber(item); m_config->set_key_value("extruder", new ConfigOptionInt(extruder)); @@ -1192,7 +1193,7 @@ void ObjectList::update_name_in_model(const wxDataViewItem& item) const if (obj_idx < 0) return; const int volume_id = m_objects_model->GetVolumeIdByItem(item); - take_snapshot(volume_id < 0 ? "Rename Object" : "Rename Part"); + take_snapshot(volume_id < 0 ? _u8L("Rename Object") : _u8L("Rename Part")); ModelObject* obj = object(obj_idx); if (m_objects_model->GetItemType(item) & itObject) { @@ -1360,7 +1361,7 @@ void ObjectList::paste_settings_into_list() { wxDataViewItemArray sels; GetSelections(sels); - take_snapshot("Paste settings"); + take_snapshot(_u8L("Paste settings")); std::unique_ptr global_keys; // need copy from global @@ -1578,7 +1579,7 @@ void ObjectList::list_manipulation(const wxPoint& mouse_pos, bool evt_context_me int obj_idx, vol_idx; get_selected_item_indexes(obj_idx, vol_idx, item); if (obj_idx != -1) { - Plater::TakeSnapshot(plater, "Shift objects to bed"); + Plater::TakeSnapshot(plater, _u8L("Shift objects to bed")); (*m_objects)[obj_idx]->ensure_on_bed(); cnv->reload_scene(true, true); update_info_items(obj_idx); @@ -2001,7 +2002,7 @@ void ObjectList::OnDrop(wxDataViewEvent &event) } //#if 1 - take_snapshot("Object order changed"); + take_snapshot(_u8L("Object order changed")); if(m_dragged_data.type() & itObject){ int delta = dest_obj_id < src_obj_id ? -1 : 1; @@ -2065,9 +2066,9 @@ void ObjectList::add_category_to_settings_from_selection(const std::vector< std: assert(m_config); auto opt_keys = m_config->keys(); - const std::string snapshot_text = item_type & itLayer ? "Layer setting added" : - item_type & itVolume ? "Part setting added" : - "Object setting added"; + const std::string snapshot_text = item_type & itLayer ? _u8L("Layer setting added") : + item_type & itVolume ? _u8L("Part setting added") : + _u8L("Object setting added"); take_snapshot(snapshot_text); const DynamicPrintConfig& from_config = printer_technology() == ptFFF ? @@ -2106,9 +2107,9 @@ void ObjectList::add_category_to_settings_from_frequent(const std::vectorkeys(); - const std::string snapshot_text = item_type & itLayer ? "Height range settings added" : - item_type & itVolume ? "Part settings added" : - "Object settings added"; + const std::string snapshot_text = item_type & itLayer ? _u8L("Height range settings added") : + item_type & itVolume ? _u8L("Part settings added") : + _u8L("Object settings added"); take_snapshot(snapshot_text); const DynamicPrintConfig& from_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; @@ -2176,7 +2177,7 @@ void ObjectList::load_subobject(ModelVolumeType type, bool from_galery/* = false if (input_files.IsEmpty()) return; - take_snapshot((type == ModelVolumeType::MODEL_PART) ? "Load Part" : "Load Modifier"); + take_snapshot((type == ModelVolumeType::MODEL_PART) ? _u8L("Load Part") : _u8L("Load Modifier")); std::vector volumes; // ! ysFIXME - delete commented code after testing and rename "load_modifier" to something common @@ -2463,7 +2464,7 @@ void ObjectList::load_generic_subobject(const std::string& type_name, const Mode if (instance_idx == -1) return; - take_snapshot("Add primitive"); + take_snapshot(_u8L("Add primitive")); // Selected object ModelObject &model_object = *(*m_objects)[obj_idx]; @@ -2555,11 +2556,20 @@ void ObjectList::load_shape_object(const std::string &type_name) if (obj_idx < 0) return; - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Add Primitive"); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Add Primitive")); // Create mesh BoundingBoxf3 bb; TriangleMesh mesh = create_mesh(type_name, bb); + // Rotate the largest overhang area toward the part cooling fan so new shapes start in a + // cooling friendly orientation. Skip the plain cube: the pressure advance pattern + // calibration reuses it as an axis-aligned anchor and scales it by its bounding box, + // so its orientation must stay fixed. + const Slic3r::DynamicPrintConfig& full_config = wxGetApp().preset_bundle->full_config(); + if (type_name != "Cube" && full_config.has("fan_direction") && full_config.has("auxiliary_fan")) { + FanDirection config_dir = full_config.option>("fan_direction")->value; + orientation::orient_for_cooling(mesh, config_dir); + } // BBS: remove "Shape" prefix load_mesh_object(mesh, _(type_name)); wxGetApp().mainframe->update_title(); @@ -2716,7 +2726,7 @@ void ObjectList::del_settings_from_config(const wxDataViewItem& parent_item) (is_layer_settings && opt_cnt == 2 && m_config->has("extruder") && m_config->has("layer_height"))) return; - take_snapshot("Delete Settings"); + take_snapshot(_u8L("Delete Settings")); int extruder = m_config->has("extruder") ? m_config->extruder() : -1; @@ -2757,7 +2767,7 @@ void ObjectList::del_layer_from_object(const int obj_idx, const t_layer_height_r if (del_range == object(obj_idx)->layer_config_ranges.end()) return; - take_snapshot("Remove height range"); + take_snapshot(_u8L("Remove height range")); object(obj_idx)->layer_config_ranges.erase(del_range); @@ -2830,7 +2840,7 @@ bool ObjectList::del_subobject_from_object(const int obj_idx, const int idx, con return false; } - take_snapshot("Delete part"); + take_snapshot(_u8L("Delete part")); object->delete_volume(idx); @@ -2895,7 +2905,7 @@ void ObjectList::split() return; } - take_snapshot("Split to parts"); + take_snapshot(_u8L("Split to parts")); volume->split(filament_cnt, wxGetApp().app_config->get_bool("keep_painting")); @@ -3028,7 +3038,7 @@ void ObjectList::merge(bool to_multipart_object) GetSelections(sels); assert(!sels.IsEmpty()); - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Assemble"); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Assemble")); get_object_idxs(obj_idxs, sels); @@ -3176,7 +3186,7 @@ void ObjectList::merge(bool to_multipart_object) if (obj_idx == -1) return; - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Merge parts to an object"); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Merge parts to an object")); ModelObject* model_object = (*m_objects)[obj_idx]; model_object->merge(); @@ -3243,7 +3253,7 @@ void ObjectList::layers_editing() // set some default value if (ranges.empty()) { // BBS: remove snapshot name "Add layers" - take_snapshot("Add layers"); + take_snapshot(_u8L("Add layers")); ranges[{ 0.0f, 2.0f }].assign_config(get_default_layer_config(obj_idx)); } @@ -4234,7 +4244,7 @@ void ObjectList::delete_from_model_and_list(const ItemType type, const int obj_i if (!(type&(itObject|itVolume|itInstance))) return; - take_snapshot("Delete selected"); + take_snapshot(_u8L("Delete selected")); if (type&itObject) { bool was_cut = object(obj_idx)->is_cut(); @@ -4467,7 +4477,7 @@ void ObjectList::remove() UnselectAll(); update_selection(sels, sels_mode, m_objects_model); - Plater::TakeSnapshot snapshot = Plater::TakeSnapshot(wxGetApp().plater(), "Delete selected"); + Plater::TakeSnapshot snapshot = Plater::TakeSnapshot(wxGetApp().plater(), _u8L("Delete selected")); for (auto& item : sels) { @@ -5525,7 +5535,7 @@ void ObjectList::change_part_type() return; } - take_snapshot("Change part type"); + take_snapshot(_u8L("Change part type")); volume->set_type(new_type); wxDataViewItemArray sel = reorder_volumes_and_get_selection(obj_idx, [volume](const ModelVolume* vol) { return vol == volume; }); @@ -5799,7 +5809,7 @@ void ObjectList::set_volume_type(ModelVolumeType new_type) } } - take_snapshot("Change part type"); + take_snapshot(_u8L("Change part type")); std::set changed_volumes; std::set touched_objects; @@ -6033,7 +6043,7 @@ void ObjectList::split_instances() if (obj_idx == -1) return; - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Instances to Separated Objects"); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Instances to Separated Objects")); if (selection.is_single_full_object()) { @@ -6164,7 +6174,7 @@ void ObjectList::fix_through_cgal() return true; }; - Plater::TakeSnapshot snapshot(plater, "Repairing model object"); + Plater::TakeSnapshot snapshot(plater, _u8L("Repairing model object")); // Open a progress dialog. ProgressDialog progress_dlg(_L("Repairing model object"), "", 100, find_toplevel_parent(plater), @@ -6495,7 +6505,7 @@ void ObjectList::OnEditingStarted(wxDataViewEvent &event) else if (col == colSinking) { Plater * plater = wxGetApp().plater(); GLCanvas3D *cnv = plater->canvas3D(); - Plater::TakeSnapshot(plater, "Shift objects to bed"); + Plater::TakeSnapshot(plater, _u8L("Shift objects to bed")); int obj_idx, vol_idx; get_selected_item_indexes(obj_idx, vol_idx, item); (*m_objects)[obj_idx]->ensure_on_bed(); @@ -6582,7 +6592,7 @@ void ObjectList::set_extruder_for_selected_items(const int extruder) if (sels.empty()) return; - take_snapshot("Change Filaments"); + take_snapshot(_u8L("Change Filaments")); for (const wxDataViewItem& sel_item : sels) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp index 353301995f..dd712011a5 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoCut.cpp @@ -2975,7 +2975,7 @@ void GLGizmoCut3D::render_cut_plane_input_window(CutConnectors &connectors, floa ImGui::SameLine(); m_imgui->disabled_begin(is_cut_plane_init && !has_connectors); if (m_imgui->button(_L("Reset"), _L("Reset cutting plane and remove connectors"))) { - Plater::TakeSnapshot snapshot(wxGetApp().plater(), "Reset Cut", UndoRedo::SnapshotType::GizmoAction); + Plater::TakeSnapshot snapshot(wxGetApp().plater(), _u8L("Reset Cut"), UndoRedo::SnapshotType::GizmoAction); reset_cut_plane(); reset_connectors(); } @@ -3500,10 +3500,10 @@ static void check_objects_after_cut(const ModelObjectPtrs& objects) wxString names = from_u8(err_objects_names[0]); for (size_t i = 1; i < err_objects_names.size(); i++) names += ", " + from_u8(err_objects_names[i]); - WarningDialog(wxGetApp().plater(), format_wxstr("Objects(%1%) have duplicated connectors. " + WarningDialog(wxGetApp().plater(), format_wxstr(_L("Objects(%1%) have duplicated connectors. " "Some connectors may be missing in slicing result.\n" "Please report to PrusaSlicer team in which scenario this issue happened.\n" - "Thank you.", names)).ShowModal(); + "Thank you."), names)).ShowModal(); } void synchronize_model_after_cut(Model& model, const CutObjectBase& cut_id) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp index b7c963cc63..3d51c77c00 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoEmboss.cpp @@ -1951,7 +1951,7 @@ void GLGizmoEmboss::draw_model_type() float minimum_spacing_x = 8.0f; float minimum_offset_x = ImGui::GetCursorPosX() + minimum_spacing_x; float offset_x = std::max(m_gui_cfg->input_offset, minimum_offset_x); - ImGui::SameLine(offset_x); + ImGui::SameLine(); ImGuiWrapper::push_radio_style(m_parent.get_scale()); // ORCA if (ImGui::RadioButton(_u8L("Join").c_str(), type == part)) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp index 218a67890b..a99b68340d 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoMeasure.cpp @@ -1303,7 +1303,7 @@ void GLGizmoMeasure::render_dimensioning() return; const double ratio = new_value / old_value; - wxGetApp().plater()->take_snapshot(_u8L("Scale"), UndoRedo::SnapshotType::GizmoAction); + wxGetApp().plater()->take_snapshot(_CTX_utf8("Scale", "Verb"), UndoRedo::SnapshotType::GizmoAction); // apply scale TransformationType type; type.set_world(); diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp index c43a02da9f..1da865105f 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSVG.cpp @@ -1989,7 +1989,7 @@ void GLGizmoSVG::draw_mirroring() void GLGizmoSVG::draw_model_type() { - ImGui::AlignTextToFramePadding(); + //ImGui::AlignTextToFramePadding(); bool is_last_solid_part = m_volume->is_the_only_one_part(); std::string title = _u8L("Operation"); if (is_last_solid_part) { @@ -2005,6 +2005,8 @@ void GLGizmoSVG::draw_model_type() ModelVolumeType part = ModelVolumeType::MODEL_PART; ModelVolumeType type = m_volume->type(); + ImGui::SameLine(); + //TRN EmbossOperation ImGuiWrapper::push_radio_style(m_parent.get_scale()); //ORCA if (ImGui::RadioButton(_u8L("Join").c_str(), type == part)) diff --git a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp index 77fc7ef46c..ebbb76f348 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoScale.cpp @@ -143,9 +143,9 @@ bool GLGizmoScale3D::on_init() std::string GLGizmoScale3D::on_get_name() const { if (!on_is_activable() && m_state == EState::Off) { - return _u8L("Scale") + ":\n" + _u8L("Please select at least one object."); + return _CTX_utf8("Scale", "Verb") + ":\n" + _u8L("Please select at least one object."); } else { - return _u8L("Scale"); + return _CTX_utf8("Scale", "Verb"); } } diff --git a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp index 5297f95c82..3f82777a2a 100644 --- a/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp +++ b/src/slic3r/GUI/Gizmos/GizmoObjectManipulation.cpp @@ -1161,7 +1161,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w imgui_wrapper->calc_text_size(_L("Part")).x }) + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3.5f); float label_max = std::max({ - imgui_wrapper->calc_text_size(_L("Scale")).x, + imgui_wrapper->calc_text_size(_CTX("Scale", "Noun")).x, imgui_wrapper->calc_text_size(_L("Size")).x }); float caption_max = std::max(label_max, coord_combo_width - 3 * space_size); @@ -1218,7 +1218,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w //ImGui::PushItemWidth(unit_size * 2); ImGui::AlignTextToFramePadding(); - imgui_wrapper->text(_L("Scale")); + imgui_wrapper->text(_CTX("Scale", "Noun")); ImGui::SameLine(caption_max + space_size); ImGui::PushItemWidth(unit_size); ImGui::BBLInputDouble(label_scale_values[0][0], &scale[0], 0.0f, 0.0f, "%.2f"); diff --git a/src/slic3r/GUI/IMToolbar.cpp b/src/slic3r/GUI/IMToolbar.cpp index 733683366f..2a569c960b 100644 --- a/src/slic3r/GUI/IMToolbar.cpp +++ b/src/slic3r/GUI/IMToolbar.cpp @@ -61,8 +61,6 @@ void IMToolbar::del_stats_item() void IMToolbar::set_enabled(bool enable) { m_enabled = enable; - if (!m_enabled) - is_render_finish = false; } bool IMReturnToolbar::init() diff --git a/src/slic3r/GUI/IMToolbar.hpp b/src/slic3r/GUI/IMToolbar.hpp index 24152f20ee..bf5bf70756 100644 --- a/src/slic3r/GUI/IMToolbar.hpp +++ b/src/slic3r/GUI/IMToolbar.hpp @@ -51,7 +51,6 @@ public: float icon_height; bool is_display_scrollbar; bool show_stats_item{ false }; - bool is_render_finish{false}; IMToolbar() { icon_width = DEFAULT_TOOLBAR_BUTTON_WIDTH; icon_height = DEFAULT_TOOLBAR_BUTTON_HEIGHT; diff --git a/src/slic3r/GUI/ImGuiWrapper.cpp b/src/slic3r/GUI/ImGuiWrapper.cpp index 94083dacee..62881ab77b 100644 --- a/src/slic3r/GUI/ImGuiWrapper.cpp +++ b/src/slic3r/GUI/ImGuiWrapper.cpp @@ -2785,6 +2785,11 @@ void ImGuiWrapper::init_font(bool compress) builder.BuildRanges(&ranges); // Build the final result (ordered ranges with all the unique characters submitted) io.Fonts->Flags |= ImFontAtlasFlags_NoPowerOfTwoHeight; + // TexDesiredWidth will be increased adaptively below if the built height + // exceeds GL_MAX_TEXTURE_SIZE. Leave it at 0 so ImGui picks the minimum + // width for small glyph sets and we only widen when actually necessary. + io.Fonts->TexDesiredWidth = 0; + ImFontConfig cfg = ImFontConfig(); cfg.OversampleH = cfg.OversampleV = 1; //FIXME replace with io.Fonts->AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, m_font_size, nullptr, ranges.Data); @@ -2856,7 +2861,23 @@ void ImGuiWrapper::init_font(bool compress) io.Fonts->AddCustomRectFontGlyph(default_font, icon.first, icon_sz * 4, icon_sz * 4, 3.0 * font_scale + icon_sz * 4); } - // Build texture atlas + // Build texture atlas, widening it if the height would exceed GL_MAX_TEXTURE_SIZE. + // Increasing the width allows the packing algorithm to grow more horizontally which reduces the height. + io.Fonts->Build(); + GLint gl_max_tex_size = 0; + glsafe(::glGetIntegerv(GL_MAX_TEXTURE_SIZE, &gl_max_tex_size)); + constexpr int max_retries = 6; + for (int attempt = 0; attempt < max_retries && io.Fonts->TexHeight > gl_max_tex_size; ++attempt) { + io.Fonts->TexDesiredWidth = (io.Fonts->TexDesiredWidth > 0 ? io.Fonts->TexDesiredWidth : io.Fonts->TexWidth) * 2; + io.Fonts->Build(); + } + if (io.Fonts->TexHeight > gl_max_tex_size) { + // Shouldn't really happen + BOOST_LOG_TRIVIAL(error) << "Font atlas height " << io.Fonts->TexHeight + << " still exceeds GL_MAX_TEXTURE_SIZE (" << gl_max_tex_size << ")" + << " after " << max_retries << " attempts; rendering may be incomplete"; + } + unsigned char* pixels; int width, height; io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height); // Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory. @@ -3141,6 +3162,9 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) shader->set_uniform("Texture", 0); shader->set_uniform("ProjMtx", ortho_projection); + const uint8_t stage = 0; + shader->set_uniform("s_texture", stage); + // Will project scissor/clipping rectangles into framebuffer space const ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports const ImVec2 clip_scale = draw_data->FramebufferScale; // (1,1) unless using retina display which are often (2,2) @@ -3205,6 +3229,7 @@ void ImGuiWrapper::render_draw_data(ImDrawData *draw_data) glsafe(::glScissor((int)clip_min.x, (int)(fb_height - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y))); // Bind texture, Draw + glsafe(::glActiveTexture(GL_TEXTURE0 + stage)); glsafe(::glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID())); glsafe(::glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, (void*)(intptr_t)(pcmd->IdxOffset * sizeof(ImDrawIdx)))); } diff --git a/src/slic3r/GUI/ImageGrid.cpp b/src/slic3r/GUI/ImageGrid.cpp index 77fd7b132e..3c333c93fb 100644 --- a/src/slic3r/GUI/ImageGrid.cpp +++ b/src/slic3r/GUI/ImageGrid.cpp @@ -644,7 +644,7 @@ void Slic3r::GUI::ImageGrid::renderContent1(wxDC &dc, wxPoint const &pt, int ind if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) { if (secondAction != _L("Play")) thirdAction = secondAction; - secondAction = _L("Print"); + secondAction = _CTX("Print", "Verb"); } // Draw buttons on hovered item wxRect rect{pt.x, pt.y + m_content_rect.GetBottom() - m_buttons_background.GetHeight(), m_content_rect.GetWidth(), m_buttons_background.GetHeight()}; diff --git a/src/slic3r/GUI/Jobs/FillBedJob.cpp b/src/slic3r/GUI/Jobs/FillBedJob.cpp index 711228c0bc..a9a66cb96f 100644 --- a/src/slic3r/GUI/Jobs/FillBedJob.cpp +++ b/src/slic3r/GUI/Jobs/FillBedJob.cpp @@ -348,6 +348,8 @@ void FillBedJob::finalize(bool canceled, std::exception_ptr &eptr) } m_plater->update(); } + + m_plater->mark_plate_toolbar_image_dirty(); } }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Jobs/OrientJob.cpp b/src/slic3r/GUI/Jobs/OrientJob.cpp index 2a7a7556fc..7347bad6a2 100644 --- a/src/slic3r/GUI/Jobs/OrientJob.cpp +++ b/src/slic3r/GUI/Jobs/OrientJob.cpp @@ -229,15 +229,32 @@ orientation::OrientMesh OrientJob::get_orient_mesh(ModelInstance* instance) auto obj = instance->get_object(); om.name = obj->name; om.mesh = obj->mesh(); // don't know the difference to obj->raw_mesh(). Both seem OK + const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); if (obj->config.has("support_threshold_angle")) om.overhang_angle = obj->config.opt_int("support_threshold_angle"); else { - const Slic3r::DynamicPrintConfig& config = wxGetApp().preset_bundle->full_config(); om.overhang_angle = config.opt_int("support_threshold_angle"); } + if (config.has("fan_direction") && config.has("auxiliary_fan")) { + FanDirection config_dir = config.option>("fan_direction")->value; + if (config_dir == FanDirection::fdUndefine || !config.opt_bool("auxiliary_fan")) { + // no part cooling airflow to face, keep the orientation around the z axis unchanged + om.cooling_direction = {0, 0, 0}; + } else if (config_dir == FanDirection::fdRight) { + // the part cooling airflow comes from the right side + om.cooling_direction = {1, 0, 0}; + om.has_cooling_fan = true; + } else { + // the part cooling airflow comes from the left side, or from both sides + om.cooling_direction = {-1, 0, 0}; + om.has_cooling_fan = true; + } + } + om.setter = [instance](const OrientMesh& p) { instance->rotate(p.rotation_matrix); + instance->rotate(p.rotation_matrix_vertical); instance->get_object()->invalidate_bounding_box(); instance->get_object()->ensure_on_bed(); }; diff --git a/src/slic3r/GUI/MainFrame.cpp b/src/slic3r/GUI/MainFrame.cpp index 66d7d87835..028a47964b 100644 --- a/src/slic3r/GUI/MainFrame.cpp +++ b/src/slic3r/GUI/MainFrame.cpp @@ -2013,10 +2013,10 @@ wxBoxSizer* MainFrame::create_side_tools() }); // upload and print - SideButton* send_gcode_btn = new SideButton(p, _L("Print"), ""); + SideButton* send_gcode_btn = new SideButton(p, _CTX("Print", "Verb"), ""); send_gcode_btn->SetCornerRadius(0); send_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) { - m_print_btn->SetLabel(_L("Print")); + m_print_btn->SetLabel(_CTX("Print", "Verb")); m_print_select = eSendGcode; m_print_enable = get_enable_print_status(); m_print_btn->Enable(m_print_enable); @@ -2662,9 +2662,9 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); append_menu_item(view_menu, wxID_ANY, _L("Rear") + "\t" + ctrl + "4", _L("Rear View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("rear"); }, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); - append_menu_item(view_menu, wxID_ANY, _CTX(L_CONTEXT("Left", "Camera"), "Camera") + "\t" + ctrl + "5", _L("Left View"),[mainFrame](wxCommandEvent &) {mainFrame->select_view("left"); }, + append_menu_item(view_menu, wxID_ANY, _CTX("Left", "Camera View") + "\t" + ctrl + "5", _L("Left View"),[mainFrame](wxCommandEvent &) {mainFrame->select_view("left"); }, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); - append_menu_item(view_menu, wxID_ANY, _CTX(L_CONTEXT("Right", "Camera"), "Camera") + "\t" + ctrl + "6", _L("Right View"),[mainFrame](wxCommandEvent &) { mainFrame->select_view("right"); }, + append_menu_item(view_menu, wxID_ANY, _CTX("Right", "Camera View") + "\t" + ctrl + "6", _L("Right View"),[mainFrame](wxCommandEvent &) { mainFrame->select_view("right"); }, "", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame); } @@ -2809,21 +2809,6 @@ void MainFrame::init_menubar_as_editor() append_submenu(fileMenu, export_menu, wxID_ANY, _L("Export"), ""); fileMenu->AppendSeparator(); - append_menu_item(fileMenu, wxID_ANY, _L("Sync Presets"), _L("Pull and apply the latest presets from OrcaCloud"), - [this](wxCommandEvent&) { - if (!wxGetApp().is_user_login()) { - MessageDialog info_dlg(this, _L("You must be logged in to sync presets from cloud."), - _L("Sync Presets"), wxOK | wxICON_INFORMATION); - info_dlg.ShowModal(); - return; - } - wxGetApp().restart_sync_user_preset(); - }, "", nullptr, - [this]() { - return wxGetApp().is_user_login() && !wxGetApp().app_config->get_stealth_mode(); - }, this); - - fileMenu->AppendSeparator(); #ifndef __APPLE__ append_menu_item(fileMenu, wxID_EXIT, _L("Quit"), wxString::Format(_L("Quit")), @@ -3289,6 +3274,8 @@ void MainFrame::init_menubar_as_editor() }, "", nullptr, []() { return true; }, this); + m_topbar->GetTopMenu()->AppendSeparator(); + append_menu_item( m_topbar->GetTopMenu(), wxID_ANY, _L("Preset Bundle") + "\t", "", [this](wxCommandEvent &) { @@ -3316,6 +3303,8 @@ void MainFrame::init_menubar_as_editor() return wxGetApp().is_user_login() && !wxGetApp().app_config->get_stealth_mode(); }, this); + m_topbar->GetTopMenu()->AppendSeparator(); + //m_topbar->AddDropDownMenuItem(preference_item); //m_topbar->AddDropDownMenuItem(printer_item); //m_topbar->AddDropDownMenuItem(language_item); @@ -3425,6 +3414,25 @@ void MainFrame::init_menubar_as_editor() plater()->get_current_canvas3D()->force_set_focus(); }, "", nullptr, []() { return true; }, this); + + append_menu_item( + fileMenu, wxID_ANY, _L("Sync Presets"), _L("Pull and apply the latest presets from OrcaCloud"), + [this](wxCommandEvent&) { + if (!wxGetApp().is_user_login()) { + MessageDialog info_dlg(this, _L("You must be logged in to sync presets from cloud."), + _L("Sync Presets"), wxOK | wxICON_INFORMATION); + info_dlg.ShowModal(); + return; + } + if (m_plater) + m_plater->get_notification_manager()->push_notification( + into_u8(_L("Syncing presets from cloud\u2026"))); + wxGetApp().restart_sync_user_preset(); + }, "", nullptr, + [this]() { + return wxGetApp().is_user_login() && !wxGetApp().app_config->get_stealth_mode(); + }, this); + m_menubar->Append(fileMenu, wxString::Format("&%s", _L("File"))); if (editMenu) m_menubar->Append(editMenu, wxString::Format("&%s", _L("Edit"))); @@ -3727,7 +3735,7 @@ void MainFrame::load_config_file() // return; wxFileDialog dlg(this, _L("Select profile to load:"), !m_last_config.IsEmpty() ? get_dir_name(m_last_config) : wxGetApp().app_config->get_last_dir(), - "config.json", "Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament", wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); + "config.json", _L("Config files (*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament)|*.json;*.zip;*.orca_printer;*.orca_bundle;*.orca_filament"), wxFD_OPEN | wxFD_MULTIPLE | wxFD_FILE_MUST_EXIST); wxArrayString files; if (dlg.ShowModal() != wxID_OK) return; @@ -4040,7 +4048,7 @@ void MainFrame::set_print_button_to_default(PrintSelectType select_type) m_print_btn->Enable(m_print_enable); this->Layout(); } else if (select_type == PrintSelectType::eSendGcode) { - m_print_btn->SetLabel(_L("Print")); + m_print_btn->SetLabel(_CTX("Print", "Verb")); m_print_select = eSendGcode; if (m_print_enable) m_print_enable = get_enable_print_status() && can_send_gcode(); diff --git a/src/slic3r/GUI/MediaFilePanel.cpp b/src/slic3r/GUI/MediaFilePanel.cpp index 1fca47e7c4..6c1a261966 100644 --- a/src/slic3r/GUI/MediaFilePanel.cpp +++ b/src/slic3r/GUI/MediaFilePanel.cpp @@ -520,7 +520,7 @@ void MediaFilePanel::fetchUrl(boost::weak_ptr wfs) fs->SetUrl(res); } }); - }); + }, wxGetApp().get_printer_cloud_provider()); } } @@ -556,7 +556,7 @@ void MediaFilePanel::doAction(size_t index, int action) } else if (action == 1) { if (fs->GetFileType() == PrinterFileSystem::F_MODEL) { if (index != -1) { - auto dlg = new MediaProgressDialog(_L("Print"), this, [fs] { fs->FetchModelCancel(); }); + auto dlg = new MediaProgressDialog(_CTX("Print", "Verb"), this, [fs] { fs->FetchModelCancel(); }); dlg->Update(0, _L("Fetching model information...")); fs->FetchModel(index, [this, fs, dlg, index](int result, std::string const &data) { dlg->Destroy(); @@ -566,7 +566,7 @@ void MediaFilePanel::doAction(size_t index, int action) wxString msg = data.empty() ? _L("Failed to fetch model information from printer.") : from_u8(data); CallAfter([this, msg] { - MessageDialog(this, msg, _L("Print"), wxOK).ShowModal(); + MessageDialog(this, msg, _CTX("Print", "Verb"), wxOK).ShowModal(); }); return; } @@ -579,7 +579,7 @@ void MediaFilePanel::doAction(size_t index, int action) || plate_data_list.empty()) { MessageDialog(this, _L("Failed to parse model information."), - _L("Print"), wxOK).ShowModal(); + _CTX("Print", "Verb"), wxOK).ShowModal(); return; } diff --git a/src/slic3r/GUI/Monitor.cpp b/src/slic3r/GUI/Monitor.cpp index dff8cdc15b..ccec5048f2 100644 --- a/src/slic3r/GUI/Monitor.cpp +++ b/src/slic3r/GUI/Monitor.cpp @@ -518,6 +518,16 @@ void MonitorPanel::jump_to_HMS() m_tabpanel->SetSelection(PT_HMS); } +void MonitorPanel::jump_to_Upgrade() +{ + if (this->IsShown()) { + auto page = m_tabpanel->GetCurrentPage(); + if (page && page != m_upgrade_panel) { + m_tabpanel->SetSelection(PT_UPDATE); + } + } +} + void MonitorPanel::jump_to_LiveView() { if (!this->IsShown()) { return; } diff --git a/src/slic3r/GUI/Monitor.hpp b/src/slic3r/GUI/Monitor.hpp index b7502b9d51..cf050068b6 100644 --- a/src/slic3r/GUI/Monitor.hpp +++ b/src/slic3r/GUI/Monitor.hpp @@ -156,6 +156,7 @@ public: void jump_to_HMS(); + void jump_to_Upgrade(); void jump_to_LiveView(); void update_network_version_footer(); }; diff --git a/src/slic3r/GUI/Mouse3DController.cpp b/src/slic3r/GUI/Mouse3DController.cpp index 3a71e1ddfe..11709501ac 100644 --- a/src/slic3r/GUI/Mouse3DController.cpp +++ b/src/slic3r/GUI/Mouse3DController.cpp @@ -353,6 +353,7 @@ bool Mouse3DController::State::apply(const Mouse3DController::Params ¶ms, Ca rot = Vec3d(rot.x(), -rot.z(), rot.y()); rot = Vec3d(rot.x() * pitchmult, rot.y() * yawmult, rot.z() * rollmult); camera.rotate_local_around_target(Vec3d(rot.x(), - rot.z(), rot.y())); + camera.auto_type(Camera::EType::Perspective); } else { assert(input_queue_item.is_buttons()); switch (input_queue_item.type_or_buttons) { diff --git a/src/slic3r/GUI/MsgDialog.cpp b/src/slic3r/GUI/MsgDialog.cpp index 724e54c2f7..ed76c822f1 100644 --- a/src/slic3r/GUI/MsgDialog.cpp +++ b/src/slic3r/GUI/MsgDialog.cpp @@ -19,6 +19,7 @@ #include "I18N.hpp" //#include "ConfigWizard.hpp" #include "wxExtensions.hpp" +#include "Widgets/Label.hpp" #include "slic3r/GUI/MainFrame.hpp" #include "GUI_App.hpp" #define MSG_DLG_MAX_SIZE wxSize(-1, FromDIP(464))//notice:ban setting the maximum width value @@ -750,6 +751,47 @@ NetworkErrorDialog::NetworkErrorDialog(wxWindow* parent) Centre(wxBOTH); } + +FilamentWarningDialog::FilamentWarningDialog(wxWindow *parent, const wxString &title, std::vector infos) + : MsgDialog(parent, title.IsEmpty() ? wxString::Format(_L("%s warning"), SLIC3R_APP_FULL_NAME) : title, wxEmptyString, wxOK | wxICON_WARNING), m_messages(infos) +{ + BuildContent(); + finalize(); +} + +void FilamentWarningDialog::BuildContent() +{ + wxBoxSizer *messages_sizer = new wxBoxSizer(wxVERTICAL); + + int message_count = 0; + for (int i = 0; i < m_messages.size(); i++) + { + const wxString &message = m_messages[i].info_msg; + const wxString &wiki_url = m_messages[i].wiki_url; + if (message_count > 0) { messages_sizer->AddSpacer(FromDIP(10)); } + + if (wiki_url.IsEmpty()) { + // No wiki link - just display as regular text + Label *text = new Label(this, message); + text->SetFont(::Label::Body_12); + text->Wrap(FromDIP(400)); + messages_sizer->Add(text, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5)); + } else { + Label *link = new Label(this, message + " " + _L("Please refer to Wiki before use->")); + link->SetForegroundColour(wxColour(8, 153, 46)); + link->SetFont(::Label::Body_12); + link->Wrap(FromDIP(400)); + link->Bind(wxEVT_ENTER_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_HAND); }); + link->Bind(wxEVT_LEAVE_WINDOW, [this](auto &e) { SetCursor(wxCURSOR_ARROW); }); + link->Bind(wxEVT_LEFT_DOWN, [wiki_url](auto &event) { wxLaunchDefaultBrowser(wiki_url); }); + messages_sizer->Add(link, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(5)); + } + message_count++; + } + + content_sizer->Add(messages_sizer, 1, wxEXPAND | wxALL, FromDIP(5)); +} + } // namespace GUI } // namespace Slic3r diff --git a/src/slic3r/GUI/MsgDialog.hpp b/src/slic3r/GUI/MsgDialog.hpp index a385fbaa13..174d734336 100644 --- a/src/slic3r/GUI/MsgDialog.hpp +++ b/src/slic3r/GUI/MsgDialog.hpp @@ -67,6 +67,10 @@ struct MsgDialog : DPIDialog bool get_checkbox_state(); virtual void on_dpi_changed(const wxRect& suggested_rect); void SetButtonLabel(wxWindowID btn_id, const wxString& label, bool set_focus = false); + // Public wrapper around add_button — lets callers append custom-labelled choice buttons to an + // already-constructed dialog (used by the H2C rack hotend "Jump to the upgrade page" prompt). + // Purely additive; existing dialogs are unaffected. + void AddButton(wxWindowID btn_id, const wxString& label, bool set_focus = false) { add_button(btn_id, set_focus, label); } protected: enum { @@ -434,6 +438,32 @@ public: bool m_show_again{false}; }; +// Multi-item filament-blacklist warning dialog with per-item wiki links. Replaces the plain +// MessageDialog used for warnings so stacked accumulate-all warnings render with their own +// optional Wiki link. +struct FilamentWarningInfo +{ + wxString info_msg; + wxString wiki_url; +}; + +class FilamentWarningDialog : public MsgDialog +{ +public: + FilamentWarningDialog(wxWindow *parent, const wxString &title, std::vector infos); + FilamentWarningDialog(FilamentWarningDialog &&) = delete; + FilamentWarningDialog(const FilamentWarningDialog &) = delete; + FilamentWarningDialog &operator=(FilamentWarningDialog &&) = delete; + FilamentWarningDialog &operator=(const FilamentWarningDialog &) = delete; + virtual ~FilamentWarningDialog() = default; + +private: + void BuildContent(); + +private: + std::vector m_messages; +}; + } } diff --git a/src/slic3r/GUI/OpenGLManager.cpp b/src/slic3r/GUI/OpenGLManager.cpp index 2b5ebcd086..382a9176b9 100644 --- a/src/slic3r/GUI/OpenGLManager.cpp +++ b/src/slic3r/GUI/OpenGLManager.cpp @@ -266,7 +266,12 @@ bool OpenGLManager::init_gl(bool popup_error) else s_compressed_textures_supported = false; - if (GLAD_GL_ARB_framebuffer_object) { + if (s_gl_info.is_version_greater_or_equal_to(3, 0)) { + // ARB framebuffer became a mandatory part of core OpenGL 3.0 + s_framebuffers_type = EFramebufferType::Arb; + BOOST_LOG_TRIVIAL(info) << "Opengl version >= 30, FrameBuffer Type ARB." << std::endl; + } + else if (GLAD_GL_ARB_framebuffer_object) { s_framebuffers_type = EFramebufferType::Arb; BOOST_LOG_TRIVIAL(info) << "Found Framebuffer Type ARB."<< std::endl; } diff --git a/src/slic3r/GUI/PartPlate.cpp b/src/slic3r/GUI/PartPlate.cpp index 18d6e17b33..415e1ea0f5 100644 --- a/src/slic3r/GUI/PartPlate.cpp +++ b/src/slic3r/GUI/PartPlate.cpp @@ -3,7 +3,9 @@ #include #include #include +#include #include +#include "libslic3r/MultiNozzleUtils.hpp" #include #include #include @@ -66,6 +68,8 @@ static const int PARTPLATE_PLATENAME_OFFSET_Y = 10; const float WIPE_TOWER_DEFAULT_X_POS = 165.; const float WIPE_TOWER_DEFAULT_Y_POS = 250.; // Max y +const float N9_WIPE_TOWER_DEFAULT_Y_POS = 160.; + const float I3_WIPE_TOWER_DEFAULT_X_POS = 0.; const float I3_WIPE_TOWER_DEFAULT_Y_POS = 250.; // Max y @@ -315,6 +319,18 @@ std::vector PartPlate::get_real_filament_maps(const DynamicConfig& g_config return g_maps; } +std::vector PartPlate::get_real_filament_volume_maps(const DynamicConfig& g_config, bool* use_global_param) const +{ + auto maps = get_filament_volume_maps(); + if (!maps.empty()) { + if (use_global_param) { *use_global_param = false; } + return maps; + } + auto g_maps = g_config.option("filament_volume_map")->values; + if (use_global_param) { *use_global_param = true; } + return g_maps; +} + FilamentMapMode PartPlate::get_real_filament_map_mode(const DynamicConfig& g_config, bool* use_global_param) const { auto mode = get_filament_map_mode(); @@ -385,7 +401,7 @@ void PartPlate::set_spiral_vase_mode(bool spiral_mode, bool as_global) } } -bool PartPlate::valid_instance(int obj_id, int instance_id) +bool PartPlate::valid_instance(int obj_id, int instance_id) const { if ((obj_id >= 0) && (obj_id < m_model->objects.size())) { @@ -1688,7 +1704,7 @@ std::vector PartPlate::get_extruders_under_cli(bool conside_custom_gcode, D int obj_id = it->first; int instance_id = it->second; - if ((obj_id >= 0) && (obj_id < m_model->objects.size())) + if (valid_instance(obj_id, instance_id)) { ModelObject* object = m_model->objects[obj_id]; ModelInstance* instance = object->instances[instance_id]; @@ -1903,6 +1919,17 @@ int PartPlate::get_physical_extruder_by_filament_id(const DynamicConfig& g_confi return the_map->values[zero_base_logical_idx]; } +int PartPlate::get_logical_extruder_by_filament_id(const DynamicConfig& g_config, int idx) const +{ + const std::vector& filament_map = get_real_filament_maps(g_config); + if (idx <= 0 || idx > (int)filament_map.size()) + { + return -1; + } + + return filament_map[idx - 1] - 1; +} + std::vector PartPlate::get_used_filaments() { std::vector used_filaments; @@ -2359,6 +2386,9 @@ void PartPlate::set_pos_and_size(Vec3d& origin, int width, int depth, int height for (std::set>::iterator it = obj_to_instance_set.begin(); it != obj_to_instance_set.end(); ++it) { int obj_id = it->first; int instance_id = it->second; + if (!valid_instance(obj_id, instance_id)) + continue; + ModelObject* object = m_model->objects[obj_id]; ModelInstance* instance = object->instances[instance_id]; @@ -2403,6 +2433,9 @@ void PartPlate::set_pos_and_size(Vec3d& origin, int width, int depth, int height m_depth = depth; m_height = height; + if (with_instance_move && m_plater) + m_plater->mark_plate_toolbar_image_dirty(); + return; } @@ -2750,6 +2783,8 @@ int PartPlate::add_instance(int obj_id, int instance_id, bool move_position, Bou } BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1% , m_ready_for_slice changes to %2%") % m_plate_index %m_ready_for_slice; + if (m_plater) + m_plater->mark_plate_toolbar_image_dirty(); return 0; } @@ -2833,7 +2868,7 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, s int obj_id = it->first; int instance_id = it->second; - if ((obj_id >= 0) && (obj_id < m_model->objects.size())) + if (valid_instance(obj_id, instance_id)) { ModelObject* object = m_model->objects[obj_id]; ModelInstance* instance = object->instances[instance_id]; @@ -2866,7 +2901,7 @@ void PartPlate::duplicate_all_instance(unsigned int dup_count, bool need_skip, s int obj_id = it->first; int instance_id = it->second; - if ((obj_id >= 0) && (obj_id < m_model->objects.size())) + if (valid_instance(obj_id, instance_id)) { ModelObject* object = m_model->objects[obj_id]; ModelInstance* instance = object->instances[instance_id]; @@ -2983,8 +3018,8 @@ int PartPlate::printable_instance_size() int obj_id = it->first; int instance_id = it->second; - if (obj_id >= m_model->objects.size()) - continue; + if (!valid_instance(obj_id, instance_id)) + continue; ModelObject * object = m_model->objects[obj_id]; ModelInstance *instance = object->instances[instance_id]; @@ -3006,7 +3041,7 @@ bool PartPlate::has_printable_instances() int obj_id = it->first; int instance_id = it->second; - if (obj_id >= m_model->objects.size()) + if (!valid_instance(obj_id, instance_id)) continue; ModelObject* object = m_model->objects[obj_id]; @@ -3030,7 +3065,8 @@ bool PartPlate::is_all_instances_unprintable() int obj_id = it->first; int instance_id = it->second; - if (obj_id >= m_model->objects.size()) continue; + if (!valid_instance(obj_id, instance_id)) + continue; ModelObject * object = m_model->objects[obj_id]; ModelInstance *instance = object->instances[instance_id]; @@ -3502,8 +3538,16 @@ int PartPlate::load_gcode_from_file(const std::string& filename) int ret = 0; // process gcode + auto& preset_bundle = wxGetApp().preset_bundle; std::vector filament_maps = this->get_filament_maps(); - DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(false, filament_maps); + // Inject the plate's volume map (or the per-extruder defaults) exactly like the apply-time + // composition, so the config applied over the loaded slice result matches the next + // background-process apply and does not invalidate the embedded g-code. + std::vector f_volume_maps = this->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(filament_maps); + } + DynamicPrintConfig full_config = preset_bundle->full_config(false, filament_maps, f_volume_maps); full_config.apply(m_config, true); 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, @@ -3810,6 +3854,40 @@ void PartPlate::clear_filament_map() m_config.erase("filament_map"); } +std::vector PartPlate::get_filament_volume_maps() const +{ + std::string key = "filament_volume_map"; + if (m_config.has(key)) + return m_config.option(key)->values; + + return {}; +} + +void PartPlate::set_filament_volume_maps(const std::vector& f_maps) +{ + m_config.option("filament_volume_map", true)->values = f_maps; +} + +void PartPlate::clear_filament_volume_map() +{ + if (m_config.has("filament_volume_map")) + m_config.erase("filament_volume_map"); +} + +std::vector PartPlate::get_filament_nozzle_maps() const +{ + std::string key = "filament_nozzle_map"; + if (m_config.has(key)) + return m_config.option(key)->values; + + return {}; +} + +void PartPlate::set_filament_nozzle_maps(const std::vector& f_maps) +{ + m_config.option("filament_nozzle_map", true)->values = f_maps; +} + void PartPlate::clear_filament_map_mode() { if (m_config.has("filament_map_mode")) @@ -3836,6 +3914,16 @@ void PartPlate::set_filament_count(int filament_count) std::vector& filament_maps = m_config.option("filament_map")->values; filament_maps.resize(filament_count, 1); } + + if (m_config.has("filament_nozzle_map")) { + std::vector& filament_nozzle_map = m_config.option("filament_nozzle_map")->values; + filament_nozzle_map.resize(filament_count, 0); + } + + if (m_config.has("filament_volume_map")) { + std::vector& filament_volume_map = m_config.option("filament_volume_map")->values; + filament_volume_map.resize(filament_count, static_cast(NozzleVolumeType::nvtStandard)); + } } void PartPlate::on_filament_added() @@ -3844,6 +3932,27 @@ void PartPlate::on_filament_added() std::vector& filament_maps = m_config.option("filament_map")->values; filament_maps.push_back(1); } + + if (m_config.has("filament_nozzle_map")) { + std::vector& filament_nozzle_map = m_config.option("filament_nozzle_map")->values; + filament_nozzle_map.push_back(0); + } + + if (m_config.has("filament_volume_map")) { + std::vector& filament_volume_map = m_config.option("filament_volume_map")->values; + // A new filament defaults onto the first extruder, so seed its volume value from + // that extruder's flow type. + int volume_type = static_cast(NozzleVolumeType::nvtStandard); + auto nozzle_volumes = wxGetApp().preset_bundle->project_config.option("nozzle_volume_type"); + if (nozzle_volumes && !nozzle_volumes->values.empty()) + volume_type = nozzle_volumes->values[0]; + // Orca: never store the Hybrid marker as a per-filament value; on a Hybrid extruder + // each filament still prints with a concrete flow, defaulting to Standard. + if (volume_type == static_cast(NozzleVolumeType::nvtHybrid)) + volume_type = static_cast(NozzleVolumeType::nvtStandard); + + filament_volume_map.push_back(volume_type); + } } void PartPlate::on_filament_deleted(int filament_count, int filament_id) @@ -3856,6 +3965,19 @@ void PartPlate::on_filament_deleted(int filament_count, int filament_id) if (filament_id >= 0 && filament_id < (int) filament_maps.size()) filament_maps.erase(filament_maps.begin() + filament_id); } + + if (m_config.has("filament_nozzle_map")) { + std::vector& filament_nozzle_map = m_config.option("filament_nozzle_map")->values; + if (filament_id >= 0 && filament_id < (int) filament_nozzle_map.size()) + filament_nozzle_map.erase(filament_nozzle_map.begin() + filament_id); + } + + if (m_config.has("filament_volume_map")) { + std::vector& filament_volume_map = m_config.option("filament_volume_map")->values; + if (filament_id >= 0 && filament_id < (int) filament_volume_map.size()) + filament_volume_map.erase(filament_volume_map.begin() + filament_id); + } + update_first_layer_print_sequence_when_delete_filament(filament_id); } @@ -4221,6 +4343,12 @@ void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx, bool ini y = I3_WIPE_TOWER_DEFAULT_Y_POS; } + std::string printer_type = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); + // Note: printer_type == "N9" and printer_structure_opt->value == PrinterStructure::psI3 can both be true + if (printer_type == "N9") { + y = N9_WIPE_TOWER_DEFAULT_Y_POS; + } + PartPlate *part_plate = get_plate(plate_idx); Vec3d plate_origin = part_plate->get_origin(); BoundingBoxf3 plate_bbox = part_plate->get_bounding_box(); @@ -4237,7 +4365,14 @@ void PartPlateList::set_default_wipe_tower_pos_for_plate(int plate_idx, bool ini coordf_t plate_bbox_y_max_local_coord = plate_bbox_2d.max(1) - plate_origin(1); std::vector filament_maps = part_plate->get_real_filament_maps(proj_cfg); - DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(false, filament_maps); + // Keep this composition consistent with the apply-time injection (plate volume map, else + // per-extruder defaults); the config below currently only feeds scalar reads, but a + // divergent volume map would silently mis-resolve any future per-filament read here. + std::vector f_volume_maps = part_plate->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = wxGetApp().preset_bundle->get_default_nozzle_volume_types_for_filaments(filament_maps); + } + DynamicPrintConfig full_config = wxGetApp().preset_bundle->full_config(false, filament_maps, f_volume_maps); const DynamicPrintConfig &print_cfg = wxGetApp().preset_bundle->prints.get_edited_preset().config; float w = dynamic_cast(print_cfg.option("prime_tower_width"))->value; float v = dynamic_cast(full_config.option("prime_volume"))->value; @@ -5214,6 +5349,9 @@ int PartPlateList::notify_instance_removed(int obj_id, int instance_id) unprintable_plate.update_object_index(obj_id, m_model->objects.size()); } + if (m_plater) + m_plater->mark_plate_toolbar_image_dirty(); + return 0; } @@ -6135,6 +6273,9 @@ int PartPlateList::rebuild_plates_after_arrangement(bool recycle_plates, bool ex } #endif + if (m_plater) + m_plater->mark_plate_toolbar_image_dirty(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":after rebuild, plates count %1%") % m_plate_list.size(); return ret; } @@ -6279,6 +6420,58 @@ int PartPlateList::load_from_3mf_structure(PlateDataPtrs& plate_data_list, int f m_plate_list[index]->slice_filaments_info = plate_data_list[i]->slice_filaments_info; gcode_result->warnings = plate_data_list[i]->warnings; gcode_result->filament_maps = plate_data_list[i]->filament_maps; + + // Reconstruct the device-side nozzle grouping from the loaded 3mf so + // the monitor/preview can map filaments to physical nozzles. + // load_nozzle_infos_with_compatibility handles older single-nozzle 3mf (no tags) by + // falling back to the per-filament group_id, then to the extruder volume types / nozzle diameters. + { + // nozzle_volume_types is space-separated ints; nozzle_diameters is comma/space-separated floats. + auto parse_int_tokens = [](const std::string& str) -> std::vector { + std::vector out; + std::istringstream iss(str); + std::string tok; + while (iss >> tok) { try { out.push_back(std::stoi(tok)); } catch (...) {} } + return out; + }; + auto parse_double_tokens = [](const std::string& str) -> std::vector { + std::vector out; + std::string s = str; + std::replace(s.begin(), s.end(), ',', ' '); + std::istringstream iss(s); + std::string tok; + while (iss >> tok) { try { out.push_back(std::stod(tok)); } catch (...) {} } + return out; + }; + + std::vector nozzle_volume_type_values = parse_int_tokens(plate_data_list[i]->nozzle_volume_types); + std::vector nozzle_diameter_values = parse_double_tokens(plate_data_list[i]->nozzle_diameters); + + std::vector extruder_volume_types(nozzle_volume_type_values.size(), NozzleVolumeType::nvtStandard); + for (size_t idx = 0; idx < nozzle_volume_type_values.size(); ++idx) + if (nozzle_volume_type_values[idx] >= 0 && nozzle_volume_type_values[idx] <= nvtMaxNozzleVolumeType) + extruder_volume_types[idx] = static_cast(nozzle_volume_type_values[idx]); + + auto nozzle_infos = MultiNozzleUtils::load_nozzle_infos_with_compatibility( + plate_data_list[i]->nozzles_info, + plate_data_list[i]->slice_filaments_info, + plate_data_list[i]->filament_maps, + extruder_volume_types, + nozzle_diameter_values); + + std::vector fil_seq(plate_data_list[i]->filament_change_sequence.begin(), plate_data_list[i]->filament_change_sequence.end()); + std::vector noz_seq(plate_data_list[i]->nozzle_change_sequence.begin(), plate_data_list[i]->nozzle_change_sequence.end()); + bool enable_filament_dynamic_map = false; + if (plate_data_list[i]->config.has("enable_filament_dynamic_map")) + enable_filament_dynamic_map = plate_data_list[i]->config.option("enable_filament_dynamic_map")->value; + + auto group_result = MultiNozzleUtils::StaticNozzleGroupResult::create( + plate_data_list[i]->slice_filaments_info, nozzle_infos, fil_seq, noz_seq, enable_filament_dynamic_map); + if (group_result) + gcode_result->nozzle_group_result = std::make_shared(group_result.value()); + else + gcode_result->nozzle_group_result = nullptr; + } if (m_plater && !plate_data_list[i]->thumbnail_file.empty()) { BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": plate %1%, load thumbnail from %2%.")%(i+1) %plate_data_list[i]->thumbnail_file; if (boost::filesystem::exists(plate_data_list[i]->thumbnail_file)) { @@ -6438,9 +6631,10 @@ void PartPlateList::init_bed_type_info() auto bed_texture_maps = wxGetApp().plater()->get_bed_texture_maps(); std::string bottom_texture_end_name = bed_texture_maps.find("bottom_texture_end_name") != bed_texture_maps.end() ? bed_texture_maps["bottom_texture_end_name"] : ""; std::string bottom_texture_rect_str = bed_texture_maps.find("bottom_texture_rect") != bed_texture_maps.end() ? bed_texture_maps["bottom_texture_rect"] : ""; + std::string bottom_texture_rect_longer_str = bed_texture_maps.find("bottom_texture_rect_longer") != bed_texture_maps.end() ? bed_texture_maps["bottom_texture_rect_longer"] : ""; std::string middle_texture_rect_str = bed_texture_maps.find("middle_texture_rect") != bed_texture_maps.end() ? bed_texture_maps["middle_texture_rect"] : ""; std::string use_double_extruder_default_texture = bed_texture_maps.find("use_double_extruder_default_texture") != bed_texture_maps.end() ? bed_texture_maps["use_double_extruder_default_texture"] : ""; - std::array bottom_texture_rect = {0, 0, 0, 0}, middle_texture_rect = {0, 0, 0, 0}; + std::array bottom_texture_rect = {0, 0, 0, 0}, bottom_texture_rect_longer = {0, 0, 0, 0}, middle_texture_rect = {0, 0, 0, 0}; if (bottom_texture_rect_str.size() > 0) { std::vector items; boost::algorithm::erase_all(bottom_texture_rect_str, " "); @@ -6451,6 +6645,16 @@ void PartPlateList::init_bed_type_info() } } } + if (bottom_texture_rect_longer_str.size() > 0) { + std::vector items; + boost::algorithm::erase_all(bottom_texture_rect_longer_str, " "); + boost::split(items, bottom_texture_rect_longer_str, boost::is_any_of(",")); + if (items.size() == 4) { + for (int i = 0; i < items.size(); i++) { + bottom_texture_rect_longer[i] = std::atof(items[i].c_str()); + } + } + } if (middle_texture_rect_str.size() > 0) { std::vector items; boost::algorithm::erase_all(middle_texture_rect_str, " "); @@ -6471,6 +6675,7 @@ void PartPlateList::init_bed_type_info() } pte_part2 = BedTextureInfo::TexturePart(45, -14.5, 70, 8, "bbl_bed_pte_left_bottom.svg"); auto &bottom_rect = bottom_texture_rect; + auto &bottom_rect_longer = bottom_texture_rect_longer; if (bottom_texture_end_name.size() > 0 && bottom_rect[2] > 0.f) { std::string pte_part2_name = "bbl_bed_pte_bottom_" + bottom_texture_end_name + ".svg"; pte_part2 = BedTextureInfo::TexturePart(bottom_rect[0], bottom_rect[1], bottom_rect[2], bottom_rect[3], pte_part2_name); @@ -6494,6 +6699,9 @@ void PartPlateList::init_bed_type_info() if (bottom_texture_end_name.size() > 0 && bottom_rect[2] > 0.f) { std::string st_part2_name = "bbl_bed_st_bottom_" + bottom_texture_end_name + ".svg"; st_part2 = BedTextureInfo::TexturePart(bottom_rect[0], bottom_rect[1], bottom_rect[2], bottom_rect[3], st_part2_name); + } else if (bottom_rect_longer[2] > 0.f) { + // SuperTack bottom strip uses the wider "longer" rect. + st_part2.update_pos(bottom_rect_longer[0], bottom_rect_longer[1], bottom_rect_longer[2], bottom_rect_longer[3]); } ep_part1 = BedTextureInfo::TexturePart(57, 300, 236.12f, 10.f, "bbl_bed_ep_middle.svg"); @@ -6504,6 +6712,9 @@ void PartPlateList::init_bed_type_info() if (bottom_texture_end_name.size() > 0 && bottom_rect[2] > 0.f) { std::string ep_part2_name = "bbl_bed_ep_bottom_" + bottom_texture_end_name + ".svg"; ep_part2 = BedTextureInfo::TexturePart(bottom_rect[0], bottom_rect[1], bottom_rect[2], bottom_rect[3], ep_part2_name); + } else if (bottom_rect_longer[2] > 0.f) { + // Engineering-plate bottom strip uses the wider "longer" rect. + ep_part2.update_pos(bottom_rect_longer[0], bottom_rect_longer[1], bottom_rect_longer[2], bottom_rect_longer[3]); } pc_part1 = BedTextureInfo::TexturePart(57, 300, 236.12f, 10.f, "bbl_bed_pc_middle.svg"); diff --git a/src/slic3r/GUI/PartPlate.hpp b/src/slic3r/GUI/PartPlate.hpp index d4c5399142..8f4055706f 100644 --- a/src/slic3r/GUI/PartPlate.hpp +++ b/src/slic3r/GUI/PartPlate.hpp @@ -167,7 +167,7 @@ private: wxCoord m_name_texture_height; void init(); - bool valid_instance(int obj_id, int instance_id); + bool valid_instance(int obj_id, int instance_id) const; void generate_print_polygon(ExPolygon &print_polygon); void generate_exclude_polygon(ExPolygon &exclude_polygon); void generate_logo_polygon(ExPolygon &logo_polygon); @@ -253,6 +253,7 @@ public: PrintSequence get_real_print_seq(bool* plate_same_as_global=nullptr) const; std::vector get_real_filament_maps(const DynamicConfig& g_config, bool* use_global_param = nullptr)const; + std::vector get_real_filament_volume_maps(const DynamicConfig& g_config, bool* use_global_param = nullptr) const; FilamentMapMode get_real_filament_map_mode(const DynamicConfig& g_config,bool * use_global_param = nullptr) const; FilamentMapMode get_filament_map_mode() const; @@ -262,6 +263,15 @@ public: std::vector get_filament_maps() const; void set_filament_maps(const std::vector& f_maps); + // per-filament nozzle-volume choice (NozzleVolumeType values, 0 based filament ids) + std::vector get_filament_volume_maps() const; + void set_filament_volume_maps(const std::vector& f_maps); + void clear_filament_volume_map(); + + // per-filament nozzle-group choice (0 based filament and nozzle ids) + std::vector get_filament_nozzle_maps() const; + void set_filament_nozzle_maps(const std::vector& f_maps); + void clear_filament_map(); void clear_filament_map_mode(); @@ -340,6 +350,7 @@ public: std::vector get_used_filaments(); const std::vector& get_slice_filaments_info() const { return slice_filaments_info; } int get_physical_extruder_by_filament_id(const DynamicConfig& g_config, int idx) const; + int get_logical_extruder_by_filament_id(const DynamicConfig& g_config, int idx) const; bool check_filament_printable(const DynamicPrintConfig & config, wxString& error_message); bool check_tpu_printable_status(const DynamicPrintConfig & config, const std::vector &tpu_filaments); bool check_mixture_of_pla_and_petg(const DynamicPrintConfig & config); @@ -668,6 +679,12 @@ public: this->filename = part.filename; this->texture = part.texture; } + void update_pos(float xx, float yy, float ww, float hh) { + x = xx; + y = yy; + w = ww; + h = hh; + } void update_file(std::string file) { filename = file; } diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index 8deede98ac..9cd8dec3e2 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -123,6 +123,8 @@ #include "NotificationManager.hpp" #include "PresetComboBoxes.hpp" #include "MsgDialog.hpp" +#include "Widgets/MultiNozzleSync.hpp" // NozzleOption, tryPopUpMultiNozzleDialog, setExtruderNozzleCount +#include "DeviceCore/DevNozzleSystem.h" // DevNozzle, GetExtNozzles / GetRackNozzles #include "ProjectDirtyStateManager.hpp" #include "Gizmos/GLGizmoSimplify.hpp" // create suggestion notification #include "Gizmos/GLGizmoSVG.hpp" // Drop SVG file @@ -169,6 +171,7 @@ #include "StepMeshDialog.hpp" #include "FilamentMapDialog.hpp" #include "CloneDialog.hpp" +#include "PurgeModeDialog.hpp" #include "DeviceCore/DevFilaSystem.h" #include "DeviceCore/DevManager.h" @@ -275,6 +278,21 @@ void Plater::show_illegal_characters_warning(wxWindow* parent) show_error(parent, _L("Invalid name, the following characters are not allowed:") + " <>:/\\|?*\""); } +void Plater::mark_plate_toolbar_image_dirty() +{ + m_b_plate_toolbar_image_dirty = true; +} + +bool Plater::is_plate_toolbar_image_dirty() const +{ + return m_b_plate_toolbar_image_dirty; +} + +void Plater::clear_plate_toolbar_image_dirty() +{ + m_b_plate_toolbar_image_dirty = false; +} + static std::map bed_type_thumbnails = { {BedType::btPC, "bed_cool" }, {BedType::btEP, "bed_engineering" }, @@ -430,10 +448,123 @@ enum class ActionButtonType : int { abSendGCode }; +// Interactive title row for the sidebar extruder cards: " ( <count> ) [edit]". The count shows the +// extruder's physical nozzle count on multi-nozzle printers (hidden elsewhere, SetCount(-1)), and the +// trailing button opens the manual nozzle-count editor when enabled (a plain dot otherwise). +class HoverLabel : public wxPanel +{ +public: + HoverLabel(wxWindow *parent, const wxString &label) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) + { +#ifdef __WXOSX__ + SetBackgroundColour("#F7F7F7"); +#else + SetBackgroundColour(*wxWHITE); +#endif + auto sizer = new wxBoxSizer(wxHORIZONTAL); + + m_label = new wxStaticText(this, wxID_ANY, label, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_label->SetFont(Label::Body_13); + m_label->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#6B6B6B"))); + + m_brace_left = new wxStaticText(this, wxID_ANY, "(", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_brace_left->SetFont(Label::Body_13); + m_brace_left->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_brace_left->Hide(); + + m_count = new wxStaticText(this, wxID_ANY, "", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_count->SetFont(Label::Body_13.Bold()); + m_count->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_count->Hide(); + + m_brace_right = new wxStaticText(this, wxID_ANY, ")", wxDefaultPosition, wxDefaultSize, wxBORDER_NONE); + m_brace_right->SetFont(Label::Body_13); + m_brace_right->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#262E30"))); + m_brace_right->Hide(); + + m_hover_btn = new ScalableButton(this, wxID_ANY, "dot"); + m_hover_btn->SetMinSize(wxSize(FromDIP(25), -1)); +#ifdef __WXOSX__ + m_hover_btn->SetBackgroundColour("#F7F7F7"); +#else + m_hover_btn->SetBackgroundColour(*wxWHITE); +#endif + m_hover_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](auto &evt) { + if (m_enabled && m_hover_on_click) + m_hover_on_click(); + }); + + sizer->Add(m_label, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_brace_left, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_count, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_brace_right, 0, wxALIGN_CENTER_VERTICAL); + sizer->Add(m_hover_btn, 0, wxLEFT | wxALIGN_CENTER_VERTICAL, FromDIP(5)); + + // No SetSizerAndFit: that would record the count-hidden width as an explicit min size, + // which outranks best size in sizer allocation, so once the count is shown any ancestor + // Layout() would shrink the row back and clip the trailing edit button. + SetSizer(sizer); + Layout(); + } + + void EnableEdit(bool enable) + { + m_enabled = enable; + m_hover_btn->SetBitmap_(enable ? "edit" : "dot"); + } + + void SetOnHoverClick(std::function<void()> on_click) { m_hover_on_click = std::move(on_click); } + + void SetCount(int count) + { + if (count < 0) { + m_count->Hide(); + m_brace_left->Hide(); + m_brace_right->Hide(); + } else { + m_count->SetLabel(wxString::Format("%d", count)); + m_count->Show(); + m_brace_left->Show(); + m_brace_right->Show(); + } + UpdateSizing(); + } + + void SetTitle(const wxString &title) + { + m_label->SetLabel(title); + UpdateSizing(); + } + + void Rescale() { m_hover_btn->msw_rescale(); } + +private: + // Content changed: the cached best size (ours and, transitively, our ancestors') is stale, + // and the parent must re-lay this row or the sizer keeps allocating the old width. + void UpdateSizing() + { + InvalidateBestSize(); + Layout(); + Fit(); + if (GetParent()) + GetParent()->Layout(); + } + + wxStaticText *m_label; + wxStaticText *m_brace_left; + wxStaticText *m_count; + wxStaticText *m_brace_right; + ScalableButton *m_hover_btn; + + std::function<void()> m_hover_on_click; + bool m_enabled{false}; +}; + struct ExtruderGroup : StaticGroup { ExtruderGroup(wxWindow * parent, int index, wxString const &title); wxStaticBoxSizer *sizer = nullptr; + HoverLabel * hover_label = nullptr; ScalableButton * btn_edit = nullptr; ComboBox * combo_diameter = nullptr; ComboBox * combo_flow = nullptr; @@ -463,11 +594,16 @@ struct ExtruderGroup : StaticGroup void update_ams(); void SetTitle(const wxString& title); + void SetCount(int count) { if (hover_label) hover_label->SetCount(count); } + void SetEditEnabled(bool enable) { if (hover_label) hover_label->EnableEdit(enable); } + void SetOnHoverClick(std::function<void()> on_click) { if (hover_label) hover_label->SetOnHoverClick(std::move(on_click)); } void sync_ams(MachineObject const *obj, std::vector<DevAms *> const &ams4, std::vector<DevAms *> const &ams1); void Rescale() { + if (hover_label) + hover_label->Rescale(); if (btn_edit) btn_edit->msw_rescale(); btn_up->msw_rescale(); @@ -538,6 +674,7 @@ struct Sidebar::priv //wxComboBox * m_comboBox_print_preset; wxStaticLine * m_staticline1; StaticBox* m_panel_filament_title; + wxPanel* m_panel_filament_separator; wxStaticText* m_staticText_filament_settings; wxStaticText* m_staticText_filament_count; ScalableButton * m_bpButton_add_filament; @@ -550,6 +687,7 @@ struct Sidebar::priv wxStaticLine* m_staticline2; wxPanel* m_panel_project_title; ScalableButton* m_filament_icon = nullptr; + Button * m_purge_mode_btn = nullptr; Button * m_flushing_volume_btn = nullptr; TextInput* m_search_item = nullptr; StaticBox* m_search_bar = nullptr; @@ -557,12 +695,16 @@ struct Sidebar::priv // BBS printer config StaticBox* m_panel_printer_title = nullptr; + wxPanel* m_panel_printer_separator = nullptr; ScalableButton* m_printer_icon = nullptr; ScalableButton* m_printer_connect = nullptr; ScalableButton* m_printer_bbl_sync = nullptr; ScalableButton* m_printer_setting = nullptr; wxStaticText * m_text_printer_settings = nullptr; wxPanel* m_panel_printer_content = nullptr; + // Filament Track Switch status overlay: an icon floated over the left/single extruder AMS area, + // shown only when the switch is installed (green when ready, red when not calibrated). + wxStaticBitmap* extruder_separator_icon = nullptr; ObjectList *m_object_list{ nullptr }; ObjectSettings *object_settings{ nullptr }; @@ -585,10 +727,27 @@ struct Sidebar::priv void jump_to_object(ObjectDataViewModelNode* item); void can_search(); - bool sync_extruder_list(bool &only_external_material); + bool sync_extruder_list(bool &only_external_material, bool is_manual = false); + // Resolve the nozzle option for a multi-nozzle machine. Returns nullopt (and is a no-op) unless + // extruder_count >= 2 && support_multi_nozzle. When is_manual, always pops the MultiNozzleSyncDialog; + // otherwise reuses the app_config-cached option when the machine's nozzle config is unchanged. + std::optional<NozzleOption> get_nozzle_options(MachineObject* obj, int extruder_count, bool support_multi_nozzle, bool is_manual); bool switch_diameter(bool single); void update_sync_status(const MachineObject* obj); + // Filament Track Switch (H2-family accessory): true only when the connected printer is the + // selected one, online, and reports the switch installed and calibrated. + bool is_fila_switch_ready(); + // One-time info tip when the switch is ready, and a not-calibrated warning otherwise. + void show_filament_switcher_dialog(bool is_ready, bool is_manual); + void show_fila_switch_msg(bool ready); + bool fila_switch_warning_shown = false; + // Show/hide and reposition the switcher status icon; caches the last state to avoid churn. + void update_extruder_separator_icon(bool show, bool ready); + // Orca: BBS resets the switcher UI from DeviceManager::OnSelectedMachineChanged, which Orca lacks. + // Track the last-synced device id here so update_sync_status can detect a machine change. + std::string last_sync_dev_id; + #ifdef _WIN32 wxString btn_reslice_tip; void show_rich_tip(const wxString& tooltip, wxButton* btn); @@ -637,6 +796,18 @@ void Sidebar::priv::layout_printer(bool isBBL, bool isDual) extruder_dual_sizer->AddSpacer(FromDIP(4)); extruder_dual_sizer->Add(right_extruder->sizer, 1, wxEXPAND, 0); + // Filament Track Switch status icon, floated over the extruder AMS area (positioned in + // update_extruder_separator_icon). Created hidden; a click re-shows the ready/not-ready tip. + if (!extruder_separator_icon) { + auto bitmap = ScalableBitmap(m_panel_printer_content, "fila_switch", 10); + extruder_separator_icon = new wxStaticBitmap(m_panel_printer_content, wxID_ANY, bitmap.bmp(), wxDefaultPosition, bitmap.GetBmpSize()); + extruder_separator_icon->Hide(); + extruder_separator_icon->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent& evt) { + show_fila_switch_msg(is_fila_switch_ready()); + evt.Skip(); + }); + } + // single extruder_single_sizer = single_extruder->sizer; wxBoxSizer * extruder_sizer = new wxBoxSizer(wxVERTICAL); @@ -1045,13 +1216,18 @@ public: }; ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title) - : StaticGroup(parent, wxID_ANY, title) + : StaticGroup(parent, wxID_ANY, wxString()) { SetFont(Label::Body_10); SetForegroundColour(wxColour("#CECECE")); SetBorderColor(wxColour("#EEEEEE")); SetCornerRadius(FromDIP(PRINTER_PANEL_RADIUS)); // ORCA match radius with other boxes ShowBadge(true); + + // The title lives in an interactive row inside the card (with the nozzle-count badge and its edit + // button) instead of being painted on the border by StaticGroup. + hover_label = new HoverLabel(this, title); + // Nozzle wxStaticText *label_diameter = new wxStaticText(this, wxID_ANY, _L("Diameter")); label_diameter->SetFont(Label::Body_14); @@ -1067,9 +1243,16 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title combo_flow->GetDropDown().SetUseContentWidth(true); combo_flow->Bind(wxEVT_COMBOBOX, [this, index, combo_flow](wxCommandEvent &evt) { auto printer_tab = dynamic_cast<TabPrinter *>(wxGetApp().get_tab(Preset::TYPE_PRINTER)); - printer_tab->set_extruder_volume_type(index, NozzleVolumeType(intptr_t(combo_flow->GetClientData(evt.GetInt())))); - if (GUI::wxGetApp().plater()) - GUI::wxGetApp().plater()->update_machine_sync_status(); + NozzleVolumeType volume_type = NozzleVolumeType(intptr_t(combo_flow->GetClientData(evt.GetInt()))); + printer_tab->set_extruder_volume_type(index, volume_type); + auto plater = GUI::wxGetApp().plater(); + if (plater) { + // A new Flow type invalidates the per-filament volume choices stored on the + // plates for this extruder; rewrite them so the next apply/grouping sees the + // selected volume instead of a stale one. + plater->update_filament_volume_map(index, static_cast<int>(volume_type)); + plater->update_machine_sync_status(); + } }); this->combo_flow = combo_flow; @@ -1146,15 +1329,19 @@ ExtruderGroup::ExtruderGroup(wxWindow * parent, int index, wxString const &title if (index < 0) { label_ams->Hide(); ams_not_installed_msg->Hide(); - wxStaticBoxSizer *hsizer = new wxStaticBoxSizer(this, wxHORIZONTAL); + wxStaticBoxSizer *vsizer = new wxStaticBoxSizer(this, wxVERTICAL); + wxBoxSizer *hsizer = new wxBoxSizer(wxHORIZONTAL); hsizer->Add(hsizer_diameter, 1, wxEXPAND | wxTOP| wxBOTTOM, FromDIP(8)); hsizer->Add(hsizer_nozzle, 1, wxEXPAND | wxALL, FromDIP(8)); hsizer->AddSpacer(FromDIP(2)); // Avoid badge - this->sizer = hsizer; + vsizer->Add(hover_label, 0, wxLEFT | wxALL, FromDIP(2)); + vsizer->Add(hsizer, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(2)); + this->sizer = vsizer; } else { wxStaticBoxSizer *vsizer = new wxStaticBoxSizer(this, wxVERTICAL); - vsizer->Add(hsizer_ams, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(2)); - vsizer->Add(hsizer_diameter, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT | wxBOTTOM, FromDIP(2)); + vsizer->Add(hover_label, 0, wxLEFT | wxALL, FromDIP(2)); + vsizer->Add(hsizer_ams, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, FromDIP(2)); + vsizer->Add(hsizer_diameter, 0, wxEXPAND | wxLEFT | wxTOP | wxRIGHT, FromDIP(2)); vsizer->Add(hsizer_nozzle, 0, wxEXPAND | wxALL, FromDIP(2)); this->sizer = vsizer; } @@ -1254,12 +1441,8 @@ void ExtruderGroup::sync_ams(MachineObject const *obj, std::vector<DevAms *> con void ExtruderGroup::SetTitle(const wxString& title) { - m_label = title; - int tW, tH, descent, externalLeading; - GetTextExtent(m_label.IsEmpty() ? "Orca" : m_label, &tW, &tH, &descent, &externalLeading, &m_font); - m_label_height = tH - externalLeading; - m_label_width = tW; - Refresh(); + if (hover_label) + hover_label->SetTitle(title); } bool Sidebar::priv::switch_diameter(bool single) @@ -1324,7 +1507,393 @@ static bool is_skip_high_flow_printer(const std::string& printer) return invalidate_list.count(printer); }; -bool Sidebar::priv::sync_extruder_list(bool &only_external_material) +// ---- Multi-nozzle sync helpers ---------------------------- +// Serialize/deserialize the machine nozzle config + chosen NozzleOption for the app_config +// "sync_extruder" reuse cache, and Sidebar::priv::get_nozzle_options (the nozzle picker). + +static std::string serialize_nozzle_config(const std::map<int, std::vector<DevNozzle>>& nozzle_cfg_map) +{ + std::ostringstream oss; + + std::vector<DevNozzle> deputy_nozzles; + auto deputy_it = nozzle_cfg_map.find(1); + if (deputy_it != nozzle_cfg_map.end()) { + deputy_nozzles = deputy_it->second; + } + + std::vector<DevNozzle> main_nozzles; + auto main_it = nozzle_cfg_map.find(0); + if (main_it != nozzle_cfg_map.end()) { + main_nozzles = main_it->second; + } + + for (size_t i = 0; i < deputy_nozzles.size(); ++i) { + if (i > 0) oss << ";"; + oss << std::fixed << std::setprecision(1) << deputy_nozzles[i].GetNozzleDiameter() << "," + << static_cast<int>(deputy_nozzles[i].GetNozzleFlowType()); + } + + oss << "|"; + + for (size_t i = 0; i < main_nozzles.size(); ++i) { + if (i > 0) oss << ";"; + oss << std::fixed << std::setprecision(1) << main_nozzles[i].GetNozzleDiameter() << "," + << static_cast<int>(main_nozzles[i].GetNozzleFlowType()); + } + + return oss.str(); +} + +static std::map<int, std::vector<DevNozzle>> deserialize_nozzle_config(const std::string &config_str) +{ + std::map<int, std::vector<DevNozzle>> nozzle_cfg_map; + if (config_str.empty()) return nozzle_cfg_map; + + std::vector<std::string> extruder_parts; + boost::split(extruder_parts, config_str, boost::is_any_of("|")); + + auto get_nozzles_from_string = [](const std::string& part_str) -> std::vector<DevNozzle> { + std::vector<DevNozzle> nozzles; + std::vector<std::string> parts; + boost::split(parts, part_str, boost::is_any_of(";")); + for (const auto &part : parts) { + std::vector<std::string> values; + boost::split(values, part, boost::is_any_of(",")); + if (values.size() == 2) { + DevNozzle nozzle; + nozzle.m_diameter = std::stof(values[0]); + nozzle.m_nozzle_flow = static_cast<NozzleFlowType>(std::stoi(values[1])); + nozzles.push_back(nozzle); + } + } + return nozzles; + }; + + if (extruder_parts.size() != 2) { + auto nozzles = get_nozzles_from_string(config_str); + nozzle_cfg_map[MAIN_EXTRUDER_ID] = nozzles; + nozzle_cfg_map[DEPUTY_EXTRUDER_ID] = { DevNozzle() }; + return nozzle_cfg_map; + } + + if (!extruder_parts[0].empty()) { + auto nozzles = get_nozzles_from_string(extruder_parts[0]); + nozzle_cfg_map[DEPUTY_EXTRUDER_ID] = nozzles; + } + if (!extruder_parts[1].empty()) { + auto nozzles = get_nozzles_from_string(extruder_parts[1]); + nozzle_cfg_map[MAIN_EXTRUDER_ID] = nozzles; + } + + return nozzle_cfg_map; +} + +static bool is_same_nozzle_config(const std::map<int, std::vector<DevNozzle>> &config1, const std::map<int, std::vector<DevNozzle>> &config2) +{ + if (config1.size() != config2.size()) return false; + + for (const auto& [eid, nozzles1] : config1) { + auto it = config2.find(eid); + if (it == config2.end()) return false; + + const auto &nozzles2 = it->second; + if (nozzles1.size() != nozzles2.size()) return false; + + auto sorted_nozzles1 = nozzles1; + auto sorted_nozzles2 = nozzles2; + + auto compare_nozzle = [](const DevNozzle &a, const DevNozzle &b) { + float dia_a = a.GetNozzleDiameter(); + float dia_b = b.GetNozzleDiameter(); + if (std::abs(dia_a - dia_b) > EPSILON) { + return dia_a < dia_b; + } + return static_cast<int>(a.GetNozzleFlowType()) < static_cast<int>(b.GetNozzleFlowType()); + }; + + std::sort(sorted_nozzles1.begin(), sorted_nozzles1.end(), compare_nozzle); + std::sort(sorted_nozzles2.begin(), sorted_nozzles2.end(), compare_nozzle); + + for (size_t i = 0; i < sorted_nozzles1.size(); ++i) { + if (std::abs(sorted_nozzles1[i].GetNozzleDiameter() - sorted_nozzles2[i].GetNozzleDiameter()) > EPSILON || + sorted_nozzles1[i].GetNozzleFlowType() != sorted_nozzles2[i].GetNozzleFlowType()) { + return false; + } + } + } + + return true; +} + +static std::string serialize_nozzle_option(const NozzleOption& option) { + std::ostringstream oss; + oss << option.diameter << "|"; + + bool first = true; + for (const auto& pair : option.extruder_nozzle_stats) { + if (!first) oss << ";"; + first = false; + oss << pair.first << ":"; + + bool first_stat = true; + for (const auto& stat_pair : pair.second) { + if (!first_stat) oss << ","; + first_stat = false; + oss << static_cast<int>(stat_pair.first) << "#" << stat_pair.second; + } + } + return oss.str(); +} + +static std::optional<NozzleOption> deserialize_nozzle_option(const std::string& option_str) { + if (option_str.empty()) return std::nullopt; + + std::vector<std::string> parts; + boost::split(parts, option_str, boost::is_any_of("|")); + if (parts.size() != 2) return std::nullopt; + + NozzleOption option; + option.diameter = parts[0]; + + std::vector<std::string> extruder_parts; + boost::split(extruder_parts, parts[1], boost::is_any_of(";")); + + for (const auto& extruder_part : extruder_parts) { + if (extruder_part.empty()) continue; + + std::vector<std::string> extruder_data; + boost::split(extruder_data, extruder_part, boost::is_any_of(":")); + if (extruder_data.size() != 2) continue; + + int extruder_id = std::stoi(extruder_data[0]); + std::unordered_map<NozzleVolumeType, int> stats; + + std::vector<std::string> stat_parts; + boost::split(stat_parts, extruder_data[1], boost::is_any_of(",")); + + for (const auto& stat_part : stat_parts) { + std::vector<std::string> kv; + boost::split(kv, stat_part, boost::is_any_of("#")); + if (kv.size() == 2) { + NozzleVolumeType type = static_cast<NozzleVolumeType>(std::stoi(kv[0])); + int count = std::stoi(kv[1]); + stats[type] = count; + } + } + + option.extruder_nozzle_stats[extruder_id] = stats; + } + + return option; +} + +std::optional<NozzleOption> Sidebar::priv::get_nozzle_options(MachineObject* obj, int extruder_count, bool support_multi_nozzle, bool is_manual) +{ + if (extruder_count < 2 || !support_multi_nozzle) { + return std::nullopt; + } + if (!obj || !obj->GetNozzleSystem()) return std::nullopt; + auto nozzle_system = obj->GetNozzleSystem(); + + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (!preset_bundle) return std::nullopt; + + std::string curr_dev_id = obj->get_dev_id(); + std::map<int, std::vector<DevNozzle>> curr_nozzle_cfg; + + for (const auto& ext_nozzle : nozzle_system->GetExtNozzles()) { + int extruder_id = ext_nozzle.first; + curr_nozzle_cfg[extruder_id].emplace_back(ext_nozzle.second); + } + + for (const auto& rack_nozzle : nozzle_system->GetRackNozzles()) { + curr_nozzle_cfg[MAIN_EXTRUDER_ID].emplace_back(rack_nozzle.second); + } + + AppConfig *app_config = wxGetApp().app_config; + std::string saved_dev_id = app_config->get("sync_extruder", "dev_id"); + std::string saved_nozzle_config_str = app_config->get("sync_extruder", "nozzle_config"); + std::string saved_nozzle_option_str = app_config->get("sync_extruder", "nozzle_option"); + std::optional<NozzleOption> nozzle_option; + + if (is_manual) { + nozzle_option = tryPopUpMultiNozzleDialog(obj); + } else { + bool can_reuse_saved_option = false; + if (!saved_dev_id.empty() && !saved_nozzle_config_str.empty() && !saved_nozzle_option_str.empty() && saved_dev_id == curr_dev_id) { + auto saved_nozzle_config = deserialize_nozzle_config(saved_nozzle_config_str); + if (is_same_nozzle_config(saved_nozzle_config, curr_nozzle_cfg)) { + nozzle_option = deserialize_nozzle_option(saved_nozzle_option_str); + can_reuse_saved_option = nozzle_option.has_value(); + } + if (can_reuse_saved_option) { + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " Reusing saved nozzle option for dev_id: " << curr_dev_id; + + auto &project_config = preset_bundle->project_config; + ConfigOptionEnumsGeneric *nozzle_volume_type_opt = project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); + + // Write to preset bundle config + for (int extruder_id = 0; extruder_id < extruder_count; ++extruder_id) { + NozzleVolumeType volume_type; + int nozzle_count; + bool clear_all = true; + + if (!nozzle_option->extruder_nozzle_stats.count(extruder_id)) { + nozzle_count = 0; + // Reset the concrete volume types (Standard/High Flow); Hybrid is not a physical + // nozzle type and never appears in the stats. TPU High Flow is a concrete variant + // shipped on 0.4/0.6 nozzles, so reset it too, but only there (mirrors the + // High-Flow-skip-for-0.2 guard). + std::vector<NozzleVolumeType> reset_types{nvtStandard, nvtHighFlow}; + if (extruder_supports_tpu_high_flow(preset_bundle, extruder_id)) + reset_types.push_back(nvtTPUHighFlow); + for (NozzleVolumeType vt : reset_types) { + volume_type = vt; + setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, nozzle_count, clear_all); + clear_all = false; + } + } else { + for (auto &stat : nozzle_option->extruder_nozzle_stats[extruder_id]) { + volume_type = stat.first; + nozzle_count = stat.second; + setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, nozzle_count, clear_all); + clear_all = false; + } + } + } + // The stats now hold the device's per-type breakdown: protect it from being collapsed by + // a manual flow switch, and refresh the sidebar badges. + setNozzleStatsFromMachine(true); + if (nozzle_volume_type_opt) { + for (int extruder_id = 0; extruder_id < extruder_count && extruder_id < (int) nozzle_volume_type_opt->values.size(); ++extruder_id) + updateNozzleCountDisplay(preset_bundle, extruder_id, NozzleVolumeType(nozzle_volume_type_opt->values[extruder_id])); + } + } + } + + if (!can_reuse_saved_option) { + nozzle_option = tryPopUpMultiNozzleDialog(obj); + } + } + if (nozzle_option) { + std::string current_nozzle_config = serialize_nozzle_config(curr_nozzle_cfg); + std::string current_nozzle_option = serialize_nozzle_option(*nozzle_option); + if (app_config->has_section("sync_extruder")) { + app_config->set("sync_extruder", "dev_id", curr_dev_id); + app_config->set("sync_extruder", "nozzle_config", current_nozzle_config); + app_config->set("sync_extruder", "nozzle_option", current_nozzle_option); + } else { + std::map<std::string, std::string> data; + data["dev_id"] = curr_dev_id; + data["nozzle_config"] = current_nozzle_config; + data["nozzle_option"] = current_nozzle_option; + app_config->set_section("sync_extruder", data); + } + } + + return nozzle_option; +} + +bool Sidebar::priv::is_fila_switch_ready() +{ + if (!wxGetApp().plater()->is_same_printer_for_connected_and_selected(false)) + return false; + auto device_manager = wxGetApp().getDeviceManager(); + if (device_manager == nullptr) + return false; + auto obj = device_manager->get_selected_machine(); + if (obj == nullptr || !obj->is_online()) + return false; + auto fila_switch = obj->GetFilaSwitch(); + if (fila_switch == nullptr) + return false; + return fila_switch->IsInstalled() && fila_switch->IsReady(); +} + +void Sidebar::priv::show_fila_switch_msg(bool ready) +{ + wxString msg = ready ? _L("Filament switcher detected. All AMS filaments are now available for both extruders. " + "The slicer will auto-assign for optimal printing. ") : + _L("A filament switcher is detected but not calibrated and thus currently unavailable. " + "Please calibrate it on the printer and synchronize before use. "); + + long style = ready ? (wxICON_INFORMATION | wxOK) : (wxICON_WARNING | wxOK); + // Orca: drop the vendor "Learn more" tracking link; there is no Orca help page for the switch yet. + MessageDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe), msg, _L("Tips"), style); + dlg.CenterOnParent(); + dlg.ShowModal(); +} + +void Sidebar::priv::show_filament_switcher_dialog(bool is_ready, bool is_manual) +{ + if (is_ready) { + // Show the "switch is ready" tip only once, ever. + if (wxGetApp().app_config->get("show_fila_switch_tips") == "true") { + wxGetApp().app_config->set("show_fila_switch_tips", "false"); + show_fila_switch_msg(true); + } + } else { + // A manual sync always warns; an automatic update warns once per session. + if (is_manual || !fila_switch_warning_shown) { + fila_switch_warning_shown = true; + show_fila_switch_msg(false); + } + } +} + +void Sidebar::priv::update_extruder_separator_icon(bool show, bool ready) +{ + if (!extruder_separator_icon) + return; + static bool last_show = false; + static bool last_ready = false; + static bool first_call = true; + + if (!first_call && last_show == show && last_ready == ready) + return; + first_call = false; + last_show = show; + last_ready = ready; + + // Never overlay the icon when the connected printer is not the selected preset. + if (!wxGetApp().plater()->is_same_printer_for_connected_and_selected(false)) { + extruder_separator_icon->Hide(); + if (m_panel_printer_content) + m_panel_printer_content->Refresh(); + return; + } + + if (show && left_extruder && left_extruder->hsizer_ams && left_extruder->sizer) { + // Orca: center the icon over the seam between the two extruder cards, vertically aligned with + // the AMS row. left_extruder and the icon share m_panel_printer_content as parent, so + // left_extruder->GetPosition() and the icon position live in the same coordinate space. + wxPoint left_box_pos = left_extruder->GetPosition(); + wxPoint ams_local_pos = left_extruder->hsizer_ams->GetPosition(); + wxSize left_size = left_extruder->sizer->GetSize(); + wxSize ams_size = left_extruder->hsizer_ams->GetSize(); + wxSize icon_size = extruder_separator_icon->GetSize(); + int ams_abs_y = left_box_pos.y + ams_local_pos.y + FromDIP(4); + int center_x = left_size.GetWidth() + FromDIP(6); + int center_y = ams_abs_y + (ams_size.GetHeight() - icon_size.GetHeight()) / 2; + center_x -= icon_size.GetWidth() / 2; + center_y -= icon_size.GetHeight() / 2; + extruder_separator_icon->SetPosition(wxPoint(center_x, center_y)); + + auto normal_bitmap = ScalableBitmap(m_panel_printer_content, "fila_switch", 10); + auto error_bitmap = ScalableBitmap(m_panel_printer_content, "fila_switch_error", 10); + extruder_separator_icon->SetBitmap(ready ? normal_bitmap.bmp() : error_bitmap.bmp()); + + extruder_separator_icon->Show(); + extruder_separator_icon->Raise(); + } else { + extruder_separator_icon->Hide(); + } + + if (m_panel_printer_content) + m_panel_printer_content->Refresh(); +} + +bool Sidebar::priv::sync_extruder_list(bool &only_external_material, bool is_manual) { MachineObject *obj = wxGetApp().getDeviceManager()->get_selected_machine(); auto printer_name = plater->get_selected_printer_name_in_combox(); @@ -1378,13 +1947,35 @@ bool Sidebar::priv::sync_extruder_list(bool &only_external_material) } assert(obj->GetExtderSystem()->GetTotalExtderCount() == extruder_nums); + // Multi-nozzle: resolve the nozzle option (pops MultiNozzleSyncDialog when is_manual). No-op for every + // existing printer — support_multi_nozzle is false unless some extruder_max_nozzle_count entry is a real + // value > 1 (nil-guarded, matching the manual/ToolOrdering gates), which no shipping single-nozzle or + // dual-extruder profile sets. When the machine is multi-nozzle but no option resolves (e.g. user cancelled), + // abort the sync. + const ConfigOptionIntsNullable *extruder_max_nozzle_count = cur_preset.config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + bool support_multi_nozzle = extruder_max_nozzle_count != nullptr && + std::any_of(extruder_max_nozzle_count->values.begin(), extruder_max_nozzle_count->values.end(), + [](int val) { return val > 1 && val != ConfigOptionIntsNullable::nil_value(); }); + auto nozzle_option = get_nozzle_options(obj, extruder_nums, support_multi_nozzle, is_manual); + if (!nozzle_option && support_multi_nozzle) + return false; + std::vector<float> nozzle_diameters; nozzle_diameters.resize(extruder_nums); + std::vector<NozzleVolumeType> target_types(extruder_nums, NozzleVolumeType::nvtStandard); for (size_t index = 0; index < extruder_nums; ++index) { int extruder_id = extruder_map[index]; - nozzle_diameters[extruder_id] = obj->GetExtderSystem()->GetNozzleDiameter(index); + nozzle_diameters[extruder_id] = nozzle_option ? atof(nozzle_option->diameter.c_str()) : obj->GetExtderSystem()->GetNozzleDiameter(index); NozzleVolumeType target_type = NozzleVolumeType::nvtStandard; - auto printer_tab = dynamic_cast<TabPrinter *>(wxGetApp().get_tab(Preset::TYPE_PRINTER)); + std::optional<NozzleVolumeType> select_type; + if (nozzle_option && nozzle_option->extruder_nozzle_stats.count(index)) { + const auto &stats = nozzle_option->extruder_nozzle_stats[index]; + if (stats.size() > 1) + // The extruder holds nozzles of several flow types: select the mixed-flow mode. + select_type = NozzleVolumeType::nvtHybrid; + else + select_type = stats.begin()->first; + } if (obj->is_nozzle_flow_type_supported()) { if (obj->GetExtderSystem()->GetNozzleFlowType(index) == NozzleFlowType::NONE_FLOWTYPE) { MessageDialog dlg(this->plater, _L("There are unset nozzle types. Please set the nozzle types of all extruders before synchronizing."), @@ -1394,24 +1985,39 @@ bool Sidebar::priv::sync_extruder_list(bool &only_external_material) } // hack code, only use standard flow for 0.2 if (std::fabs(nozzle_diameters[extruder_id] - 0.2) > EPSILON) - target_type = NozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(extruder_id) - 1); + // Map device flow->volume via the table, not `flowtype - 1`. + // The arithmetic only aligns for S_FLOW/H_FLOW; U_FLOW(3)-1 would yield nvtHybrid(2), not nvtTPUHighFlow(3). + target_type = DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(extruder_id)); } - printer_tab->set_extruder_volume_type(index, target_type); + if (select_type) + target_type = *select_type; + target_types[index] = target_type; } int deputy_4 = 0, main_4 = 0, deputy_1 = 0, main_1 = 0; + const bool switch_ready = is_fila_switch_ready(); for (auto ams : obj->GetFilaSystem()->GetAmsList()) { - // Main (first) extruder at right - if (ams.second->GetExtruderId() == 0) { - if (ams.second->GetAmsType() == DevAms::N3S) // N3S - ++main_1; - else - ++main_4; - } else if (ams.second->GetExtruderId() == 1) { - if (ams.second->GetAmsType() == DevAms::N3S) // N3S - ++deputy_1; - else - ++deputy_4; + for (int extruder_id : ams.second->GetBindedExtruderSet()) { + // With the switch installed every AMS binds to both extruders; once it is ready, attribute + // each to the extruder its input track feeds so the per-extruder counts stay correct. Without + // a switch the binding set is the single extruder and the filter is skipped, matching the + // pre-switch counts. + if (switch_ready) { + auto switcher_pos = ams.second->GetSwitcherPos(); + if (!switcher_pos) + continue; + int switcher_id = obj->is_main_extruder_on_left() ? (1 - static_cast<int>(switcher_pos.value())) + : static_cast<int>(switcher_pos.value()); + if (extruder_id != switcher_id) + continue; + } + const bool is_n3s = ams.second->GetAmsType() == DevAms::N3S; + // Main (first) extruder is id 0, deputy is id 1. + if (extruder_id == 0) { + if (is_n3s) ++main_1; else ++main_4; + } else if (extruder_id == 1) { + if (is_n3s) ++deputy_1; else ++deputy_4; + } } } only_external_material = !obj->GetFilaSystem()->HasAms(); @@ -1440,6 +2046,28 @@ bool Sidebar::priv::sync_extruder_list(bool &only_external_material) is_switching_diameter = false; } + // set nozzle volume type after switching prset, so this value can override the old value stored in conf + auto printer_tab = dynamic_cast<TabPrinter *>(wxGetApp().get_tab(Preset::TYPE_PRINTER)); + for (size_t idx = 0; idx < target_types.size(); ++idx) { + printer_tab->set_extruder_volume_type(idx, target_types[idx]); + } + + if (extruder_nums > 1) { + auto fila_switch = obj->GetFilaSwitch(); + if (fila_switch->IsInstalled()) + show_filament_switcher_dialog(fila_switch->IsReady(), is_manual); + else + fila_switch_warning_shown = false; + } + + // Copy the live switch state into the project so slicing and the send dialog honor it. Both + // resolve to false unless the switch is installed and calibrated, so nothing changes without one. + auto &project_config = wxGetApp().preset_bundle->project_config; + if (auto *dynamic_filament = project_config.opt<ConfigOptionBool>("enable_filament_dynamic_map")) + dynamic_filament->value = is_fila_switch_ready(); + if (auto *has_switcher = project_config.opt<ConfigOptionBool>("has_filament_switcher")) + has_switcher->value = is_fila_switch_ready(); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " finish sync_extruder_list"; return true; } @@ -1457,6 +2085,7 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) right_extruder->sync_ams(nullptr, {}, {}); single_extruder->ShowBadge(false); single_extruder->sync_ams(nullptr, {}, {}); + update_extruder_separator_icon(false, false); //btn_sync_printer->SetBorderColor(not_synced_colour); //btn_sync_printer->SetIcon("printer_sync"); m_printer_bbl_sync->SetBitmap_("printer_sync_not"); @@ -1467,6 +2096,16 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) return; } + // Orca: replaces BBS's reset_fila_switch hook on DeviceManager::OnSelectedMachineChanged (absent + // in Orca). Selection/MQTT updates all funnel through here, so a change of the selected device id + // resets the switcher icon and the once-per-session not-ready warning for the new printer. + const std::string cur_dev_id = obj->get_dev_id(); + if (cur_dev_id != last_sync_dev_id) { + last_sync_dev_id = cur_dev_id; + update_extruder_separator_icon(false, false); + fila_switch_warning_shown = false; + } + PresetBundle *preset_bundle = wxGetApp().preset_bundle; if (!preset_bundle) { clear_all_sync_status(); @@ -1518,6 +2157,21 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) if (extruder_nums != obj->GetExtderSystem()->GetTotalExtderCount()) return; + // Filament Track Switch: only ever surfaced on multi-extruder machines. When installed, tip/warn + // and show the status icon (green ready / red not-calibrated); when absent the icon stays hidden. + // Inert on any printer without a switch: GetFilaSwitch()->IsInstalled() is false. + const bool fila_switch_flag = is_fila_switch_ready(); + if (extruder_nums > 1) { + auto fila_switch = obj->GetFilaSwitch(); + if (fila_switch->IsInstalled()) { + show_filament_switcher_dialog(fila_switch->IsReady(), false); + update_extruder_separator_icon(true, fila_switch->IsReady()); + } else { + update_extruder_separator_icon(false, false); + fila_switch_warning_shown = false; + } + } + std::vector<ExtruderInfo> extruder_infos(extruder_nums); std::vector<int> nozzle_volume_types = wxGetApp().preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values; //for (size_t i = 0; i < nozzle_volume_types.size(); ++i) { @@ -1559,16 +2213,34 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) machine_extruder_infos[extruder.GetExtId()].diameter = extruder.GetNozzleDiameter(); } for (auto &item : obj->GetFilaSystem()->GetAmsList()) { - if (item.second->GetExtruderId() >= machine_extruder_infos.size()) + int extruder_id; + // With the switch ready every AMS feeds both extruders, so attribute each to the extruder its + // input track feeds. Without a switch the binding is a single extruder + // (GetUniqueBindedExtruderId() == GetExtruderId()) and the switcher position is empty, so this + // yields the same attribution as before. + if (fila_switch_flag) { + auto switcher_pos = item.second->GetSwitcherPos(); + if (!switcher_pos) + continue; + extruder_id = obj->is_main_extruder_on_left() ? (1 - static_cast<int>(switcher_pos.value())) + : static_cast<int>(switcher_pos.value()); + } else { + const auto &uniq_extruder_id = item.second->GetUniqueBindedExtruderId(); + if (!uniq_extruder_id) + continue; + extruder_id = uniq_extruder_id.value(); + } + + if (extruder_id >= machine_extruder_infos.size()) continue; if (item.second->GetAmsType() == DevAms::N3S) { // N3S - machine_extruder_infos[item.second->GetExtruderId()].ams_1++; - machine_extruder_infos[item.second->GetExtruderId()].ams_v1.push_back(item.second); + machine_extruder_infos[extruder_id].ams_1++; + machine_extruder_infos[extruder_id].ams_v1.push_back(item.second); } else { - machine_extruder_infos[item.second->GetExtruderId()].ams_4++; - machine_extruder_infos[item.second->GetExtruderId()].ams_v4.push_back(item.second); + machine_extruder_infos[extruder_id].ams_4++; + machine_extruder_infos[extruder_id].ams_v4.push_back(item.second); } } @@ -1622,6 +2294,20 @@ void Sidebar::priv::update_sync_status(const MachineObject *obj) // btn_sync_printer->SetIcon("printer_sync"); m_printer_bbl_sync->SetBitmap_("printer_sync_not"); } + + // When the switch is ready every AMS filament is available to both extruders; refresh the + // filament combos whenever the AMS list changes so both extruders pick up the full set. + if (fila_switch_flag) { + static std::map<int, DynamicPrintConfig> last_filament_ams_list; + bool is_same_ams_list = last_filament_ams_list == wxGetApp().preset_bundle->filament_ams_list; + if (!is_same_ams_list) + last_filament_ams_list = wxGetApp().preset_bundle->filament_ams_list; + const auto print_tech = wxGetApp().preset_bundle->printers.get_edited_preset().printer_technology(); + if (print_tech == ptFFF && !is_same_ams_list) { + for (PlaterPresetComboBox *cb : combos_filament) + cb->update(); + } + } } void Sidebar::update_sync_ams_btn_enable(wxUpdateUIEvent &e) @@ -1736,10 +2422,6 @@ Sidebar::Sidebar(Plater *parent) p->m_panel_printer_title->Layout(); // 1.2 Add spliters around title bar - // add spliter 1 - //auto spliter_1 = new ::StaticLine(p->scrolled); - //spliter_1->SetBackgroundColour("#A6A9AA"); - //scrolled_sizer->Add(spliter_1, 0, wxEXPAND); // add printer title scrolled_sizer->Add(p->m_panel_printer_title, 0, wxEXPAND | wxALL, 0); @@ -1751,14 +2433,13 @@ Sidebar::Sidebar(Plater *parent) wxString title = _L("Printer") + wxString(!isShown ? "" : (" | " + p->combo_printer->GetValue())); p->m_text_printer_settings->SetLabel(title); p->m_panel_printer_content->Show(!isShown); + p->m_panel_printer_separator->Show(isShown); m_scrolled_sizer->Layout(); }); - - // add spliter 2 - auto spliter_2 = new ::StaticLine(p->scrolled); - spliter_2->SetLineColour("#CECECE"); - scrolled_sizer->Add(spliter_2, 0, wxEXPAND); - + // ORCA add bottom border for seperation wile sections folded + p->m_panel_printer_separator = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(2))); // ORCA staticline class not works without string + p->m_panel_printer_separator->SetBackgroundColour("#FFFFFF"); + scrolled_sizer->Add(p->m_panel_printer_separator, 0, wxEXPAND); /*************************** 2. add printer content ************************/ @@ -1938,9 +2619,9 @@ Sidebar::Sidebar(Plater *parent) } wxGridSizer *nozzle_dia_sizer = new wxGridSizer(3, 1, FromDIP(2), 0); - nozzle_dia_sizer->Add(p->label_nozzle_title, 0, wxALIGN_CENTER | wxTOP, FromDIP(4)); - nozzle_dia_sizer->Add(p->combo_nozzle_dia , 0, wxALIGN_CENTER | wxTOP | wxBOTTOM, FromDIP(2)); - nozzle_dia_sizer->Add(p->label_nozzle_type , 0, wxALIGN_CENTER); + nozzle_dia_sizer->Add(p->label_nozzle_title, 1, wxALIGN_CENTER | wxTOP , FromDIP(2)); + nozzle_dia_sizer->Add(p->combo_nozzle_dia , 0, wxALIGN_CENTER); + nozzle_dia_sizer->Add(p->label_nozzle_type , 1, wxALIGN_CENTER | wxBOTTOM, FromDIP(1)); p->panel_nozzle_dia->SetSizer(nozzle_dia_sizer); @@ -2074,6 +2755,30 @@ Sidebar::Sidebar(Plater *parent) p->left_extruder = new ExtruderGroup(p->m_panel_printer_content, 0, _L("Left Nozzle")); p->right_extruder = new ExtruderGroup(p->m_panel_printer_content, 1, _L("Right Nozzle")); p->single_extruder = new ExtruderGroup(p->m_panel_printer_content, -1, _L("Nozzle")); + // manuallySetNozzleCount refreshes the badge and the plater itself; it is a no-op unless the + // printer has a multi-nozzle extruder (and the edit button is only enabled then, see + // enable_nozzle_count_edit). + p->left_extruder->SetOnHoverClick([]() { GUI::manuallySetNozzleCount(0); }); + p->right_extruder->SetOnHoverClick([]() { GUI::manuallySetNozzleCount(1); }); + p->single_extruder->SetEditEnabled(false); + // Orca: keep the floating switcher icon aligned with the left extruder's AMS row when the + // extruder card is resized (the overlay is absolutely positioned, not managed by a sizer). + p->left_extruder->Bind(wxEVT_SIZE, [this](wxSizeEvent &evt) { + if (p->extruder_separator_icon && p->extruder_separator_icon->IsShown()) { + wxPoint left_box_pos = p->left_extruder->GetPosition(); + wxPoint ams_local_pos = p->left_extruder->hsizer_ams->GetPosition(); + wxSize left_size = p->left_extruder->sizer->GetSize(); + wxSize ams_size = p->left_extruder->hsizer_ams->GetSize(); + wxSize icon_size = p->extruder_separator_icon->GetSize(); + int ams_abs_y = left_box_pos.y + ams_local_pos.y + FromDIP(4); + int center_x = left_size.GetWidth() + FromDIP(6) - icon_size.GetWidth() / 2; + int center_y = ams_abs_y + (ams_size.GetHeight() - icon_size.GetHeight()) / 2 - icon_size.GetHeight() / 2; + p->extruder_separator_icon->SetPosition(wxPoint(center_x, center_y)); + if (p->m_panel_printer_content) + p->m_panel_printer_content->Refresh(); + } + evt.Skip(); + }); auto switch_diameter = [this](wxCommandEvent & evt) { auto extruder = dynamic_cast<ExtruderGroup *>(dynamic_cast<ComboBox *>(evt.GetEventObject())->GetParent()); p->is_switching_diameter = true; @@ -2099,17 +2804,20 @@ Sidebar::Sidebar(Plater *parent) p->m_panel_filament_title->SetBackgroundColor(title_bg); p->m_panel_filament_title->SetBackgroundColor2(0xF1F1F1); p->m_panel_filament_title->Bind(wxEVT_LEFT_UP, [this](wxMouseEvent &e) { - if (!p || !p->m_panel_filament_content || !m_scrolled_sizer || !p->m_bpButton_set_filament || !p->m_flushing_volume_btn || !p->m_bpButton_add_filament || !ams_btn) + if (!p || !p->m_panel_filament_content || !m_scrolled_sizer || !p->m_bpButton_set_filament || !p->m_purge_mode_btn || !p->m_flushing_volume_btn || !p->m_bpButton_add_filament || !ams_btn) return; // ORCA exclude area of del button from titlebar collapse/expand feature to fix undesired collapse when user spams del filament button // also block fold/unfold feature when user clicks to spacing between icons int exclude_pt = p->m_bpButton_set_filament->GetPosition().x; // maximum fixed item - if (p->m_flushing_volume_btn->IsShown()) exclude_pt = p->m_flushing_volume_btn->GetPosition().x; + if (p->m_purge_mode_btn->IsShown()) exclude_pt = p->m_purge_mode_btn->GetPosition().x; + else if (p->m_flushing_volume_btn->IsShown()) exclude_pt = p->m_flushing_volume_btn->GetPosition().x; else if (p->m_bpButton_add_filament->IsShown()) exclude_pt = p->m_bpButton_add_filament->GetPosition().x - FromDIP(30); // reserve spacing for delete button else if (ams_btn->IsShown()) exclude_pt = ams_btn->GetPosition().x; if (e.GetPosition().x > exclude_pt) return; - p->m_panel_filament_content->Show(!p->m_panel_filament_content->IsShown()); + bool isShown = p->m_panel_filament_content->IsShown(); + p->m_panel_filament_content->Show(!isShown); + p->m_panel_filament_separator->Show(isShown); m_scrolled_sizer->Layout(); CallAfter([this]{update_filaments_counter(true);}); // call after all UI processing done @@ -2129,16 +2837,32 @@ Sidebar::Sidebar(Plater *parent) p->m_panel_filament_title->SetSizer( bSizer39 ); p->m_panel_filament_title->Layout(); - auto spliter_1 = new ::StaticLine(p->scrolled); - spliter_1->SetLineColour("#A6A9AA"); - scrolled_sizer->Add(spliter_1, 0, wxEXPAND); scrolled_sizer->Add(p->m_panel_filament_title, 0, wxEXPAND | wxALL, 0); - auto spliter_2 = new ::StaticLine(p->scrolled); - spliter_2->SetLineColour("#CECECE"); - scrolled_sizer->Add(spliter_2, 0, wxEXPAND); + // ORCA add bottom border for seperation wile sections folded + p->m_panel_filament_separator = new wxPanel(p->scrolled, wxID_ANY, wxDefaultPosition, wxSize(-1, FromDIP(2))); // ORCA staticline class not works without string + p->m_panel_filament_separator->SetBackgroundColour("#FFFFFF"); + scrolled_sizer->Add(p->m_panel_filament_separator, 0, wxEXPAND); bSizer39->AddStretchSpacer(1); + p->m_purge_mode_btn = new Button(p->m_panel_filament_title, _L("Purge mode")); + p->m_purge_mode_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Compact); + + p->m_purge_mode_btn->Bind(wxEVT_BUTTON, [](wxCommandEvent &e) { + auto &preset_bundle = *wxGetApp().preset_bundle; + auto support_fast_purge_opt = preset_bundle.printers.get_edited_preset().config.option<ConfigOptionBool>("support_fast_purge_mode"); + bool support_fast_purge = support_fast_purge_opt ? support_fast_purge_opt->value : false; + auto dlg_type = support_fast_purge ? PurgeModeDialogType::FastMode : PurgeModeDialogType::MultiNozzle; + PurgeModeDialog dlg(static_cast<wxWindow *>(wxGetApp().mainframe), dlg_type); + if (dlg.ShowModal() == wxID_OK) { + preset_bundle.project_config.set_key_value("prime_volume_mode", new ConfigOptionEnum<PrimeVolumeMode>(dlg.get_selected_mode())); + wxGetApp().plater()->update(); + } + }); + + bSizer39->Add(p->m_purge_mode_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(4)); + bSizer39->Hide(p->m_purge_mode_btn); // hidden on launch; shown only for printers that support purge mode selection + // BBS // add wiping dialog //wiping_dialog_button->SetFont(wxGetApp().normal_font()); @@ -2707,8 +3431,12 @@ void Sidebar::update_presets(Preset::Type preset_type) auto type = extruders_def->enum_labels[extruders->values[index]]; int select = -1; for (size_t i = 0; i < nozzle_volumes_def->enum_labels.size(); ++i) { - if (boost::algorithm::contains(extruder_variants->values[index], type + " " + nozzle_volumes_def->enum_labels[i]) /*|| - extruder_max_nozzle_count->values[index] > 1 && nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]) == nvtHybrid*/) { // TODO: Orca: Support hybrid + // get_at falls back to the first entry when a profile defines no per-extruder value, + // so extruders without an explicit sub-nozzle count never offer Hybrid. A nullable-int + // nil is INT_MAX (> 1) and would otherwise falsely pass the gate, so exclude it too. + if (boost::algorithm::contains(extruder_variants->values[index], type + " " + nozzle_volumes_def->enum_labels[i]) || + extruder_max_nozzle_count->get_at(index) > 1 && extruder_max_nozzle_count->get_at(index) != ConfigOptionIntsNullable::nil_value() && + nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]) == nvtHybrid) { if (nozzle_volumes_def->enum_keys_map->at(nozzle_volumes_def->enum_values[i]) == NozzleVolumeType::nvtHighFlow &&(diameter == "0.2" || is_skip_high_flow_printer(printer_model))) continue; @@ -3008,6 +3736,7 @@ void Sidebar::msw_rescale() p->m_bpButton_del_filament->msw_rescale(); p->m_bpButton_ams_filament->msw_rescale(); p->m_bpButton_set_filament->msw_rescale(); + p->m_purge_mode_btn->Rescale(); p->m_flushing_volume_btn->Rescale(); set_flushing_volume_warning(is_flush_config_modified()); // ORCA reapply appearance @@ -3093,6 +3822,7 @@ void Sidebar::sys_color_changed() p->m_bpButton_del_filament->msw_rescale(); p->m_bpButton_ams_filament->msw_rescale(); p->m_bpButton_set_filament->msw_rescale(); + p->m_purge_mode_btn->Rescale(); p->m_flushing_volume_btn->Rescale(); set_flushing_volume_warning(is_flush_config_modified()); // ORCA reapply appearance @@ -3487,6 +4217,16 @@ bool Sidebar::sync_extruder_list() return p->sync_extruder_list(only_external_material); } +bool Sidebar::is_fila_switch_ready() +{ + return p->is_fila_switch_ready(); +} + +void Sidebar::reset_fila_switch() +{ + p->update_extruder_separator_icon(false, false); +} + bool Sidebar::need_auto_sync_extruder_list_after_connect_priner(const MachineObject *obj) { if(!obj) @@ -3746,15 +4486,13 @@ void Sidebar::sync_ams_list(bool is_from_big_sync_btn) { // badge ams filament clear_combos_filament_badge(); if (sync_result.direct_sync) { - auto& ams_list = wxGetApp().preset_bundle->filament_ams_list; - size_t tray_idx = 0; - for (auto& entry : ams_list) { - if (tray_idx >= p->combos_filament.size()) break; - auto filament_id = entry.second.opt_string("filament_id", 0u); - if (!filament_id.empty()) { - badge_combox_filament(p->combos_filament[tray_idx]); - } - tray_idx++; + // Orca: PresetBundle::sync_ams_list rebuilds combos_filament + // 1:1 from the AMS trays that produce a combo (loaded trays + placeholders; non-placeholder + // empty trays are skipped), so every resulting combo is AMS-sourced and gets a badge. The + // previous per-tray index walked the full filament_ams_list (including the skipped empties), + // so an empty slot before a loaded one dropped the badge for the trailing filaments. + for (auto &c : p->combos_filament) { + badge_combox_filament(c); } } } @@ -3854,6 +4592,37 @@ void Sidebar::show_SEMM_buttons() Layout(); } +void Sidebar::enable_purge_mode_btn(bool enable) +{ + if (!p || !p->m_purge_mode_btn) + return; + p->m_purge_mode_btn->Show(enable); + wxGetApp().CallAfter([this]() { + p->m_panel_filament_title->Layout(); + this->Layout(); + }); +} + +void Sidebar::set_extruder_nozzle_count(int extruder_id, int nozzle_count) +{ + if (!p) + return; + if (extruder_id == 0) { + p->left_extruder->SetCount(nozzle_count); + p->single_extruder->SetCount(nozzle_count); + } else if (extruder_id == 1) { + p->right_extruder->SetCount(nozzle_count); + } +} + +void Sidebar::enable_nozzle_count_edit(bool enable) +{ + if (!p) + return; + p->left_extruder->SetEditEnabled(enable); + p->right_extruder->SetEditEnabled(enable); +} + void Sidebar::update_dynamic_filament_list() { dynamic_filament_list.update(); @@ -3949,7 +4718,8 @@ bool Sidebar::is_multifilament() void Sidebar::deal_btn_sync() { m_begin_sync_printer_status = true; bool only_external_material; - auto ok = p->sync_extruder_list(only_external_material); + // Manual "sync machine" button: is_manual=true so an H2C pops the MultiNozzleSyncDialog to pick a nozzle option. + auto ok = p->sync_extruder_list(only_external_material, true); if (ok) { pop_sync_nozzle_and_ams_dialog(); } @@ -5600,10 +6370,8 @@ void Plater::priv::update(unsigned int flags) //BBS assemble view this->assemble_view->reload_scene(false, flags); - if (current_panel && is_preview_shown()) { - q->force_update_all_plate_thumbnails(); - //update_fff_scene_only_shells(true); - } + // todo: better to mark thumbnail dirty here + q->mark_plate_toolbar_image_dirty(); if (force_background_processing_restart) this->restart_background_process(update_status); @@ -5670,6 +6438,9 @@ std::map<std::string, std::string> Plater::get_bed_texture_maps() if (pm->bottom_texture_rect.size() > 0) { maps["bottom_texture_rect"] = pm->bottom_texture_rect; } + if (pm->bottom_texture_rect_longer.size() > 0) { + maps["bottom_texture_rect_longer"] = pm->bottom_texture_rect_longer; + } if (pm->middle_texture_rect.size() > 0) { maps["middle_texture_rect"] = pm->middle_texture_rect; } @@ -6615,6 +7386,16 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ filament_map->values.resize(filament_count, 1); } + ConfigOptionInts* filament_nozzle_map = proj_cfg.opt<ConfigOptionInts>("filament_nozzle_map", true); + if (filament_nozzle_map->size() != filament_count) { + filament_nozzle_map->values.resize(filament_count, 0); + } + + ConfigOptionInts* filament_volume_map = proj_cfg.opt<ConfigOptionInts>("filament_volume_map", true); + if (filament_volume_map->size() != filament_count) { + filament_volume_map->values.resize(filament_count, static_cast<int>(NozzleVolumeType::nvtStandard)); + } + // Sync filament multi colour ConfigOptionStrings* filament_multi_color = proj_cfg.opt<ConfigOptionStrings>("filament_multi_colour", true); if (filament_multi_color->size() != filament_count) { @@ -6639,9 +7420,24 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ } } } + + // Filament Track Switch state is derived live from the connected + // printer; a loaded project must not carry a stale installed/active + // flag, so clear both and let device sync re-derive them. + if (auto* has_switcher = proj_cfg.opt<ConfigOptionBool>("has_filament_switcher")) + has_switcher->value = false; + if (auto* dynamic_map = proj_cfg.opt<ConfigOptionBool>("enable_filament_dynamic_map")) + dynamic_map->value = false; } // Update filament combobox after loading config wxGetApp().plater()->sidebar().update_presets(Preset::TYPE_FILAMENT); + // The loaded project supplies nozzle_volume_type; refresh the sidebar + // nozzle-count badges against it. + if (auto *nozzle_volumes = wxGetApp().preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")) { + const int extruder_count = wxGetApp().preset_bundle->get_printer_extruder_count(); + for (int extruder_id = 0; extruder_id < extruder_count && extruder_id < (int) nozzle_volumes->values.size(); ++extruder_id) + updateNozzleCountDisplay(wxGetApp().preset_bundle, extruder_id, NozzleVolumeType(nozzle_volumes->values[extruder_id])); + } } } if (!silence) wxGetApp().app_config->update_config_dir(path.parent_path().string()); @@ -6870,7 +7666,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ // BBS BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << ":" << __LINE__ << " " << boost::format("import 3mf IMPORT_LOAD_MODEL_OBJECTS \n"); - wxString msg = wxString::Format("Loading file: %s", from_path(real_filename)); + wxString msg = wxString::Format(_L("Loading file: %s"), from_path(real_filename)); model_idx++; dlg_cont = dlg.Update(progress_percent, msg); if (!dlg_cont) { @@ -7130,6 +7926,7 @@ std::vector<size_t> Plater::priv::load_files(const std::vector<fs::path>& input_ } } q->schedule_background_process(true); + q->mark_plate_toolbar_image_dirty(); return obj_idxs; } @@ -7509,6 +8306,8 @@ void Plater::priv::object_list_changed() main_frame->update_slice_print_status(MainFrame::eEventObjectUpdate, can_slice); wxGetApp().params_panel()->notify_object_config_changed(); + + q->mark_plate_toolbar_image_dirty(); } void Plater::priv::select_curr_plate_all() @@ -7570,7 +8369,7 @@ bool Plater::priv::delete_object_from_model(size_t obj_idx, bool refresh_immedia return false; } - std::string snapshot_label = "Delete Object"; + std::string snapshot_label = _u8L("Delete Object"); if (!obj->name.empty()) snapshot_label += ": " + obj->name; Plater::TakeSnapshot snapshot(q, snapshot_label); @@ -7594,7 +8393,7 @@ bool Plater::priv::delete_object_from_model(size_t obj_idx, bool refresh_immedia void Plater::priv::delete_all_objects_from_model() { - Plater::TakeSnapshot snapshot(q, "Delete All Objects"); + Plater::TakeSnapshot snapshot(q, _u8L("Delete All Objects")); if (view3D->is_layers_editing_enabled()) view3D->enable_layers_editing(false); @@ -7625,7 +8424,7 @@ void Plater::priv::delete_all_objects_from_model() void Plater::priv::reset(bool apply_presets_change) { - Plater::TakeSnapshot snapshot(q, "Reset Project", UndoRedo::SnapshotType::ProjectSeparator); + Plater::TakeSnapshot snapshot(q, _u8L("Reset Project"), UndoRedo::SnapshotType::ProjectSeparator); clear_warnings(); @@ -7774,7 +8573,7 @@ void Plater::priv::split_object(int obj_idx, bool auto_drop /* = true */) // NotificationManager::NotificationLevel::PrintInfoNotificationLevel, // _u8L("All non-solid parts (modifiers) were deleted")); - Plater::TakeSnapshot snapshot(q, "Split to Objects"); + Plater::TakeSnapshot snapshot(q, _u8L("Split to Objects")); auto is_atleast_one_floating = [new_objects]() { for (ModelObject* new_object : new_objects) { @@ -8090,7 +8889,11 @@ unsigned int Plater::priv::update_background_process(bool force_validation, bool if (preset_bundle->get_printer_extruder_count() > 1) { PartPlate* cur_plate = background_process.get_current_plate(); std::vector<int> f_maps = cur_plate->get_real_filament_maps(preset_bundle->project_config); - invalidated = background_process.apply(this->model, preset_bundle->full_config(false, f_maps)); + std::vector<int> f_volume_maps = cur_plate->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps); + } + invalidated = background_process.apply(this->model, preset_bundle->full_config(false, f_maps, f_volume_maps)); background_process.fff_print()->set_extruder_filament_info(get_extruder_filament_info()); } else @@ -8408,6 +9211,8 @@ void Plater::priv::update_fff_scene() view3D->reload_scene(true); //BBS: add assemble view related logic assemble_view->reload_scene(true); + + q->mark_plate_toolbar_image_dirty(); } //BBS: add print project related logic @@ -8584,7 +9389,7 @@ void Plater::priv::replace_with_stl() return; } - if (!replace_volume_with_stl(object_idx, volume_idx, out_path, "Replace with 3D file")) + if (!replace_volume_with_stl(object_idx, volume_idx, out_path, _u8L("Replace with 3D file"))) return; // update 3D scene @@ -8701,7 +9506,7 @@ void Plater::priv::replace_all_with_stl() BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " replacing volume : " << input_path << " with " << new_path; - if (!replace_volume_with_stl(object_idx, volume_idx, new_path, "Replace with 3D file")) { + if (!replace_volume_with_stl(object_idx, volume_idx, new_path, _u8L("Replace with 3D file"))) { status += boost::str(boost::format(_L("✖ Skipped %1%: failed to replace.\n").ToStdString()) % volume_name); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << " cannot replace volume : failed to replace with " << new_path; continue; @@ -8761,7 +9566,7 @@ void Plater::priv::reload_from_disk() return (v1.first == v2.first) && (v1.second == v2.second); }), selected_volumes.end()); #else - Plater::TakeSnapshot snapshot(q, "Reload from disk"); + Plater::TakeSnapshot snapshot(q, _u8L("Reload from disk")); const Selection& selection = get_selection(); @@ -8910,7 +9715,7 @@ void Plater::priv::reload_from_disk() replace_paths.erase(std::unique(replace_paths.begin(), replace_paths.end()), replace_paths.end()); #if ENABLE_RELOAD_FROM_DISK_REWORK - Plater::TakeSnapshot snapshot(q, "Reload from disk"); + Plater::TakeSnapshot snapshot(q, _u8L("Reload from disk")); #endif // ENABLE_RELOAD_FROM_DISK_REWORK std::vector<wxString> fail_list; @@ -9203,7 +10008,7 @@ void Plater::priv::reload_all_from_disk() if (model.objects.empty()) return; - Plater::TakeSnapshot snapshot(q, "Reload all"); + Plater::TakeSnapshot snapshot(q, _u8L("Reload all")); Plater::SuppressSnapshots suppress(q); Selection& selection = get_selection(); @@ -9316,9 +10121,6 @@ void Plater::priv::set_current_panel(wxPanel* panel, bool no_slice) preview->get_canvas3d()->enable_select_plate_toolbar(true); } } - else { - preview->get_canvas3d()->enable_select_plate_toolbar(false); - } if (current_panel == panel) { @@ -9716,11 +10518,14 @@ void Plater::priv::on_select_preset(wxCommandEvent &evt) } } } + } else { + // BBS + // wxWindowUpdateLocker noUpdates1(sidebar->print_panel()); + wxWindowUpdateLocker noUpdates2(sidebar->filament_panel()); + wxGetApp().get_tab(preset_type)->select_preset(preset_name); + // update plater with new config + q->on_config_change(wxGetApp().preset_bundle->full_config()); } - //BBS - //wxWindowUpdateLocker noUpdates1(sidebar->print_panel()); - wxWindowUpdateLocker noUpdates2(sidebar->filament_panel()); - wxGetApp().get_tab(preset_type)->select_preset(preset_name); } // ORCA: Always refresh the selected filament combo so its color swatch (clr_picker) @@ -10174,6 +10979,7 @@ void Plater::priv::on_process_completed(SlicingProcessCompletedEvent &evt) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(":finished, reload print soon"); m_is_slicing = false; this->preview->reload_print(false); + q->mark_plate_toolbar_image_dirty(); /* BBS if in publishing progress */ if (m_is_publishing) { if (m_publish_dlg && !m_publish_dlg->was_cancelled()) { @@ -11141,8 +11947,9 @@ bool Plater::priv::check_ams_status_impl(bool is_slice_all) auto nozzle_volumes_values = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values; assert(obj->GetExtderSystem()->GetTotalExtderCount() == 2 && nozzle_volumes_values.size() == 2); if (obj->GetExtderSystem()->GetTotalExtderCount() == 2 && nozzle_volumes_values.size() == 2) { - NozzleVolumeType right_nozzle_type = NozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(0) - 1); - NozzleVolumeType left_nozzle_type = NozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(1) - 1); + // Map device flow->volume via the table, not `flowtype - 1` (which mis-maps U_FLOW to nvtHybrid). + NozzleVolumeType right_nozzle_type = DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(0)); + NozzleVolumeType left_nozzle_type = DevNozzle::ToNozzleVolumeType(obj->GetExtderSystem()->GetNozzleFlowType(1)); NozzleVolumeType preset_left_type = NozzleVolumeType(nozzle_volumes_values[0]); NozzleVolumeType preset_right_type = NozzleVolumeType(nozzle_volumes_values[1]); is_same_as_printer = (left_nozzle_type == preset_left_type && right_nozzle_type == preset_right_type); @@ -12241,8 +13048,9 @@ void Plater::load_project(wxString const& filename2, BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << boost::format(": current loading other project, return directly"); return; } - else - m_loading_project = true; + + m_loading_project = true; + ScopeGuard loading_project_sc([this]() { m_loading_project = false; }); // Make sure state restored on any early return m_only_gcode = false; m_exported_file = false; @@ -12336,7 +13144,6 @@ void Plater::load_project(wxString const& filename2, sidebar().set_flushing_volume_warning(has_modify); BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << __LINE__ << " load project done"; - m_loading_project = false; } // BBS: save logic @@ -13142,6 +13949,8 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f)); _obj->config.set_key_value("infill_direction", new ConfigOptionFloat(45)); _obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(135)); + _obj->config.set_key_value("center_of_surface_pattern", new ConfigOptionEnum<CenterOfSurfacePattern>(CenterOfSurfacePattern::Each_Surface)); + _obj->config.set_key_value("separated_infills", new ConfigOptionBool(false)); _obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true)); _obj->config.set_key_value("ironing_type", new ConfigOptionEnum<IroningType>(IroningType::NoIroning)); _obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloatsNullable(internal_solid_speeds)); @@ -13149,7 +13958,13 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i _obj->config.set_key_value("seam_slope_type", new ConfigOptionEnum<SeamScarfType>(SeamScarfType::None)); _obj->config.set_key_value("gap_fill_target", new ConfigOptionEnum<GapFillTarget>(GapFillTarget::gftNowhere)); print_config->set_key_value("max_volumetric_extrusion_rate_slope", new ConfigOptionFloat(0)); + // ORCA: request the calibration's special toolpath order (chords first, center spiral + // last and inside-out) so opposing directions collide into the tactile lip the test + // reads. The special order only applies while the fill order is Default, so reset the + // profile's fill order on the calibration objects; changing the setting on the object + // afterwards deliberately overrides the special order. _obj->config.set_key_value("calib_flowrate_topinfill_special_order", new ConfigOptionBool(true)); + _obj->config.set_key_value("top_surface_fill_order", new ConfigOptionEnum<SurfaceFillOrder>(SurfaceFillOrder::Default)); // extract flowrate from name, filename format: flowrate_xxx std::string obj_name = _obj->name; @@ -13886,6 +14701,7 @@ void Plater::invalid_all_plate_thumbnails() plate->thumbnail_data.reset(); plate->no_light_thumbnail_data.reset(); } + mark_plate_toolbar_image_dirty(); } void Plater::force_update_all_plate_thumbnails() @@ -13896,7 +14712,6 @@ void Plater::force_update_all_plate_thumbnails() invalid_all_plate_thumbnails(); update_all_plate_thumbnails(true); } - get_preview_canvas3D()->update_plate_thumbnails(); } // BBS: backup @@ -13952,17 +14767,9 @@ bool Plater::preview_zip_archive(const boost::filesystem::path& archive_path) if (mz_zip_reader_file_stat(&archive, i, &stat)) { if (size != stat.m_uncomp_size) // size must fit continue; - wxString wname = boost::nowide::widen(stat.m_filename); - std::string name = into_u8(wname); + std::string name = Slic3r::decode_archive_entry_path(&archive, stat); fs::path archive_path(name); - std::string extra(1024, 0); - size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size()); - if (extra_size > 0) { - archive_path = fs::path(extra.substr(0, extra_size)); - name = archive_path.string(); - } - if (archive_path.empty()) continue; if (path != archive_path) @@ -15779,7 +16586,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy std::vector<Preset*> project_presets = preset_bundle.get_current_project_embedded_presets(); StoreParams store_params; - store_params.path = path_u8.c_str(); + store_params.path = path_u8; store_params.model = &p->model; store_params.plate_data_list = plate_data_list; store_params.export_plate_idx = export_plate_idx; @@ -17071,12 +17878,24 @@ void Plater::set_global_filament_map(const std::vector<int>& filament_map) project_config.option<ConfigOptionInts>("filament_map")->values = filament_map; } +void Plater::set_global_filament_volume_map(const std::vector<int>& filament_volume_map) +{ + auto& project_config = wxGetApp().preset_bundle->project_config; + project_config.option<ConfigOptionInts>("filament_volume_map")->values = filament_volume_map; +} + std::vector<int> Plater::get_global_filament_map() const { auto& project_config = wxGetApp().preset_bundle->project_config; return project_config.option<ConfigOptionInts>("filament_map")->values; } +std::vector<int> Plater::get_global_filament_volume_map() const +{ + auto& project_config = wxGetApp().preset_bundle->project_config; + return project_config.option<ConfigOptionInts>("filament_volume_map")->values; +} + FilamentMapMode Plater::get_global_filament_map_mode() const { @@ -17381,6 +18200,9 @@ void Plater::suppress_background_process(const bool stop_background_process) this->p->suppressed_backround_processing_update = true; } +// Expose the slicing process to the device GUI. +BackgroundSlicingProcess& Plater::background_process() { return p->background_process; } + void Plater::center_selection() { p->center_selection(); } void Plater::drop_selection() { p->drop_selection(); } void Plater::mirror(Axis axis) { p->mirror(axis); } @@ -17626,7 +18448,11 @@ void Plater::apply_background_progress() Print::ApplyStatus invalidated; if (preset_bundle->get_printer_extruder_count() > 1) { std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config); - invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps)); + std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps); + } + invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps)); } else invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false)); @@ -17671,7 +18497,11 @@ int Plater::select_plate(int plate_index, bool need_slice) //always apply the current plate's print if (preset_bundle->get_printer_extruder_count() > 1) { std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config); - invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps)); + std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps); + } + invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps)); } else invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false)); @@ -18009,13 +18839,17 @@ void Plater::open_filament_map_setting_dialog(wxCommandEvent &evt) auto plate_filament_maps = curr_plate->get_real_filament_maps(project_config); auto plate_filament_map_mode = curr_plate->get_filament_map_mode(); + auto plate_filament_volume_maps = curr_plate->get_real_filament_volume_maps(project_config); if (plate_filament_maps.size() != filament_colors.size()) // refine it later, save filament map to app config plate_filament_maps.resize(filament_colors.size(), 1); + if (plate_filament_volume_maps.size() != filament_colors.size()) + plate_filament_volume_maps.resize(filament_colors.size(), 0); FilamentMapDialog filament_dlg(this, filament_colors, filament_types, plate_filament_maps, + plate_filament_volume_maps, curr_plate->get_extruders(true), plate_filament_map_mode, this->get_machine_sync_status(), @@ -18029,16 +18863,21 @@ void Plater::open_filament_map_setting_dialog(wxCommandEvent &evt) FilamentMapMode old_map_mode = curr_plate->get_filament_map_mode(); FilamentMapMode new_map_mode = filament_dlg.get_mode(); + std::vector<int> new_filament_volume_maps = filament_dlg.get_filament_volume_maps(); + std::vector<int> old_filament_volume_maps = curr_plate->get_real_filament_volume_maps(project_config); + if (new_map_mode != old_map_mode) { curr_plate->set_filament_map_mode(new_map_mode); } if (new_map_mode == fmmManual){ curr_plate->set_filament_maps(new_filament_maps); + curr_plate->set_filament_volume_maps(new_filament_volume_maps); } bool need_invalidate = (old_map_mode != new_map_mode || - old_filament_maps != new_filament_maps); + old_filament_maps != new_filament_maps || + old_filament_volume_maps != new_filament_volume_maps); if (need_invalidate) { if (need_slice) { @@ -18092,7 +18931,11 @@ int Plater::select_plate_by_hover_id(int hover_id, bool right_click, bool isModi //always apply the current plate's print if (preset_bundle->get_printer_extruder_count() > 1) { std::vector<int> f_maps = part_plate->get_real_filament_maps(preset_bundle->project_config); - invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps)); + std::vector<int> f_volume_maps = part_plate->get_filament_volume_maps(); + if (f_volume_maps.empty()) { + f_volume_maps = preset_bundle->get_default_nozzle_volume_types_for_filaments(f_maps); + } + invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false, f_maps, f_volume_maps)); } else invalidated = p->background_process.apply(this->model(), preset_bundle->full_config(false)); @@ -18500,6 +19343,30 @@ bool Plater::get_machine_sync_status() return p->get_machine_sync_status(); } +void Plater::update_filament_volume_map(int extruder_id, int volume_type) +{ + // Hybrid is a per-extruder mix, not a per-filament volume; reset the affected filaments + // to Standard so the manual grouping dialog starts from a concrete assignment. + int selected_volume_type = volume_type == static_cast<int>(NozzleVolumeType::nvtHybrid) ? static_cast<int>(NozzleVolumeType::nvtStandard) : volume_type; + auto& partplate_list = get_partplate_list(); + for (int idx = 0; idx < partplate_list.get_plate_count(); ++idx) { + auto plate = partplate_list.get_plate(idx); + if (!plate) continue; + auto filament_map = plate->get_filament_maps(); + auto filament_volume_map = plate->get_filament_volume_maps(); + if (filament_map.empty() || filament_volume_map.empty()) continue; + if (filament_volume_map.size() < filament_map.size()) { + filament_volume_map.resize(filament_map.size(), static_cast<int>(NozzleVolumeType::nvtStandard)); + } + for (size_t i = 0; i < filament_map.size(); ++i) { + if (filament_map[i] == extruder_id + 1) { + filament_volume_map[i] = selected_volume_type; + } + } + plate->set_filament_volume_maps(filament_volume_map); + } +} + #if ENABLE_ENVIRONMENT_MAP void Plater::init_environment_texture() { diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 474a6512a7..87386eec19 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -50,6 +50,7 @@ class SLAPrint; //BBS: add partplatelist and SlicingStatusEvent class PartPlateList; class SlicingStatusEvent; +class BackgroundSlicingProcess; enum SLAPrintObjectStep : unsigned int; enum class ConversionType : int; class DevAms; @@ -195,6 +196,8 @@ public: std::map<int, DynamicPrintConfig> build_filament_ams_list(MachineObject* obj); void sync_ams_list(bool is_from_big_sync_btn = false); bool sync_extruder_list(); + bool is_fila_switch_ready(); + void reset_fila_switch(); bool need_auto_sync_extruder_list_after_connect_priner(const MachineObject* obj); void update_sync_status(const MachineObject* obj); int get_sidebar_pos_right_x(); @@ -205,6 +208,10 @@ public: // Orca static bool should_show_SEMM_buttons(); void show_SEMM_buttons(); + void enable_purge_mode_btn(bool enable); + // Sidebar nozzle-count badge on the extruder cards (multi-nozzle printers only). + void set_extruder_nozzle_count(int extruder_id, int nozzle_count); + void enable_nozzle_count_edit(bool enable); void update_dynamic_filament_list(); PlaterPresetComboBox * printer_combox(); @@ -519,6 +526,9 @@ public: void schedule_background_process(bool schedule = true); bool is_background_process_update_scheduled() const; void suppress_background_process(const bool stop_background_process) ; + // Expose the slicing process so the device GUI can read the current + // GCodeProcessorResult (e.g. the nozzle grouping for print-dispatch mapping). + BackgroundSlicingProcess& background_process(); /* -1: send current gcode if not specified * -2: send all gcode to target machine */ int send_gcode(int plate_idx = -1, Export3mfProgressFn proFn = nullptr); @@ -576,7 +586,9 @@ public: void set_global_filament_map_mode(FilamentMapMode mode); void set_global_filament_map(const std::vector<int>& filament_map); + void set_global_filament_volume_map(const std::vector<int>& filament_volume_map); std::vector<int> get_global_filament_map() const; + std::vector<int> get_global_filament_volume_map() const; FilamentMapMode get_global_filament_map_mode() const; void update_menus(); @@ -745,6 +757,11 @@ public: void update_machine_sync_status(); + // Rewrite every plate's per-filament volume choice for the filaments grouped onto this + // extruder after its Flow type changed (Hybrid resets them to Standard so the user + // re-assigns concrete volumes in the grouping dialog). + void update_filament_volume_map(int extruder_id, int volume_type); + #if ENABLE_ENVIRONMENT_MAP void init_environment_texture(); unsigned int get_environment_texture_id() const; @@ -926,6 +943,10 @@ public: bool is_loading_project() const { return m_loading_project; } + void mark_plate_toolbar_image_dirty(); + bool is_plate_toolbar_image_dirty() const; + void clear_plate_toolbar_image_dirty(); + private: struct priv; std::unique_ptr<priv> p; @@ -946,6 +967,7 @@ private: std::string m_preview_only_filename; int m_valid_plates_count { 0 }; int m_check_status = 0; // 0 not check, 1 check success, 2 check failed + bool m_b_plate_toolbar_image_dirty{ true }; void suppress_snapshots(); void allow_snapshots(); diff --git a/src/slic3r/GUI/PrePrintChecker.cpp b/src/slic3r/GUI/PrePrintChecker.cpp index d66ee53d56..866c9bd15d 100644 --- a/src/slic3r/GUI/PrePrintChecker.cpp +++ b/src/slic3r/GUI/PrePrintChecker.cpp @@ -36,6 +36,9 @@ std::string PrePrintChecker::get_print_status_info(PrintDialogStatus status) case PrintStatusNotSupportedPrintAll: return "PrintStatusNotSupportedPrintAll"; case PrintStatusBlankPlate: return "PrintStatusBlankPlate"; case PrintStatusUnsupportedPrinter: return "PrintStatusUnsupportedPrinter"; + case PrintStatusRackNozzleMappingWaiting: return "PrintStatusRackNozzleMappingWaiting"; + case PrintStatusRackNozzleMappingError: return "PrintStatusRackNozzleMappingError"; + case PrintStatusFilaSwitcherError: return "PrintStatusFilaSwitcherError"; case PrintStatusColorQuantityExceed: return "PrintStatusColorQuantityExceed"; // Handle filament errors case PrintStatusAmsOnSettingup: return "PrintStatusAmsOnSettingup"; @@ -47,13 +50,21 @@ std::string PrePrintChecker::get_print_status_info(PrintDialogStatus status) case PrintStatusTimelapseNoSdcard: return "PrintStatusTimelapseNoSdcard"; case PrintStatusTimelapseWarning: return "PrintStatusTimelapseWarning"; case PrintStatusMixAmsAndVtSlotWarning: return "PrintStatusMixAmsAndVtSlotWarning"; + case PrintStatusRackNozzleMappingWarning: return "PrintStatusRackNozzleMappingWarning"; + case PrintStatusFilaSwitcherSlicingNotMatch: return "PrintStatusFilaSwitcherSlicingNotMatch"; case PrintStatusWarningKvalueNotUsed: return "PrintStatusWarningKvalueNotUsed"; case PrintStatusHasFilamentInBlackListWarning: return "PrintStatusHasFilamentInBlackListWarning"; case PrintStatusFilamentWarningHighChamberTemp: return "PrintStatusFilamentWarningHighChamberTemp"; case PrintStatusFilamentWarningHighChamberTempCloseDoor: return "PrintStatusFilamentWarningHighChamberTempCloseDoor"; case PrintStatusFilamentWarningHighChamberTempSoft: return "PrintStatusFilamentWarningHighChamberTempSoft"; case PrintStatusFilamentWarningUnknownHighChamberTempSoft: return "PrintStatusFilamentWarningUnknownHighChamberTempSoft"; + case PrintStatusNozzleNoMatchedHotends: return "PrintStatusNozzleNoMatchedHotends"; + case PrintStatusNozzleRackMaximumInstalled: return "PrintStatusNozzleRackMaximumInstalled"; + case PrintStatusRackReading: return "PrintStatusRackReading"; + case PrintStatusRackNozzleNumUnmeetWarning: return "PrintStatusRackNozzleNumUnmeetWarning"; + case PrintStatusHasUnreliableNozzleWarning: return "PrintStatusHasUnreliableNozzleWarning"; case PrintStatusWarningExtFilamentNotMatch: return "PrintStatusWarningExtFilamentNotMatch"; + case PrintStatusFilamentWarningNozzleHRC: return "PrintStatusFilamentWarningNozzleHRC"; case PrintStatusReadingFinished: return "PrintStatusReadingFinished"; case PrintStatusSendingCanceled: return "PrintStatusSendingCanceled"; case PrintStatusAmsMappingSuccess: return "PrintStatusAmsMappingSuccess"; diff --git a/src/slic3r/GUI/PrePrintChecker.hpp b/src/slic3r/GUI/PrePrintChecker.hpp index 8e4d4ed3f4..dbceb07bfe 100644 --- a/src/slic3r/GUI/PrePrintChecker.hpp +++ b/src/slic3r/GUI/PrePrintChecker.hpp @@ -55,6 +55,8 @@ enum PrintDialogStatus : unsigned int { PrintStatusNozzleDataInvalid, PrintStatusNozzleDiameterMismatch, PrintStatusNozzleTypeMismatch, + PrintStatusNozzleNoMatchedHotends, + PrintStatusNozzleRackMaximumInstalled, PrintStatusRefreshingMachineList, PrintStatusSending, PrintStatusLanModeNoSdcard, @@ -65,6 +67,10 @@ enum PrintDialogStatus : unsigned int { PrintStatusNotSupportedPrintAll, PrintStatusBlankPlate, PrintStatusUnsupportedPrinter, + PrintStatusRackNozzleMappingWaiting, + PrintStatusRackNozzleMappingError, + PrintStatusRackReading, + PrintStatusFilaSwitcherError, PrintStatusPrinterErrorEnd, // Errors for filament, Block Print @@ -89,6 +95,10 @@ enum PrintDialogStatus : unsigned int { PrintStatusTimelapseWarning, PrintStatusMixAmsAndVtSlotWarning, PrintStatusToolHeadCoolingFanWarning, + PrintStatusRackNozzleMappingWarning, + PrintStatusFilaSwitcherSlicingNotMatch, + PrintStatusRackNozzleNumUnmeetWarning, + PrintStatusHasUnreliableNozzleWarning, PrintStatusPrinterWarningEnd, // Warnings for filament @@ -100,6 +110,7 @@ enum PrintDialogStatus : unsigned int { PrintStatusFilamentWarningHighChamberTempSoft, PrintStatusFilamentWarningUnknownHighChamberTempSoft, PrintStatusWarningExtFilamentNotMatch, + PrintStatusFilamentWarningNozzleHRC, PrintStatusFilamentWarningEnd, PrintStatusWarningEnd,//->end error<- diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index af7522c33d..e1501e9c4d 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -797,7 +797,7 @@ wxBoxSizer *PreferencesDialog::create_item_decimal_input(wxString title, wxStrin input->SetToolTip(tooltip); input->GetTextCtrl()->SetValidator(validator); - m_sizer->Add(input, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(5)); + m_sizer->Add(input, 0, wxALIGN_CENTER_VERTICAL); auto apply_value = [this, param, input, min, max, decimals]() { auto value = input->GetTextCtrl()->GetValue(); @@ -1797,6 +1797,17 @@ void PreferencesDialog::create_items() g_sizer = f_sizers.back(); g_sizer->AddGrowableCol(0, 1); + //// GRAPHICS > General + g_sizer->Add(create_item_title(_L("General")), 1, wxEXPAND); + + auto smooth_normals = create_item_checkbox( + _L("Smooth normals"), + _L("Applies smooth normals to the model.\n\nRequires manual scene reload to take effect " + "(right-click on 3D view → \"Reload All\")."), + SETTING_OPENGL_PHONG_SMOOTH_NORMALS + ); + g_sizer->Add(smooth_normals); + //// GRAPHICS > Realistic view g_sizer->Add(create_item_title(_L("Realistic View")), 1, wxEXPAND); @@ -1816,20 +1827,11 @@ void PreferencesDialog::create_items() auto item_realistic_shadows = create_item_checkbox( _L("Shadows"), - _L("Renders cast shadows on the plate in realistic view."), + _L("Renders cast shadows on the plate, other objects, and each object onto itself in realistic view."), SETTING_OPENGL_PHONG_BASIC_PLATE_SHADOWS ); g_sizer->Add(item_realistic_shadows); - - auto item_realistic_smooth_normals = create_item_checkbox( - _L("Smooth normals"), - _L("Applies smooth normals to the realistic view.\n\nRequires manual scene reload to take effect " - "(right-click on 3D view → \"Reload All\")."), - SETTING_OPENGL_PHONG_SMOOTH_NORMALS - ); - g_sizer->Add(item_realistic_smooth_normals); - //// GRAPHICS > Anti-aliasing g_sizer->Add(create_item_title(_L("Anti-aliasing")), 1, wxEXPAND); diff --git a/src/slic3r/GUI/PresetComboBoxes.cpp b/src/slic3r/GUI/PresetComboBoxes.cpp index 6475ae1c88..8fdca030c6 100644 --- a/src/slic3r/GUI/PresetComboBoxes.cpp +++ b/src/slic3r/GUI/PresetComboBoxes.cpp @@ -3,6 +3,8 @@ #include <cstddef> #include <vector> #include <string> +#include <set> +#include <utility> #include <algorithm> #include <boost/algorithm/string.hpp> @@ -510,8 +512,14 @@ bool PresetComboBox::add_ams_filaments(std::string selected, bool alias_name) bool selected_in_ams = false; bool is_bbl_vendor_preset = m_preset_bundle->is_bbl_vendor(); if (is_bbl_vendor_preset && !m_preset_bundle->filament_ams_list.empty()) { + // When a filament track switch is installed and calibrated, every AMS filament is reachable + // from both extruders, so present one deduplicated group instead of the Left/Right split. + bool fila_switch_ready = wxGetApp().sidebar().is_fila_switch_ready(); bool dual_extruder = (m_preset_bundle->filament_ams_list.begin()->first & 0x10000) == 0; - set_label_marker(Append(dual_extruder ? _L("Left filaments") : _L("AMS filament"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); + if (fila_switch_ready) + set_label_marker(Append(_L("AMS filaments"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); + else + set_label_marker(Append(dual_extruder ? _L("Left filaments") : _L("AMS filament"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); m_first_ams_filament = GetCount(); auto &filaments = m_collection->get_presets(); @@ -523,8 +531,12 @@ bool PresetComboBox::add_ams_filaments(std::string selected, bool alias_name) icon_width = 32; } + // Deduplicate by (tray_name, filament_id) so a filament shared by both extruders is + // listed once when the switch is ready. Uses Orca's tray naming/lookup, not BBS's. + std::set<std::pair<std::string, std::string>> added_filaments; + for (auto &entry : m_preset_bundle->filament_ams_list) { - if (dual_extruder && (entry.first & 0x10000)) { + if (!fila_switch_ready && dual_extruder && (entry.first & 0x10000)) { dual_extruder = false; set_label_marker(Append(_L("Right filaments"), wxNullBitmap, DD_ITEM_STYLE_SPLIT_ITEM)); } @@ -535,6 +547,13 @@ bool PresetComboBox::add_ams_filaments(std::string selected, bool alias_name) BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << boost::format(": %1% 's filament_id is empty.") % name; continue; } + if (fila_switch_ready) { + // skip the external spool and collapse duplicates shared across both extruders + if (name == "Ext") + continue; + if (!added_filaments.insert(std::make_pair(name, filament_id)).second) + continue; + } auto iter = std::find_if(filaments.begin(), filaments.end(), [&filament_id, this](auto &f) { return f.is_compatible && m_collection->get_preset_base(f) == &f && f.filament_id == filament_id; }); if (iter == filaments.end()) { @@ -1080,7 +1099,7 @@ void PlaterPresetComboBox::show_edit_menu() #ifdef __linux__ // To edit extruder color from the sidebar if (m_type == Preset::TYPE_FILAMENT) { - append_menu_item(menu, wxID_ANY, _devL("Change extruder color"), "", + append_menu_item(menu, wxID_ANY, _L("Change extruder color"), "", [this](wxCommandEvent&) { this->change_extruder_color(); }, "blank_14", menu, []() { return true; }, wxGetApp().plater()); wxGetApp().plater()->PopupMenu(menu); return; @@ -1307,10 +1326,19 @@ void PlaterPresetComboBox::update() bool selected_in_ams = false; if (m_type == Preset::TYPE_FILAMENT) { set_replace_text("Bambu", "BambuStudioBlack"); - selected_in_ams = add_ams_filaments(into_u8(selected_user_preset.empty() ? selected_system_preset : selected_user_preset), true); + // Orca: selected_system/user_preset hold the FULL preset name because Orca keys the maps above by + // full name to avoid alias collisions (BBS keys by alias). add_ams_filaments() compares against + // get_preset_name() which returns the alias, so resolve the selection back to its alias here. + // Without this, e.g. "Bambu PLA Basic @BBL H2C" never equals the AMS tray alias "Bambu PLA Basic", + // so the FROM_AMS flag is never set and update_sync_status() wipes the AMS sync check mark on the + // filament cards for connected Bambu printers. + wxString selected_full = selected_user_preset.empty() ? selected_system_preset : selected_user_preset; + auto alias_it = preset_aliases.find(selected_full); + wxString selected_alias = alias_it != preset_aliases.end() ? from_u8(alias_it->second) : selected_full; + selected_in_ams = add_ams_filaments(into_u8(selected_alias), true); } - std::vector<std::string> filament_orders = {"Bambu PLA Basic", "Bambu PLA Matte", "Bambu PETG HF", "Bambu ABS", "Bambu PLA Silk", "Bambu PLA-CF", + std::vector<wxString> filament_orders = {"Bambu PLA Basic", "Bambu PLA Matte", "Bambu PETG HF", "Bambu ABS", "Bambu PLA Silk", "Bambu PLA-CF", "Bambu PLA Galaxy", "Bambu PLA Metal", "Bambu PLA Marble", "Bambu PETG-CF", "Bambu PETG Translucent", "Bambu ABS-GF"}; std::vector<std::string> first_vendors = {"", "Bambu", "Generic"}; // Empty vendor for non-system presets std::vector<std::string> first_types = {"PLA", "PETG", "ABS", "TPU"}; @@ -1600,6 +1628,7 @@ TabPresetComboBox::TabPresetComboBox(wxWindow* parent, Preset::Type preset_type) // BBS: new layout PresetComboBox(parent, preset_type, wxSize(20 * wxGetApp().em_unit(), 30 * wxGetApp().em_unit() / 10)) { + GetDropDown().SetUseContentWidth(true,true); } void TabPresetComboBox::OnSelect(wxCommandEvent &evt) diff --git a/src/slic3r/GUI/PrintOptionsDialog.cpp b/src/slic3r/GUI/PrintOptionsDialog.cpp index 562b4cbc24..39f115ed89 100644 --- a/src/slic3r/GUI/PrintOptionsDialog.cpp +++ b/src/slic3r/GUI/PrintOptionsDialog.cpp @@ -1426,6 +1426,7 @@ wxString PrinterPartsDialog::GetString(NozzleFlowType nozzle_flow_type) const { switch (nozzle_flow_type) { case Slic3r::S_FLOW: return _L("Standard"); case Slic3r::H_FLOW: return _L("High flow"); + case Slic3r::U_FLOW: return _L("TPU High flow"); default: break; } diff --git a/src/slic3r/GUI/PrinterCloudAuthDialog.cpp b/src/slic3r/GUI/PrinterCloudAuthDialog.cpp index 41e5cebced..e44a712acc 100644 --- a/src/slic3r/GUI/PrinterCloudAuthDialog.cpp +++ b/src/slic3r/GUI/PrinterCloudAuthDialog.cpp @@ -95,7 +95,7 @@ void PrinterCloudAuthDialog::OnScriptMessage(wxWebViewEvent& evt) } Close(); } catch (std::exception& e) { - wxMessageBox(e.what(), "parse json failed", wxICON_WARNING); + wxMessageBox(e.what(), _L("parse json failed"), wxICON_WARNING); Close(); } } diff --git a/src/slic3r/GUI/PurgeModeDialog.cpp b/src/slic3r/GUI/PurgeModeDialog.cpp new file mode 100644 index 0000000000..b3191a04e5 --- /dev/null +++ b/src/slic3r/GUI/PurgeModeDialog.cpp @@ -0,0 +1,269 @@ +#include "PurgeModeDialog.hpp" + +#include <wx/sizer.h> +#include <wx/stattext.h> +#include <wx/statbmp.h> +#include <wx/dcbuffer.h> +#include <wx/graphics.h> + +#include "I18N.hpp" +#include "GUI_App.hpp" +#include "wxExtensions.hpp" +#include "Widgets/Button.hpp" +#include "libslic3r/Utils.hpp" + +namespace Slic3r { namespace GUI { + +static const wxColour BgNormalColor = wxColour("#FFFFFF"); +static const wxColour BgSelectColor = wxColour("#EBF9F0"); + +static const wxColour BorderNormalColor = wxColour("#CECECE"); +static const wxColour BorderSelectedColor = wxColour("#00AE42"); + +static const wxColour TextNormalBlackColor = wxColour("#262E30"); +static const wxColour TextNormalGreyColor = wxColour("#6B6B6B"); + +PurgeModeDialog::PurgeModeDialog(wxWindow *parent, PurgeModeDialogType dialog_type) + : DPIDialog(parent, wxID_ANY, _L("Purge Mode Settings"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE), m_dialog_type(dialog_type) +{ + SetBackgroundColour(*wxWHITE); + SetMinSize(wxSize(FromDIP(520), FromDIP(320))); + SetMaxSize(wxSize(FromDIP(520), FromDIP(320))); + std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); + SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); + + auto main_sizer = new wxBoxSizer(wxVERTICAL); + + auto options_panel = new wxPanel(this); + auto options_sizer = new wxBoxSizer(wxVERTICAL); + auto panels_sizer = new wxBoxSizer(wxHORIZONTAL); + + auto &preset_bundle = *wxGetApp().preset_bundle; + auto current_mode = preset_bundle.project_config.option<ConfigOptionEnum<PrimeVolumeMode>>("prime_volume_mode"); + PrimeVolumeMode mode = current_mode ? current_mode->value : pvmDefault; + m_selected_mode = mode; + + bool is_fast_mode = (m_dialog_type == PurgeModeDialogType::FastMode); + + m_standard_panel = new PurgeModeBtnPanel(options_panel, _L("Standard"), _L("Perform full purging with speed and temperature transition for the best print quality."), + "shield"); + m_standard_panel->SetMinSize(wxSize(FromDIP(200), FromDIP(150))); + m_standard_panel->Select(mode == pvmDefault); + m_standard_panel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &) { select_option(pvmDefault); }); + panels_sizer->Add(m_standard_panel, 1, wxEXPAND | wxRIGHT, FromDIP(12)); + if (is_fast_mode) { + m_saving_panel = new PurgeModeBtnPanel(options_panel, _L("Fast"), + _L("Uses optimized purge temperature, multiplier and stronger extrusion for faster purging. May cause slight color mixing in some extreme cases."), "leaf"); + m_saving_panel->SetMinSize(wxSize(FromDIP(200), FromDIP(150))); + m_saving_panel->Select(mode == pvmFast); + m_saving_panel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &) { select_option(pvmFast); }); + } else { + m_saving_panel = new PurgeModeBtnPanel(options_panel, _L("Prime Saving"), + _L("Reduces prime waste and prints faster. May cause slight color mixing or small surface defects."), "leaf"); + m_saving_panel->SetMinSize(wxSize(FromDIP(200), FromDIP(150))); + m_saving_panel->Select(mode == pvmSaving); + m_saving_panel->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &) { select_option(pvmSaving); }); + } + + panels_sizer->Add(m_saving_panel, 1, wxEXPAND | wxLEFT, FromDIP(12)); + + options_sizer->Add(panels_sizer, 0, wxEXPAND | wxALL, FromDIP(20)); + + options_panel->SetSizer(options_sizer); + main_sizer->Add(options_panel, 1, wxEXPAND); + + auto btn_sizer = new wxBoxSizer(wxHORIZONTAL); + btn_sizer->AddStretchSpacer(); + + auto ok_btn = new Button(this, _L("Confirm")); + ok_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Compact); + ok_btn->SetId(wxID_OK); + + auto cancel_btn = new Button(this, _L("Cancel")); + cancel_btn->SetStyle(ButtonStyle::Regular, ButtonType::Compact); + cancel_btn->SetId(wxID_CANCEL); + + btn_sizer->Add(ok_btn, 0, wxRIGHT, FromDIP(12)); + btn_sizer->Add(cancel_btn, 0); + + main_sizer->Add(btn_sizer, 0, wxEXPAND | wxALL, FromDIP(20)); + + SetSizer(main_sizer); + Fit(); + CenterOnParent(); + + wxGetApp().UpdateDlgDarkUI(this); +} + +void PurgeModeDialog::select_option(PrimeVolumeMode mode) +{ + m_selected_mode = mode; + update_panel_selection(); +} + +void PurgeModeDialog::update_panel_selection() +{ + if (m_selected_mode == pvmDefault) { + m_standard_panel->Select(true); + m_saving_panel->Select(false); + } else { + m_standard_panel->Select(false); + m_saving_panel->Select(true); + } +} + +void PurgeModeDialog::on_dpi_changed(const wxRect &suggested_rect) +{ + const int &em = em_unit(); + + msw_buttons_rescale(this, em, {wxID_OK, wxID_CANCEL}); + + const wxSize &size = wxSize(70 * em, 32 * em); + SetMinSize(size); + + Fit(); + Refresh(); +} + +PurgeModeBtnPanel::PurgeModeBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon_path) : wxPanel(parent) +{ + SetBackgroundColour(*wxWHITE); + SetBackgroundStyle(wxBG_STYLE_PAINT); + + const int horizontal_margin = FromDIP(12); + + auto sizer = new wxBoxSizer(wxVERTICAL); + + icon = create_scaled_bitmap(icon_path, nullptr, 20); + m_btn = new wxStaticBitmap(this, wxID_ANY, icon, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + + check_icon = create_scaled_bitmap("completed_2", nullptr, 20); + m_check_btn = new wxStaticBitmap(this, wxID_ANY, check_icon, wxDefaultPosition, wxDefaultSize, wxNO_BORDER); + m_check_btn->Hide(); + + auto icon_sizer = new wxBoxSizer(wxHORIZONTAL); + icon_sizer->Add(m_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, horizontal_margin); + icon_sizer->AddStretchSpacer(); + icon_sizer->Add(m_check_btn, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, horizontal_margin); + + m_label = new wxStaticText(this, wxID_ANY, label); + m_label->SetFont(Label::Head_14); + m_label->SetForegroundColour(TextNormalBlackColor); + + auto label_sizer = new wxBoxSizer(wxHORIZONTAL); + label_sizer->Add(m_label, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, horizontal_margin); + + auto detail_sizer = new wxBoxSizer(wxHORIZONTAL); + m_detail = new Label(this, detail); + m_detail->SetFont(Label::Body_12); + m_detail->SetForegroundColour(TextNormalGreyColor); + m_detail->Wrap(FromDIP(200)); + detail_sizer->Add(m_detail, 0, wxALIGN_CENTER_VERTICAL | wxLEFT | wxRIGHT, horizontal_margin); + + sizer->AddSpacer(FromDIP(15)); + sizer->Add(icon_sizer, 0, wxEXPAND); + sizer->AddSpacer(FromDIP(10)); + sizer->Add(label_sizer, 0, wxEXPAND); + sizer->AddSpacer(FromDIP(6)); + sizer->Add(detail_sizer, 0, wxEXPAND); + sizer->AddSpacer(FromDIP(10)); + + SetSizer(sizer); + Layout(); + Fit(); + + wxGetApp().UpdateDarkUIWin(this); + + // Clicks on child widgets must select the whole card, so re-dispatch them on the panel. + auto forward_click_to_parent = [this](wxMouseEvent &) { + wxCommandEvent click_event(wxEVT_LEFT_DOWN, GetId()); + click_event.SetEventObject(this); + this->ProcessEvent(click_event); + }; + + m_btn->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent); + m_label->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent); + m_detail->Bind(wxEVT_LEFT_DOWN, forward_click_to_parent); + + Bind(wxEVT_PAINT, &PurgeModeBtnPanel::OnPaint, this); + Bind(wxEVT_ENTER_WINDOW, &PurgeModeBtnPanel::OnEnterWindow, this); + Bind(wxEVT_LEAVE_WINDOW, &PurgeModeBtnPanel::OnLeaveWindow, this); +} + +void PurgeModeBtnPanel::OnPaint(wxPaintEvent &event) +{ + wxAutoBufferedPaintDC dc(this); + wxGraphicsContext *gc = wxGraphicsContext::Create(dc); + + if (gc) { + dc.Clear(); + wxRect rect = GetClientRect(); + gc->SetBrush(wxTransparentColour); + gc->DrawRoundedRectangle(0, 0, rect.width, rect.height, 0); + wxColour bg_color = m_selected ? BgSelectColor : BgNormalColor; + + wxColour border_color = m_hover || m_selected ? BorderSelectedColor : BorderNormalColor; + + bg_color = StateColor::darkModeColorFor(bg_color); + border_color = StateColor::darkModeColorFor(border_color); + gc->SetBrush(wxBrush(bg_color)); + gc->SetPen(wxPen(border_color, 1)); + gc->DrawRoundedRectangle(1, 1, rect.width - 2, rect.height - 2, 8); + delete gc; + } +} + +void PurgeModeBtnPanel::UpdateStatus() +{ + if (m_selected) { + m_btn->SetBackgroundColour(BgSelectColor); + m_label->SetBackgroundColour(BgSelectColor); + m_detail->SetBackgroundColour(BgSelectColor); + if (m_check_btn) { + m_check_btn->SetBackgroundColour(BgSelectColor); + m_check_btn->Show(); + } + } else { + m_btn->SetBackgroundColour(BgNormalColor); + m_label->SetBackgroundColour(BgNormalColor); + m_detail->SetBackgroundColour(BgNormalColor); + if (m_check_btn) { + m_check_btn->SetBackgroundColour(BgNormalColor); + m_check_btn->Hide(); + } + } + Layout(); + Refresh(); + wxGetApp().UpdateDarkUIWin(this); +} + +void PurgeModeBtnPanel::OnEnterWindow(wxMouseEvent &event) +{ + if (!m_hover) { + m_hover = true; + UpdateStatus(); + Refresh(); + event.Skip(); + } +} + +void PurgeModeBtnPanel::OnLeaveWindow(wxMouseEvent &event) +{ + if (m_hover) { + wxPoint pos = this->ScreenToClient(wxGetMousePosition()); + if (this->GetClientRect().Contains(pos)) return; + m_hover = false; + UpdateStatus(); + Refresh(); + event.Skip(); + } +} + +void PurgeModeBtnPanel::Select(bool selected) +{ + m_selected = selected; + UpdateStatus(); + Refresh(); +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/PurgeModeDialog.hpp b/src/slic3r/GUI/PurgeModeDialog.hpp new file mode 100644 index 0000000000..e5880e6ab1 --- /dev/null +++ b/src/slic3r/GUI/PurgeModeDialog.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include <wx/dialog.h> +#include <wx/panel.h> + +#include "GUI_Utils.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "Widgets/Label.hpp" + +class wxStaticText; +class wxStaticBitmap; + +namespace Slic3r { + +namespace GUI { + +class PurgeModeBtnPanel : public wxPanel +{ +public: + PurgeModeBtnPanel(wxWindow *parent, const wxString &label, const wxString &detail, const std::string &icon_path); + void Select(bool selected); + +protected: + void OnPaint(wxPaintEvent &event); + +private: + void OnEnterWindow(wxMouseEvent &event); + void OnLeaveWindow(wxMouseEvent &event); + + void UpdateStatus(); + + wxBitmap icon; + wxBitmap check_icon; + + wxStaticBitmap *m_btn; + wxStaticBitmap *m_check_btn; + wxStaticText *m_label; + Label *m_detail; + bool m_hover{false}; + bool m_selected{false}; +}; + +enum class PurgeModeDialogType { + MultiNozzle, + FastMode +}; + +class PurgeModeDialog : public DPIDialog +{ +public: + PurgeModeDialog(wxWindow *parent, PurgeModeDialogType dialog_type = PurgeModeDialogType::MultiNozzle); + + PrimeVolumeMode get_selected_mode() const { return m_selected_mode; } + +protected: + void on_dpi_changed(const wxRect &suggested_rect) override; + +private: + void select_option(PrimeVolumeMode mode); + void update_panel_selection(); + + PurgeModeBtnPanel *m_standard_panel; + PurgeModeBtnPanel *m_saving_panel; + PrimeVolumeMode m_selected_mode; + PurgeModeDialogType m_dialog_type; +}; + +} // namespace GUI +} // namespace Slic3r diff --git a/src/slic3r/GUI/ReleaseNote.cpp b/src/slic3r/GUI/ReleaseNote.cpp index 56720ba635..7ff9637ee0 100644 --- a/src/slic3r/GUI/ReleaseNote.cpp +++ b/src/slic3r/GUI/ReleaseNote.cpp @@ -1524,7 +1524,7 @@ InputIpAddressDialog::InputIpAddressDialog(wxWindow *parent) m_tip4->SetMaxSize(wxSize(FromDIP(355), -1)); // ORCA standardized HyperLink - m_trouble_shoot = new HyperLink(this, "How to trouble shooting"); + m_trouble_shoot = new HyperLink(this, _L("How to trouble shooting")); m_img_help = new wxStaticBitmap(this, wxID_ANY, create_scaled_bitmap("input_access_code_x1_en", this, 198), wxDefaultPosition, wxSize(FromDIP(355), -1), 0); diff --git a/src/slic3r/GUI/SelectMachine.cpp b/src/slic3r/GUI/SelectMachine.cpp index 09314d3b49..f7d7b6b6fe 100644 --- a/src/slic3r/GUI/SelectMachine.cpp +++ b/src/slic3r/GUI/SelectMachine.cpp @@ -20,12 +20,16 @@ #include "DeviceCore/DevConfig.h" #include "DeviceCore/DevNozzleSystem.h" +#include "DeviceCore/DevNozzleRack.h" #include "DeviceCore/DevExtensionTool.h" #include "DeviceCore/DevExtruderSystem.h" #include "DeviceCore/DevFilaBlackList.h" #include "DeviceCore/DevFilaSystem.h" +#include "DeviceCore/DevFilaSwitch.h" #include "DeviceCore/DevManager.h" #include "DeviceCore/DevMapping.h" +#include "DeviceCore/DevUtilBackend.h" +#include "DeviceCore/DevMappingNozzle.h" #include "DeviceCore/DevStorage.h" #include <wx/progdlg.h> @@ -34,6 +38,7 @@ #include <wx/mstream.h> #include <miniz.h> #include <algorithm> +#include <unordered_map> #include "Plater.hpp" #include "Notebook.hpp" #include "BitmapCache.hpp" @@ -62,12 +67,22 @@ std::string get_nozzle_volume_type_cloud_string(NozzleVolumeType nozzle_volume_t else if (nozzle_volume_type == NozzleVolumeType::nvtHighFlow) { return "high_flow"; } + else if (nozzle_volume_type == NozzleVolumeType::nvtTPUHighFlow) { + return "tpu_high_flow"; + } + else if (nozzle_volume_type == NozzleVolumeType::nvtHybrid) { + // to be supported + return "hybrid_flow"; + } else { assert(false); return ""; } } +// Throttle so the rack print-dispatch nozzle-mapping request isn't re-sent on every status poll. +static int s_nozzle_mapping_last_request_time = 0; + std::vector<wxString> SelectMachineDialog::MACHINE_BED_TYPE_STRING; std::vector<string> SelectMachineDialog::MachineBedTypeString; void SelectMachineDialog::init_machine_bed_types() @@ -138,7 +153,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) /*mode switch*/ /*auto m_sizer_mode_switch = new wxBoxSizer(wxHORIZONTAL); - m_mode_print = new SendModeSwitchButton(scroll_area, _L("Print"), true); + m_mode_print = new SendModeSwitchButton(scroll_area, _CTX("Print", "Verb"), true); m_mode_send = new SendModeSwitchButton(scroll_area,_L("Save to printer"), false); m_sizer_mode_switch->Add(m_mode_print, 0, wxALIGN_CENTER, 0); m_sizer_mode_switch->Add(0, 0, 0, wxLEFT, FromDIP(8)); @@ -506,6 +521,14 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) //m_change_filament_times_sizer->Add(m_img_change_filament_times, 0, wxTOP, FromDIP(2)); m_change_filament_times_sizer->Add(m_txt_change_filament_times, 0, wxTOP, 0); + m_warn_when_drying_sizer = new wxBoxSizer(wxHORIZONTAL); + m_txt_warn_when_drying = new Label(m_scroll_area, wxEmptyString); + m_txt_warn_when_drying->SetFont(::Label::Body_13); + m_txt_warn_when_drying->SetForegroundColour(wxColour("#F09A17")); + m_txt_warn_when_drying->SetBackgroundColour(*wxWHITE); + m_txt_warn_when_drying->SetLabel(_L("To ensure print quality, the drying temperature will be lowered during printing.")); + m_warn_when_drying_sizer->Add(m_txt_warn_when_drying, 0, wxTOP, FromDIP(2)); + /*Advanced Options*/ wxBoxSizer* sizer_split_options = new wxBoxSizer(wxHORIZONTAL); auto m_split_options_line = new wxPanel(m_scroll_area, wxID_ANY); @@ -558,7 +581,11 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) m_checkbox_list["flow_cali"] = option_flow_dynamics_cali; m_checkbox_list["nozzle_offset_cali"] = option_nozzle_offset_cali_cali; for (auto print_opt : m_checkbox_list_order) { - print_opt->Bind(EVT_SWITCH_PRINT_OPTION, [this](auto &e) { save_option_vals(); }); + print_opt->Bind(EVT_SWITCH_PRINT_OPTION, [this, print_opt](auto &e) { + save_option_vals(); + // Flow calibration feeds the printer-side rack nozzle mapping; re-request it on change. + if (print_opt == m_checkbox_list["flow_cali"]) on_flow_cali_option_changed(); + }); } option_auto_bed_level->Hide(); @@ -654,7 +681,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) sizer_error_code->Add(m_st_txt_error_code, 0, wxALL, 0); - auto st_title_error_desc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Error desc")); + auto st_title_error_desc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, _L("Error desc")); auto st_title_error_desc_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY,": "); m_st_txt_error_desc = new Label(m_sw_print_failed_info, wxEmptyString); st_title_error_desc->SetForegroundColour(0x909090); @@ -671,7 +698,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) sizer_error_desc->Add(st_title_error_desc_doc, 0, wxALL, 0); sizer_error_desc->Add(m_st_txt_error_desc, 0, wxALL, 0); - auto st_title_extra_info = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Extra info")); + auto st_title_extra_info = new wxStaticText(m_sw_print_failed_info, wxID_ANY, _L("Extra info")); auto st_title_extra_info_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": "); m_st_txt_extra_info = new Label(m_sw_print_failed_info, wxEmptyString); st_title_extra_info->SetForegroundColour(0x909090); @@ -716,6 +743,8 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater) m_scroll_sizer->Add(m_change_filament_times_sizer, 0,wxLEFT|wxRIGHT, FromDIP(15)); // m_scroll_sizer->Add(m_link_edit_nozzle, 0, wxLEFT|wxRIGHT, FromDIP(15)); m_scroll_sizer->Add(suggestion_sizer, 0, wxLEFT|wxRIGHT|wxEXPAND, FromDIP(15)); + m_scroll_sizer->Add(0, 0, 0, wxTOP, FromDIP(10)); + m_scroll_sizer->Add(m_warn_when_drying_sizer, 0, wxLEFT|wxRIGHT, FromDIP(15)); m_scroll_sizer->Add(sizer_split_options, 1, wxEXPAND|wxLEFT|wxRIGHT, FromDIP(15)); m_scroll_sizer->Add(0, 0, 0, wxTOP, FromDIP(10)); m_scroll_sizer->Add(m_options_other, 0, wxEXPAND|wxLEFT|wxRIGHT, FromDIP(15)); @@ -932,13 +961,30 @@ void SelectMachineDialog::finish_mode() void SelectMachineDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &result) { + // A rack / filament-switcher printer grows its filament cards to show the mapped-nozzle row. + // Reflow the grid so the taller cards aren't clipped; no-op for printers that never show it. + auto relayout_nozzle_cards = [this]() { + DeviceManager* dev = wxGetApp().getDeviceManager(); + MachineObject* obj_ = dev ? dev->get_selected_machine() : nullptr; + if (!obj_) return; + DevNozzleSystem* ns = obj_->GetNozzleSystem(); + if (!obj_->GetFilaSwitch()->IsInstalled() && !(ns && ns->GetNozzleRack()->IsSupported())) return; + if (m_sizer_ams_mapping_left) { m_sizer_ams_mapping_left->Layout(); m_filament_panel_left_sizer->Layout(); m_filament_left_panel->Layout(); } + if (m_sizer_ams_mapping_right) { m_sizer_ams_mapping_right->Layout(); m_filament_panel_right_sizer->Layout(); m_filament_right_panel->Layout(); } + if (m_sizer_ams_mapping) { m_sizer_ams_mapping->Layout(); m_filament_panel_sizer->Layout(); m_filament_panel->Layout(); } + if (m_scroll_area) { m_scroll_area->Layout(); } + Layout(); + }; + if (result.empty()) { BOOST_LOG_TRIVIAL(info) << "ams_mapping result is empty"; for (auto it = m_materialList.begin(); it != m_materialList.end(); it++) { wxString ams_id = "Ext";// wxColour ams_col = wxColour(0xCE, 0xCE, 0xCE); it->second->item->set_ams_info(ams_col, ams_id); + it->second->item->set_nozzle_info(get_mapped_nozzle_str(it->first)); } + relayout_nozzle_cards(); return; } @@ -975,11 +1021,13 @@ void SelectMachineDialog::sync_ams_mapping_result(std::vector<FilamentInfo> &res cols.push_back(DevAmsTray::decode_color(col)); } m->set_ams_info(ams_col, ams_id,f->ctype, cols); + m->set_nozzle_info(get_mapped_nozzle_str(id)); break; } iter++; } } + relayout_nozzle_cards(); auto tab_index = (MainFrame::TabPosition) dynamic_cast<Notebook *>(wxGetApp().tab_panel())->GetSelection(); if (tab_index == MainFrame::TabPosition::tp3DEditor || tab_index == MainFrame::TabPosition::tpPreview) { updata_thumbnail_data_after_connected_printer(); @@ -1356,78 +1404,6 @@ void SelectMachineDialog::auto_supply_with_ext(std::vector<DevAmsTray> slots) { } } -bool SelectMachineDialog::is_nozzle_type_match(DevExtderSystem data, wxString& error_message) const { - if (data.GetTotalExtderCount() <= 1 || !wxGetApp().preset_bundle) - return false; - - const auto& project_config = wxGetApp().preset_bundle->project_config; - //check nozzle used - auto used_filaments = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_used_filaments(); // 1 based - auto filament_maps = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_real_filament_maps(project_config); // 1 based - std::map<int, std::string> used_extruders_flow; - std::vector<int> used_extruders; // 0 based - for (auto f : used_filaments) { - int filament_extruder = filament_maps[f - 1] - 1; - if (std::find(used_extruders.begin(), used_extruders.end(), filament_extruder) == used_extruders.end()) used_extruders.emplace_back(filament_extruder); - } - - std::sort(used_extruders.begin(), used_extruders.end()); - - auto nozzle_volume_type_opt = dynamic_cast<const ConfigOptionEnumsGeneric *>(wxGetApp().preset_bundle->project_config.option("nozzle_volume_type")); - for (auto i = 0; i < used_extruders.size(); i++) { - if (nozzle_volume_type_opt) { - NozzleVolumeType nozzle_volume_type = (NozzleVolumeType) (nozzle_volume_type_opt->get_at(used_extruders[i])); - if (nozzle_volume_type == NozzleVolumeType::nvtStandard) { used_extruders_flow[used_extruders[i]] = "Standard";} - else {used_extruders_flow[used_extruders[i]] = "High Flow";} - } - } - - vector<int> map_extruders = {1, 0}; - - - // The default two extruders are left, right, but the order of the extruders on the machine is right, left. - std::vector<std::string> flow_type_of_machine; - for (const auto& it : data.GetExtruders()) - { - if (it.GetNozzleFlowType() == NozzleFlowType::H_FLOW) - { - flow_type_of_machine.push_back(L("High Flow")); - } - else if (it.GetNozzleFlowType() == NozzleFlowType::S_FLOW) - { - flow_type_of_machine.push_back(L("Standard")); - } - } - - //Only when all preset nozzle types and machine nozzle types are exactly the same, return true. - for (std::map<int, std::string>::iterator it = used_extruders_flow.begin(); it!= used_extruders_flow.end(); it++) { - int target_machine_nozzle_id = map_extruders[it->first]; - - if (target_machine_nozzle_id < flow_type_of_machine.size()) { - if (flow_type_of_machine[target_machine_nozzle_id] != used_extruders_flow[it->first]) { - - wxString pos; - if (target_machine_nozzle_id == DEPUTY_EXTRUDER_ID) - { - pos = _L("left nozzle"); - } - else if(target_machine_nozzle_id == MAIN_EXTRUDER_ID) - { - pos = _L("right nozzle"); - } - - error_message = wxString::Format(_L("The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). " - "Please make sure the nozzle installed matches with settings in printer, " - "then set the corresponding printer preset while slicing."), pos, - _L(flow_type_of_machine[target_machine_nozzle_id]), - _L(used_extruders_flow[it->first])); - return false; - } - } - } - return true; -} - int SelectMachineDialog::convert_filament_map_nozzle_id_to_task_nozzle_id(int nozzle_id) const { if (nozzle_id == (int)FilamentMapNozzleId::NOZZLE_LEFT) { @@ -1443,6 +1419,372 @@ int SelectMachineDialog::convert_filament_map_nozzle_id_to_task_nozzle_id(int no } } +// Physical nozzle(s) a mapped filament prints on. key: nozzle pos id, value: nozzle. +// (fila_id is the filament index, i.e. FilamentInfo::id.) Non-rack printers resolve from the +// filament->extruder map; a rack printer (H2C) resolves from the print-dispatch mapping the printer +// returned. Empty when no mapping is available yet — the per-nozzle blacklist check then skips it. +std::map<int, DevNozzle> SelectMachineDialog::get_mapped_nozzles(int fila_id) const +{ + std::map<int, DevNozzle> nozzle_map; + + DeviceManager* dev = wxGetApp().getDeviceManager(); + if (!dev) { return nozzle_map; } + MachineObject* obj_ = dev->get_selected_machine(); + if (!obj_) { return nozzle_map; } + + int total_ext_count = 0; + if (m_print_type == FROM_NORMAL) { + const auto& full_config = wxGetApp().preset_bundle->full_config(); + const auto opt = full_config.option<ConfigOptionFloats>("nozzle_diameter"); + total_ext_count = opt ? opt->values.size() : 0; + } else { + const auto opt = m_required_data_config.option<ConfigOptionFloats>("nozzle_diameter"); + total_ext_count = opt ? opt->values.size() : 0; + } + + if (total_ext_count != obj_->GetExtderSystem()->GetTotalExtderCount()) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ": total_ext_count not match"; + return nozzle_map; + } + + DevNozzleSystem* nozzle_system = obj_->GetNozzleSystem(); + if (!nozzle_system) { return nozzle_map; } + + if (!nozzle_system->GetNozzleRack()->IsSupported()) { + if (total_ext_count == 1) { + nozzle_map[MAIN_EXTRUDER_ID] = nozzle_system->GetNozzleByPosId(MAIN_EXTRUDER_ID); + } else if (total_ext_count == 2) { + if (fila_id >= 0 && (size_t)fila_id < m_filaments_map.size()) { + if (m_filaments_map[fila_id] == 1) { + nozzle_map[DEPUTY_EXTRUDER_ID] = nozzle_system->GetNozzleByPosId(DEPUTY_EXTRUDER_ID); + } else if (m_filaments_map[fila_id] == 2) { + nozzle_map[MAIN_EXTRUDER_ID] = nozzle_system->GetNozzleByPosId(MAIN_EXTRUDER_ID); + } + } + } + } else if (m_print_type == FROM_NORMAL) { + // Rack printer (H2C): resolve the physical rack nozzle(s) the print-dispatch mapping assigned + // to this filament. Empty until the printer returns the auto-mapping result. + for (int nozzle_pos : obj_->get_nozzle_mapping_result()->GetMappedNozzlePosVecByFilaId(fila_id)) + nozzle_map[nozzle_pos] = nozzle_system->GetNozzleByPosId(nozzle_pos); + } + + return nozzle_map; +} + +wxString SelectMachineDialog::get_mapped_nozzle_str(int fila_id) const +{ + if (m_print_type != FROM_NORMAL) + return wxEmptyString; // no slicing data when printing from sdcard + + DeviceManager* dev = wxGetApp().getDeviceManager(); + if (!dev) { return wxEmptyString; } + MachineObject* obj_ = dev->get_selected_machine(); + if (!obj_) { return wxEmptyString; } + + DevNozzleSystem* nozzle_system = obj_->GetNozzleSystem(); + const bool rack_supported = nozzle_system && nozzle_system->GetNozzleRack()->IsSupported(); + const bool fila_switch_installed = obj_->GetFilaSwitch()->IsInstalled(); + + // A dynamic nozzle map routes filaments through the filament switcher; without one it can't map. + if (use_dynamic_nozzle_map() && !fila_switch_installed) + return "?"; + + if (fila_switch_installed || rack_supported) { + if (rack_supported) { + return obj_->get_nozzle_mapping_result()->GetMappedNozzlePosStrByFilaId(fila_id); + } else { + const auto& nozzle_map = get_mapped_nozzles(fila_id); + if (nozzle_map.count(MAIN_EXTRUDER_ID) != 0 && nozzle_map.count(DEPUTY_EXTRUDER_ID) != 0) + return "L R"; + else if (nozzle_map.count(MAIN_EXTRUDER_ID) != 0) + return "R"; + else if (nozzle_map.count(DEPUTY_EXTRUDER_ID) != 0) + return "L"; + } + return "?"; + } + + return wxEmptyString; +} + +bool SelectMachineDialog::use_dynamic_nozzle_map() const +{ + if (m_print_type == FROM_NORMAL) { + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(m_plater); + if (nozzle_group_res && nozzle_group_res->is_support_dynamic_nozzle_map()) + return true; + } else if (m_print_type == FROM_SDCARD_VIEW) { + if (m_required_data_plate_data_list.size() > (size_t) m_print_plate_idx) { + auto dynamic_nozzle_map = m_required_data_plate_data_list[m_print_plate_idx]->config.option<ConfigOptionBool>("enable_filament_dynamic_map"); + if (dynamic_nozzle_map) + return dynamic_nozzle_map->value; + } + auto dynamic_nozzle_map = m_required_data_config.option<ConfigOptionBool>("enable_filament_dynamic_map"); + if (dynamic_nozzle_map) + return dynamic_nozzle_map->value; + } + return false; +} + +bool SelectMachineDialog::slicing_with_fila_switch() const +{ + if (use_dynamic_nozzle_map()) + return true; + + if (m_print_type == FROM_NORMAL) { + auto has_filament_switcher = wxGetApp().preset_bundle->project_config.option<ConfigOptionBool>("has_filament_switcher"); + if (has_filament_switcher) + return has_filament_switcher->value; + } else if (m_print_type == FROM_SDCARD_VIEW) { + if (m_required_data_plate_data_list.size() > (size_t) m_print_plate_idx) { + auto has_filament_switcher = m_required_data_plate_data_list[m_print_plate_idx]->config.option<ConfigOptionBool>("has_filament_switcher"); + if (has_filament_switcher) + return has_filament_switcher->value; + } + auto has_filament_switcher = m_required_data_config.option<ConfigOptionBool>("has_filament_switcher"); + if (has_filament_switcher) + return has_filament_switcher->value; + } + return false; +} + +bool SelectMachineDialog::CheckErrorDynamicSwitchNozzle(MachineObject* obj_) +{ + if (!obj_) + return false; + + // Advisory only (does not block Send): the file was sliced for a switch state that doesn't + // match the installed hardware, so grouping/flush may be suboptimal. Only on firmware that + // reports it can check this. + if (obj_->is_support_check_track_switch_match_slice_printer && slicing_with_fila_switch() != obj_->GetFilaSwitch()->IsInstalled()) { + show_status(PrintDialogStatus::PrintStatusFilaSwitcherSlicingNotMatch, + {_L("The Filament Track Switch installed on the printer does not match the slicing file. Please re-slice to avoid print quality issues.")}); + } + + // The blocking checks below only matter for dynamic nozzle mapping, which requires a switch. + if (!use_dynamic_nozzle_map()) + return true; + + if (!obj_->GetFilaSwitch()->IsInstalled()) { + show_status(PrintDialogStatus::PrintStatusFilaSwitcherError, {_L("This print requires a Filament Track Switch. Please install it first.")}); + return false; + } + + if (!obj_->GetFilaSwitch()->IsReady()) { + show_status(PrintDialogStatus::PrintStatusFilaSwitcherError, {_L("The Filament Track Switch has not been setup. Please setup it first.")}); + return false; + } + + return true; +} + +void SelectMachineDialog::clear_nozzle_mapping() +{ + m_nozzle_mapping_result.clear(); + // Orca: no BBS get_current_machine(); use the selected device (same accessor get_mapped_nozzles uses). + DeviceManager* dev = wxGetApp().getDeviceManager(); + if (MachineObject* obj_ = dev ? dev->get_selected_machine() : nullptr) + obj_->get_nozzle_mapping_result()->Clear(); +} + +void SelectMachineDialog::on_flow_cali_option_changed() +{ + // Flow calibration feeds the printer-side rack nozzle-mapping computation, so a change must + // invalidate the cached mapping and let the next status poll re-request it (V0 path). + DeviceManager* dev = wxGetApp().getDeviceManager(); + MachineObject* obj_ = dev ? dev->get_selected_machine() : nullptr; + if (!obj_ || !(obj_->GetNozzleSystem() && obj_->GetNozzleSystem()->GetNozzleRack()->IsSupported())) return; + if (use_dynamic_nozzle_map()) return; + // Orca: BBS also pops a confirmation dialog and re-fires immediately (and handles a PA-value + // switch Orca lacks); here we just clear + unthrottle so the next poll re-requests promptly. + clear_nozzle_mapping(); + s_nozzle_mapping_last_request_time = 0; +} + +// Rack print-dispatch nozzle mapping, dynamic-map (V1) path. Fires get_auto_nozzle_mapping when no +// result is cached, blocks Send while the printer computes, then surfaces error/warning. Returns +// false (pre-print check fails / keep waiting) only while blocking; true when the chain may proceed. +bool SelectMachineDialog::CheckErrorSyncNozzleMappingResultV1(MachineObject* obj_) +{ + if (m_print_type != FROM_NORMAL) + return true; // there is no slicing data when printing from sdcard + + if (!obj_) + return true; + + if (!(obj_->GetNozzleSystem() && obj_->GetNozzleSystem()->GetNozzleRack()->IsSupported())) + return true; // no need to check if the printer has no nozzle rack + + if (!use_dynamic_nozzle_map()) + return true; + + const auto& obj_nozzle_mapping_ptr = obj_->get_nozzle_mapping_result(); + if (!obj_nozzle_mapping_ptr->HasResult()) { + if (time(nullptr) - s_nozzle_mapping_last_request_time > 10) { // avoid too many requests + int rtn = obj_nozzle_mapping_ptr->CtrlGetAutoNozzleMappingV1(m_plater); + if (rtn == 0) { + s_nozzle_mapping_last_request_time = time(nullptr); + } else { + const auto& err_msg = wxString::Format(_L("Failed to send nozzle auto-mapping request to printer { code: %d }. " + "Please try to refresh the printer information. " + "If it still does not recover, you can try to rebind the printer and check the network connection."), rtn); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWaiting, {err_msg}); + return false; + } + } + + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWaiting, {_L("The printer is calculating nozzle mapping.") + " " + _L("Please wait a moment...")}); + return false; + } + + if (obj_nozzle_mapping_ptr->GetResultStr() == "failed") { + const auto& err_msg = wxString::Format(_L("Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information."), obj_nozzle_mapping_ptr->GetMqttReason()); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return false; + } + + if (obj_nozzle_mapping_ptr->GetResultStr() == "fail") { + const wxString& err_msg = wxString::Format(_L("The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information."), obj_nozzle_mapping_ptr->GetErrno()); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return false; + } + + const auto& mapping_map = obj_->get_nozzle_mapping_result()->GetNozzleMappingMap(); + if (!mapping_map.empty()) { + if (m_nozzle_mapping_result != mapping_map) { + m_nozzle_mapping_result = mapping_map; + sync_ams_mapping_result(m_ams_mapping_result); + } + + float flush_waste_base = obj_->get_nozzle_mapping_result()->GetFlushWeightBase(); + float flush_waste_current = obj_->get_nozzle_mapping_result()->GetFlushWeightCurrent(); + if ((flush_waste_base != -1) && (flush_waste_current != -1) && flush_waste_current > flush_waste_base) { + const wxString& warning_msg = wxString::Format(_L("The current nozzle mapping may produce an extra %0.2f g of waste."), flush_waste_current - flush_waste_base); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWarning, {warning_msg}); + } + return true; + } + + const wxString& err_msg = wxString::Format(_L("Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information."), "empty table"); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return true; +} + +// Rack print-dispatch nozzle mapping, static-rack (V0) path — see CheckErrorSyncNozzleMappingResultV1. +bool SelectMachineDialog::CheckErrorSyncNozzleMappingResultV0(MachineObject* obj_) +{ + if (!obj_) + return true; + + if (!(obj_->GetNozzleSystem() && obj_->GetNozzleSystem()->GetNozzleRack()->IsSupported())) + return true; // no need to check if the printer has no nozzle rack + + if (m_print_type != FROM_NORMAL) + return true; // there is no slicing data when printing from sdcard + + if (use_dynamic_nozzle_map()) + return true; // handled by the V1 path + + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(m_plater); + if (nozzle_group_res && nozzle_group_res->get_used_nozzles_in_extruder(LOGIC_R_EXTRUDER_ID).empty()) + return true; // no right-extruder nozzles used in slicing -> nothing to map + + const auto& obj_nozzle_mapping_ptr = obj_->get_nozzle_mapping_result(); + if (!obj_nozzle_mapping_ptr->HasResult()) { + if (time(nullptr) - s_nozzle_mapping_last_request_time > 10) { // avoid too many requests + // Orca: BBS passes m_pa_value_switch->GetValue() ? 0 : 1; Orca has no PA-value switch UI, + // so use the switch-off default (1). + int rtn = obj_nozzle_mapping_ptr->CtrlGetAutoNozzleMappingV0(m_plater, m_ams_mapping_result, m_checkbox_list["flow_cali"]->getValueInt(), 1); + if (rtn == 0) { + s_nozzle_mapping_last_request_time = time(nullptr); + } else { + const auto& err_msg = wxString::Format(_L("Failed to send nozzle auto-mapping request to printer { code: %d }. " + "Please try to refresh the printer information. " + "If it still does not recover, you can try to rebind the printer and check the network connection."), rtn); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWaiting, {err_msg}); + return false; + } + } + + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWaiting, {_L("The printer is calculating nozzle mapping.") + " " + _L("Please wait a moment...")}); + return false; + } + + if (obj_nozzle_mapping_ptr->GetResultStr() == "failed") { + const auto& err_msg = wxString::Format(_L("Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information."), obj_nozzle_mapping_ptr->GetMqttReason()); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return false; + } + + if (obj_nozzle_mapping_ptr->GetResultStr() == "fail") { + const wxString& err_msg = wxString::Format(_L("The printer failed to build the nozzle auto-mapping table { code: %d }. Please refresh nozzle information."), obj_nozzle_mapping_ptr->GetErrno()); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return false; + } + + const auto& mapping_map = obj_->get_nozzle_mapping_result()->GetNozzleMappingMap(); + if (!mapping_map.empty()) { + if (m_nozzle_mapping_result != mapping_map) { + m_nozzle_mapping_result = mapping_map; + sync_ams_mapping_result(m_ams_mapping_result); + } + + float flush_waste_base = obj_->get_nozzle_mapping_result()->GetFlushWeightBase(); + float flush_waste_current = obj_->get_nozzle_mapping_result()->GetFlushWeightCurrent(); + if ((flush_waste_base != -1) && (flush_waste_current != -1) && flush_waste_current > flush_waste_base) { + const wxString& warning_msg = wxString::Format(_L("The current nozzle mapping may produce an extra %0.2f g of waste."), flush_waste_current - flush_waste_base); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingWarning, {warning_msg}); + } + return true; + } + + const wxString& err_msg = wxString::Format(_L("Failed to receive nozzle auto-mapping table from printer { msg: %s }. Please refresh the printer information."), "empty table"); + show_status(PrintDialogStatus::PrintStatusRackNozzleMappingError, {err_msg}); + return true; +} + +bool SelectMachineDialog::is_ams_drying(MachineObject* obj) +{ + const auto& ams_list = obj->GetFilaSystem()->GetAmsList(); + for (auto ams = ams_list.begin(); ams != ams_list.end(); ams++) { + if (ams->second->AmsIsDrying()) { + return true; + } + } + + return false; +} + +bool SelectMachineDialog::is_selected_ams_drying(MachineObject* obj) +{ + if (!obj) return false; + + // If a UI material is selected, only when that material is mapped to an AMS + // and that AMS is currently drying. + for (const auto &kv : m_materialList) { + Material *mat = kv.second; + if (!mat || !mat->item) continue; + if (!mat->item->m_selected) continue; + + // find mapping entry for this material id + for (const FilamentInfo &f : m_ams_mapping_result) { + if (f.id != mat->id) continue; + + if (f.ams_id.empty()) return false; + + auto fila_system = obj->GetFilaSystem(); + if (!fila_system) return false; + DevAms* dev_ams = fila_system->GetAmsById(f.ams_id); + return (dev_ams && dev_ams->AmsIsDrying()); + } + + return false; + } + + return false; +} + void SelectMachineDialog::prepare(int print_plate_idx) { m_print_plate_idx = print_plate_idx; @@ -1684,6 +2026,44 @@ void SelectMachineDialog::show_status(PrintDialogStatus status, std::vector<wxSt } else if (status == PrintStatusWarningExtFilamentNotMatch) { Enable_Refresh_Button(true); Enable_Send_Button(true); + } else if (status == PrintDialogStatus::PrintStatusRackNozzleMappingWaiting) { + // Printer is computing the rack nozzle mapping: block Send until it replies. + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusRackNozzleMappingError) { + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusRackNozzleMappingWarning) { + // Extra-waste warning: allow Send. + Enable_Refresh_Button(true); + Enable_Send_Button(true); + } else if (status == PrintDialogStatus::PrintStatusFilaSwitcherError) { + // Missing or un-set-up switch required by the slice: block Send. + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusFilaSwitcherSlicingNotMatch) { + // Advisory slicing/hardware mismatch: allow Send. + Enable_Refresh_Button(true); + Enable_Send_Button(true); + } else if (status == PrintDialogStatus::PrintStatusFilamentWarningNozzleHRC) { + // Hardness caution against a rack-mapped nozzle: allow Send. + Enable_Refresh_Button(true); + Enable_Send_Button(true); + } else if (status == PrintDialogStatus::PrintStatusNozzleNoMatchedHotends) { + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusNozzleRackMaximumInstalled) { + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusRackReading) { + // Rack hotend info is being read: block Send until it finishes. + Enable_Refresh_Button(true); + Enable_Send_Button(false); + } else if (status == PrintDialogStatus::PrintStatusRackNozzleNumUnmeetWarning || + status == PrintDialogStatus::PrintStatusHasUnreliableNozzleWarning) { + // Advisory rack inventory shortfalls: allow Send. + Enable_Refresh_Button(true); + Enable_Send_Button(true); } /*enter perpare mode*/ @@ -1759,84 +2139,17 @@ static std::unordered_set<int> _get_used_nozzle_idxes() return used_nozzle_idxes; } - -static bool _is_nozzle_data_valid(MachineObject* obj_, const DevExtderSystem &ext_data) +// On a hotend-rack printer the right extruder swaps to the required nozzle during the print, so +// pre-print checks against its currently mounted nozzle don't apply. Availability of a matching +// nozzle (flow and diameter) is checked against the whole inventory (mounted + rack) in +// CheckErrorExtruderNozzleWithSlicing() instead. +static bool _is_rack_managed_nozzle(const MachineObject* obj, int nozzle_idx) { - if (obj_ == nullptr) return false; - - PresetBundle *preset_bundle = wxGetApp().preset_bundle; - - try { - PartPlate *cur_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); - auto used_filament_idxs = cur_plate->get_used_filaments(); /*the index is started from 1*/ - for (int used_filament_idx : used_filament_idxs) - { - int used_nozzle_idx = cur_plate->get_physical_extruder_by_filament_id(preset_bundle->full_config(), used_filament_idx); - if (ext_data.GetNozzleType(used_nozzle_idx) == NozzleType::ntUndefine || - ext_data.GetNozzleDiameter(used_nozzle_idx) <= 0.0f || - ext_data.GetNozzleFlowType(used_nozzle_idx) == NozzleFlowType::NONE_FLOWTYPE) { - return false; - } - } - } catch (const std::exception &) { + if (nozzle_idx != MAIN_EXTRUDER_ID) return false; - } - return true; -} - - -/**************************************************************//* - * @param tag_nozzle_type -- return the mismatch nozzle type - * @param tag_nozzle_diameter -- return the target nozzle_diameter but mismatch - * @return is same or not -/*************************************************************/ -static bool _is_same_nozzle_diameters(MachineObject* obj, float &tag_nozzle_diameter, int& mismatch_nozzle_id) -{ - if (obj == nullptr) return false; - - PresetBundle* preset_bundle = wxGetApp().preset_bundle; - auto opt_nozzle_diameters = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter"); - if (!opt_nozzle_diameters) - { - return false; - } - - try - { - PartPlate* cur_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); - auto used_filament_idxs = cur_plate->get_used_filaments();/*the index is started from 1*/ - for (int used_filament_idx : used_filament_idxs) - { - int used_nozzle_idx = cur_plate->get_physical_extruder_by_filament_id(preset_bundle->full_config(), used_filament_idx); - if (used_nozzle_idx == -1) - { - assert(0); - return false; - } - - tag_nozzle_diameter = float(opt_nozzle_diameters->get_at(used_nozzle_idx)); - auto machine_nozzle_diameter = obj->GetExtderSystem()->GetNozzleDiameter(used_nozzle_idx); - - // Assume matching if diameter is unknown - if (machine_nozzle_diameter == 0.0f) - { - continue; - } - - if (tag_nozzle_diameter != machine_nozzle_diameter) - { - mismatch_nozzle_id = used_nozzle_idx; - return false; - } - } - } - catch (const std::exception&) - { - return false; - } - - return true; + const DevNozzleSystem* nozzle_sys = obj ? obj->GetNozzleSystem() : nullptr; + return nozzle_sys && nozzle_sys->GetNozzleRack() && nozzle_sys->GetNozzleRack()->IsSupported(); } bool SelectMachineDialog::is_nozzle_hrc_matched(const DevExtder* extruder, std::string& filament_type) const @@ -1983,15 +2296,48 @@ void SelectMachineDialog::on_ok_btn(wxCommandEvent &event) } } - bool in_blacklist = false; - std::string action; - wxString info; - wxString wiki_url; - DevFilaBlacklist::check_filaments_in_blacklist_url(obj_->printer_type, filament_brand, filament_type, m_ams_mapping_result[i].filament_id, ams_id, slot_id, "", in_blacklist, - action, info, wiki_url); - if (in_blacklist && action == "warning") { - confirm_text.push_back(ConfirmBeforeSendInfo(info, wiki_url)); - has_slice_warnings = true; + DevFilaBlacklist::CheckFilamentInfo check_info; + check_info.dev_id = obj_->get_dev_id(); + check_info.model_id = obj_->printer_type; + check_info.fila_id = m_ams_mapping_result[i].filament_id; + check_info.fila_type = filament_type; + check_info.fila_vendor = filament_brand; + // Populate fila_name so the high-flow warning strings (blacklist rules 14/15/18/19, + // "%s has a risk of nozzle clogging ...") render with the filament name instead of a + // leading blank. Resolves the same preset the engine's internal AMS-name recovery uses, so + // blacklist name-matching is unchanged. + if (auto option = wxGetApp().preset_bundle->get_filament_by_filament_id(check_info.fila_id)) + check_info.fila_name = option->filament_name; + check_info.ams_id = ams_id; + check_info.slot_id = slot_id; + check_info.has_filament_switch = obj_->GetFilaSwitch()->IsInstalled(); + + std::vector<DevNozzle> mapped_nozzles; + for (const auto &[pos_id, nozzle] : get_mapped_nozzles(m_ams_mapping_result[i].id)) { + if (!nozzle.IsEmpty()) { mapped_nozzles.push_back(nozzle); } + } + + // Evaluate the blacklist once per resolved physical nozzle so the high-flow + // nozzle_flows/nozzle_diameters rules match against the real nozzle. If no nozzle context is + // resolvable (a non-rack printer, or a rack filament not yet mapped by the print-dispatch + // mapping), evaluate once with the nozzle fields unset so the non-nozzle rules still fire as + // before (empty nozzle_flow never matches a nozzle_flows rule). + const size_t iterations = mapped_nozzles.empty() ? 1 : mapped_nozzles.size(); + for (size_t n = 0; n < iterations; ++n) { + if (n < mapped_nozzles.size()) { + const DevNozzle &nozzle = mapped_nozzles[n]; + check_info.extruder_id = nozzle.GetExtruderId(); + check_info.nozzle_flow = DevNozzle::GetNozzleFlowTypeString(nozzle.GetNozzleFlowType()); + check_info.nozzle_diameter = nozzle.GetNozzleDiameter(); + } + + const auto &result = DevFilaBlacklist::check_filaments_in_blacklist(check_info); + if (const auto &warning_items = result.get_items_by_action("warning"); !warning_items.empty()) { + for (const auto &item : warning_items) { + confirm_text.push_back(ConfirmBeforeSendInfo(item.info_msg, item.wiki_url)); + has_slice_warnings = true; + } + } } } @@ -2514,6 +2860,12 @@ void SelectMachineDialog::on_send_print() m_print_job->task_ams_mapping = ams_mapping_array; m_print_job->task_ams_mapping2 = ams_mapping_array2; m_print_job->task_ams_mapping_info = ams_mapping_info; + // Print-dispatch nozzle mapping (H2C hotend rack): attach ONLY when a mapping result exists. + // For every non-rack printer (X1/P1/A1/H2S/H2D) the mapping json is empty, so task_nozzle_mapping + // stays absent and the print payload is unchanged. + if (!obj_->get_nozzle_mapping_result()->GetNozzleMappingJson().empty()) { + m_print_job->task_nozzle_mapping = obj_->get_nozzle_mapping_result()->GetNozzleMappingJson().dump(); + } /* build nozzles info for multi extruders printers */ if (build_nozzles_info(m_print_job->task_nozzles_info)) { @@ -2689,6 +3041,7 @@ void SelectMachineDialog::on_set_finish_mapping(wxCommandEvent &evt) if (item->id == m_current_filament_id) { auto ams_colour = wxColour(wxAtoi(selection_data_arr[0]), wxAtoi(selection_data_arr[1]), wxAtoi(selection_data_arr[2]), wxAtoi(selection_data_arr[3])); m->set_ams_info(ams_colour, selection_data_arr[4], ctype, material_cols); + m->set_nozzle_info(get_mapped_nozzle_str(item->id)); } iter++; } @@ -2993,9 +3346,11 @@ void SelectMachineDialog::on_selection_changed(wxCommandEvent &event) /* reset timeout and reading printer info */ m_status_bar->reset(); m_timeout_count = 0; + s_nozzle_mapping_last_request_time = 0; m_ams_mapping_res = false; m_ams_mapping_valid = false; m_ams_mapping_result.clear(); + clear_nozzle_mapping(); m_pre_print_checker.clear(); m_link_edit_nozzle->Show(false); @@ -3102,7 +3457,9 @@ void SelectMachineDialog::update_filament_change_count() auto best = stats.stats_by_multi_extruder_best; auto curr = stats.stats_by_multi_extruder_curr; - int hand_changes_count = curr.filament_change_count - best.filament_change_count; + // Per-nozzle flush_filament_change_count. Equals the per-extruder filament_change_count for + // single-nozzle-per-extruder printers, so this suggestion's shown value is unchanged. + int hand_changes_count = curr.flush_filament_change_count - best.flush_filament_change_count; int saving_weight = curr.filament_flush_weight - best.filament_flush_weight; if (obj->GetExtderSystem()->GetTotalExtderCount() > 1) { m_link_edit_nozzle->Show(true); } @@ -3158,6 +3515,303 @@ static wxString _get_nozzle_name(int total_ext_count, int ext_id) return _L("nozzle"); } +// Nozzle requirements of the sliced plate. key -> physical extruder id, value -> nozzle data. +// For example: +// {0, {0.4, S_FLOW}}, {1, {0.8, H_FLOW}} +// {0, {0.4, S_FLOW}}, {0, {0.4, H_FLOW}} // hybrid +static std::unordered_multimap<int, NozzleDef> s_get_slicing_extuder_nozzles() +{ + std::unordered_multimap<int, NozzleDef> used_extuder_nozzles; + + PresetBundle* preset_bundle = wxGetApp().preset_bundle; + if (!preset_bundle) { + return used_extuder_nozzles; + } + + PartPlate* cur_plate = wxGetApp().plater()->get_partplate_list().get_curr_plate(); + if (!cur_plate) { + return used_extuder_nozzles; + } + + auto opt_nozzle_diameters = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter"); + if (!opt_nozzle_diameters) { + return used_extuder_nozzles; + } + + auto nozzle_volume_type_opt = dynamic_cast<const ConfigOptionEnumsGeneric*>(preset_bundle->project_config.option("nozzle_volume_type")); + if (!nozzle_volume_type_opt) { + return used_extuder_nozzles; + } + + try { + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(wxGetApp().plater()); + if (nozzle_group_res && nozzle_group_res->is_support_dynamic_nozzle_map() && nozzle_volume_type_opt->values.size() == 2) { + const auto& used_nozzles = nozzle_group_res->get_used_nozzles_in_extruder(); + for (const auto& used_nozzle : used_nozzles) { + NozzleDef nozzle_data; + nozzle_data.nozzle_diameter = std::stof(used_nozzle.diameter); + nozzle_data.nozzle_flow_type = DevNozzle::ToNozzleFlowType(used_nozzle.volume_type); + if (used_nozzle.extruder_id == 0) { + used_extuder_nozzles.insert({ DEPUTY_EXTRUDER_ID, nozzle_data }); + } else if (used_nozzle.extruder_id == 1) { + used_extuder_nozzles.insert({ MAIN_EXTRUDER_ID, nozzle_data }); + } + }; + + return used_extuder_nozzles; + } + + const auto& used_filament_idxs = cur_plate->get_used_filaments(); /*the index is started from 1*/ + for (int used_filament_idx : used_filament_idxs) { + int physical_idx = cur_plate->get_physical_extruder_by_filament_id(preset_bundle->full_config(), used_filament_idx); + int logic_extruder_idx = cur_plate->get_logical_extruder_by_filament_id(preset_bundle->full_config(), used_filament_idx); + if (physical_idx < 0 || logic_extruder_idx < 0) { + assert(0); + continue; + } + + NozzleDef nozzle_data; + nozzle_data.nozzle_diameter = float(opt_nozzle_diameters->get_at(logic_extruder_idx)); + nozzle_data.nozzle_flow_type = NozzleFlowType::S_FLOW;// default value + + auto volume_type = (NozzleVolumeType)nozzle_volume_type_opt->get_at(logic_extruder_idx); + if (volume_type == NozzleVolumeType::nvtHybrid) { + if (used_extuder_nozzles.find(physical_idx) != used_extuder_nozzles.end()) { + continue;// already collected + } + + // A hybrid extruder prints with a mix of nozzle flows: collect the flow of each + // physically used nozzle instead of forcing a single one. + if (nozzle_group_res) { + for (const auto& nozzle_info : nozzle_group_res->get_used_nozzles_in_extruder(logic_extruder_idx)) { + nozzle_data.nozzle_flow_type = DevNozzle::ToNozzleFlowType(nozzle_info.volume_type); + used_extuder_nozzles.insert({ physical_idx, nozzle_data }); + } + } else { + // Orca: a by-object plate with several objects produces no plate-level nozzle + // grouping, so the used flows are unknown; skip the check for this extruder + // rather than blocking the print. + BOOST_LOG_TRIVIAL(warning) << __FUNCTION__ << ": no nozzle group result, nozzle check skipped for extruder " << logic_extruder_idx; + } + + continue; + } + + nozzle_data.nozzle_flow_type = DevNozzle::ToNozzleFlowType(volume_type); + used_extuder_nozzles.insert({ physical_idx, nozzle_data }); + }; + } catch (const std::exception& e) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "exception: " << e.what(); + } + + return used_extuder_nozzles; +} + +bool SelectMachineDialog::CheckErrorRackStatus(MachineObject* obj_) +{ + if (!obj_) { + return true; + } + + auto rack = obj_->GetNozzleSystem()->GetNozzleRack(); + if (!rack->IsSupported()) { + return true; + } + + if (rack->GetReadingCount() > 0) { + const wxString& msg = wxString::Format(_L("Refreshing information of hotends(%d/%d)."), rack->GetReadingIdx(), rack->GetReadingCount()); + show_status(PrintDialogStatus::PrintStatusRackReading, { msg + " " + _L("Please wait a moment...") }); + return false; + } + + return true; +} + +void SelectMachineDialog::CheckWarningRackStatus(MachineObject* obj_) +{ + if (!obj_) { + return; + } + + const auto& nozzle_sys = obj_->GetNozzleSystem(); + const auto& rack = nozzle_sys->GetNozzleRack(); + if (!rack->IsSupported()) { + return; + } + + auto nozzle_group_res = DevUtilBackend::GetNozzleGroupResult(m_plater); + if (!nozzle_group_res) { + return; + } + + if (m_print_type != FROM_NORMAL) { + return;// there are no slicing data when print from sdcard + } + + const auto& nozzle_vec = nozzle_group_res->get_used_nozzles_in_extruder(LOGIC_R_EXTRUDER_ID); + if (nozzle_vec.empty()) { + return;// no need to check if no right nozzles used in slicing + } + + std::unordered_map<NozzleDef, int> need_nozzle_map; + for (const auto& slicing_nozzle : nozzle_vec) { + try { + NozzleDef data; + data.nozzle_diameter = std::stof(slicing_nozzle.diameter); + data.nozzle_flow_type = DevNozzle::ToNozzleFlowType(slicing_nozzle.volume_type); + need_nozzle_map[data]++; + } catch (const std::exception& e) { + assert(0); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "exception: " << e.what(); + } + } + + for (const auto& need_nozzle : need_nozzle_map) { + const auto& nozzle_info = need_nozzle.first; + const auto& installed_nozzles = nozzle_sys->CollectNozzles(MAIN_EXTRUDER_ID, nozzle_info.nozzle_flow_type, nozzle_info.nozzle_diameter); + int installed_count = installed_nozzles.size(); + int installed_reliable_count = 0; + for (const auto& nozzle : installed_nozzles) { + if (nozzle.IsInfoReliable()) { + installed_reliable_count++; + } + } + + // check if enough nozzles installed + if (need_nozzle.second > installed_count) { + wxString msg = _L("There are not enough available hotends currently."); + msg += " "; + if (rack->GetCaliStatus() != DevNozzleRack::Rack_CALI_OK) { + msg += _L("Please complete the hotend rack setup and try again."); + } else if (nozzle_sys->HasUnknownNozzles()) { + msg += _L("Please refresh the nozzle information and try again."); + } else { + msg += _L("Please re-slice to avoid filament waste."); + } + + show_status(PrintDialogStatus::PrintStatusRackNozzleNumUnmeetWarning, { msg }); + break; + } + + // check if unreliable nozzle maybe used + if (need_nozzle.second > installed_reliable_count && nozzle_sys->HasUnreliableNozzles()) { + // Orca: text-only warning; this message board has no refresh / don't-show-again buttons. + show_status(PrintDialogStatus::PrintStatusHasUnreliableNozzleWarning, + { _L("The reported hotend information may be unreliable.") + " " + _L("Please refresh the nozzle information and try again.") }); + } + } +} + +// Compare the extruder nozzle info between slicing file and installed on printer +bool SelectMachineDialog::CheckErrorExtruderNozzleWithSlicing(MachineObject* obj_) +{ + if (!obj_) { + return false; + } + + const auto& ext_sys = obj_->GetExtderSystem(); + const auto& nozzle_sys = obj_->GetNozzleSystem(); + if (m_print_type == FROM_NORMAL) { + const auto& slicing_ext_nozzles = s_get_slicing_extuder_nozzles(); + for (auto slicing_ext_nozzle : slicing_ext_nozzles) { + int slicing_ext_idx = slicing_ext_nozzle.first; + auto slicing_ext = slicing_ext_nozzle.second; + auto installed_ext_nozzle = nozzle_sys->GetExtNozzle(slicing_ext_idx); + + // No need to check the right extruder's mounted nozzle when using a nozzle rack: the + // extruder swaps nozzles during the print, so the inventory (mounted + rack) must hold + // a matching nozzle instead. + if (slicing_ext_idx == MAIN_EXTRUDER_ID && nozzle_sys->GetNozzleRack()->IsSupported()) { + if (nozzle_sys->CollectNozzles(MAIN_EXTRUDER_ID, slicing_ext.nozzle_flow_type, slicing_ext.nozzle_diameter).empty()) { + wxString slicing_nozzle_str = DevNozzle::GetNozzleFlowTypeStr(slicing_ext.nozzle_flow_type); + if (slicing_ext.nozzle_diameter > 0.0f) + slicing_nozzle_str += wxString::Format(" %.1fmm", slicing_ext.nozzle_diameter); + wxString msg = wxString::Format(_L("The printer has no nozzle matching the slicing file (%s)."), slicing_nozzle_str); + msg += " "; + if (nozzle_sys->GetNozzleRack()->GetCaliStatus() != DevNozzleRack::Rack_CALI_OK) + msg += _L("Please complete the hotend rack setup and try again."); + else if (nozzle_sys->HasUnknownNozzles() || nozzle_sys->HasUnreliableNozzles()) + msg += _L("Please refresh the nozzle information and try again."); + else + msg += _L("Please install a matching nozzle in the hotend rack, or set the corresponding printer preset while slicing."); + + show_status(PrintDialogStatus::PrintStatusNozzleNoMatchedHotends, { msg }); + return false; + } + + // A nozzle swap needs a free rack slot to stow the mounted nozzle first. + if (nozzle_sys->IsRackMaximumInstalled()) { + show_status(PrintDialogStatus::PrintStatusNozzleRackMaximumInstalled, + { _L("The toolhead and hotend rack are full. Please remove at least one hotend before printing.") }); + return false; + } + + continue; + } + + // check nozzle data valid + { + if (installed_ext_nozzle.GetNozzleType() == NozzleType::ntUndefine || + installed_ext_nozzle.GetNozzleDiameter() <= 0.0f) { + show_status(PrintDialogStatus::PrintStatusNozzleDataInvalid); + return false; + } + + if (obj_->is_nozzle_flow_type_supported() && + installed_ext_nozzle.GetNozzleFlowType() == NozzleFlowType::NONE_FLOWTYPE) { + show_status(PrintDialogStatus::PrintStatusNozzleDataInvalid); + return false; + } + } + + // check nozzle flow type + { + if (obj_->is_nozzle_flow_type_supported() && slicing_ext.nozzle_flow_type != installed_ext_nozzle.GetNozzleFlowType()) { + const wxString& pos = _get_nozzle_name(ext_sys->GetTotalExtderCount(), slicing_ext_idx); + const wxString& installed_nozzle_str = installed_ext_nozzle.GetNozzleFlowTypeStr(); + const wxString& slicing_nozzle_str = DevNozzle::GetNozzleFlowTypeStr(slicing_ext.nozzle_flow_type); + wxString error_message = wxString::Format(_L("The nozzle flow setting of %s(%s) doesn't match with the slicing file(%s). " + "Please make sure the nozzle installed matches with settings in printer, " + "then set the corresponding printer preset while slicing."), + pos, installed_nozzle_str, slicing_nozzle_str); + + std::vector<wxString> params{ error_message }; + params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting.")); + show_status(PrintDialogStatus::PrintStatusNozzleMatchInvalid, params); + return false; + } + } + + // check nozzle diameter + { + if (slicing_ext.nozzle_diameter != installed_ext_nozzle.GetNozzleDiameter()) { + std::vector<wxString> msg_params; + if (ext_sys->GetTotalExtderCount() == 2) { + const wxString& mismatch_nozzle_str = _get_nozzle_name(ext_sys->GetTotalExtderCount(), slicing_ext_idx); + const wxString& nozzle_message = wxString::Format(_L("The %s diameter(%.1fmm) of current printer doesn't match with the slicing file (%.1fmm). " + "Please make sure the nozzle installed matches with settings in printer, then set the " + "corresponding printer preset when slicing."), + mismatch_nozzle_str, installed_ext_nozzle.GetNozzleDiameter(), slicing_ext.nozzle_diameter); + msg_params.emplace_back(nozzle_message); + } else { + const wxString& nozzle_message = wxString::Format(_L("The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). " + "Please make sure the nozzle installed matches with settings in printer, then set the " + "corresponding printer preset when slicing."), + installed_ext_nozzle.GetNozzleDiameter(), slicing_ext.nozzle_diameter); + msg_params.emplace_back(nozzle_message); + } + + msg_params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting.")); + show_status(PrintDialogStatus::PrintStatusNozzleDiameterMismatch, msg_params); + return false; + } + } + } + } + + return true; +} + static wxString _get_ext_loc_str(const std::unordered_set<int>& extruders, int total_ext_num) { assert(!extruders.empty()); @@ -3285,6 +3939,16 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) m_check_ext_change_assist->Enable(false); } + { + const bool show_warn_when_drying = is_selected_ams_drying(obj_); + const bool is_currently_shown = (m_txt_warn_when_drying != nullptr) ? m_txt_warn_when_drying->IsShown() : false; + if (is_currently_shown != show_warn_when_drying) { + m_warn_when_drying_sizer->Show(show_warn_when_drying); + Layout(); + Fit(); + } + } + /*reading done*/ if (wxGetApp().app_config) { if (obj_->upgrade_force_upgrade) { @@ -3360,59 +4024,24 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) const auto &full_config = wxGetApp().preset_bundle->full_config(); size_t nozzle_nums = full_config.option<ConfigOptionFloats>("nozzle_diameter")->values.size(); - /*the nozzle type of preset and machine are different*/ - if (nozzle_nums > 1 && m_print_type == FROM_NORMAL) { - if (!_is_nozzle_data_valid(obj_, *obj_->GetExtderSystem())) { - show_status(PrintDialogStatus::PrintStatusNozzleDataInvalid); - return; - } + // Filament Track Switch: warn on a slicing/hardware mismatch, and block Send when dynamic + // nozzle mapping needs a switch that isn't installed or set up. No-op for printers without one. + if (!CheckErrorDynamicSwitchNozzle(obj_)) return; - wxString error_message; - if (!is_nozzle_type_match(*obj_->GetExtderSystem(), error_message)) { - std::vector<wxString> params{error_message}; - params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting.")); - show_status(PrintDialogStatus::PrintStatusNozzleMatchInvalid, params); - return; - } - } + // Block Send while a rack printer is still reading its hotend information. + if (!CheckErrorRackStatus(obj_)) return; + + // Compare the slicing file's nozzle requirements (validity, flow, diameter) against the printer. + if (!CheckErrorExtruderNozzleWithSlicing(obj_)) return; - // check nozzle type and diameter if (m_print_type == PrintFromType::FROM_NORMAL) { - int mismatch_nozzle_id = 0; - float nozzle_diameter = 0; - if (!_is_same_nozzle_diameters(obj_, nozzle_diameter, mismatch_nozzle_id)) - { - std::vector<wxString> msg_params; - if (obj_->GetExtderSystem()->GetTotalExtderCount() == 2) { - wxString mismatch_nozzle_str; - if (mismatch_nozzle_id == MAIN_EXTRUDER_ID) { - mismatch_nozzle_str = _L("right nozzle"); - } else { - mismatch_nozzle_str = _L("left nozzle"); - } - - const wxString &nozzle_config = wxString::Format(_L("The %s diameter(%.1fmm) of current printer doesn't match with the slicing file (%.1fmm). " - "Please make sure the nozzle installed matches with settings in printer, then set the " - "corresponding printer preset when slicing."), - mismatch_nozzle_str, obj_->GetExtderSystem()->GetNozzleDiameter(mismatch_nozzle_id), nozzle_diameter); - msg_params.emplace_back(nozzle_config); - } else { - const wxString &nozzle_config = wxString::Format(_L("The current nozzle diameter (%.1fmm) doesn't match with the slicing file (%.1fmm). " - "Please make sure the nozzle installed matches with settings in printer, then set the " - "corresponding printer preset when slicing."), - obj_->GetExtderSystem()->GetNozzleDiameter(0), nozzle_diameter); - msg_params.emplace_back(nozzle_config); - } - - msg_params.emplace_back(_L("Tips: If you changed your nozzle of your printer lately, Please go to 'Device -> Printer parts' to change your nozzle setting.")); - show_status(PrintDialogStatus::PrintStatusNozzleDiameterMismatch, msg_params); - return; - } - + // Orca: blocking hardness gate on the mounted nozzles; the rack extruder is instead judged + // per dispatch-mapped nozzle in the blacklist loop below, as a non-blocking caution. const auto &used_nozzle_idxes = _get_used_nozzle_idxes(); for (const auto &extder : obj_->GetExtderSystem()->GetExtruders()) { if (used_nozzle_idxes.count(extder.GetNozzleId()) == 0) { continue; } + if (_is_rack_managed_nozzle(obj_, extder.GetNozzleId())) { continue; } std::string filament_type; if (!is_nozzle_hrc_matched(&extder, filament_type)) { @@ -3425,6 +4054,10 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) } } + // Rack print-dispatch nozzle mapping (dynamic V1): request/await the printer's mapping and block + // Send while it computes. No-op for non-rack printers. + if (!CheckErrorSyncNozzleMappingResultV1(obj_)) return; + if (!DevPrinterConfigUtil::support_ams_ext_mix_print(obj_->printer_type)) { bool useAms = _HasAms(m_ams_mapping_result); bool useExt = _HasExt(m_ams_mapping_result); @@ -3444,6 +4077,10 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) return; } + // Rack print-dispatch nozzle mapping (static rack V0): consumes the validated AMS mapping, so it + // runs after the AMS-validity check and before the per-nozzle blacklist loop (which needs the result). + if (!CheckErrorSyncNozzleMappingResultV0(obj_)) return; + // filaments check for black list for (auto i = 0; i < m_ams_mapping_result.size(); i++) { const auto &ams_id = m_ams_mapping_result[i].get_ams_id(); @@ -3458,22 +4095,72 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) if (fs.id == m_ams_mapping_result[i].id) { filament_brand = m_filaments[i].brand; } } - bool in_blacklist = false; - std::string action; - wxString info; - wxString wiki_url; - DevFilaBlacklist::check_filaments_in_blacklist_url(obj_->printer_type, filament_brand, filament_type, m_ams_mapping_result[i].filament_id, ams_id, slot_id, "", in_blacklist, - action, info, wiki_url); - if (in_blacklist) { + DevFilaBlacklist::CheckFilamentInfo check_info; + check_info.dev_id = obj_->get_dev_id(); + check_info.model_id = obj_->printer_type; + check_info.fila_id = m_ams_mapping_result[i].filament_id; + check_info.fila_type = filament_type; + check_info.fila_vendor = filament_brand; + // Populate fila_name so the high-flow warning strings (blacklist rules 14/15/18/19, + // "%s has a risk of nozzle clogging ...") render with the filament name instead of a + // leading blank. Resolves the same preset the engine's internal AMS-name recovery uses, so + // blacklist name-matching is unchanged. + if (auto option = wxGetApp().preset_bundle->get_filament_by_filament_id(check_info.fila_id)) + check_info.fila_name = option->filament_name; + check_info.ams_id = ams_id; + check_info.slot_id = slot_id; + check_info.has_filament_switch = obj_->GetFilaSwitch()->IsInstalled(); - std::vector<wxString> error_msg { info }; - if (action == "prohibition") { - show_status(PrintDialogStatus::PrintStatusHasFilamentInBlackListError, error_msg, wiki_url); + std::vector<DevNozzle> mapped_nozzles; + for (const auto &[pos_id, nozzle] : get_mapped_nozzles(m_ams_mapping_result[i].id)) { + if (!nozzle.IsEmpty()) { mapped_nozzles.push_back(nozzle); } + } + + // Per-physical-nozzle blacklist check — thread the nozzle the filament prints on so the + // high-flow prohibition/warning rules evaluate against the real nozzle flow/diameter. + // With no resolvable nozzle context (a non-rack printer, or a rack filament not yet mapped + // by the print-dispatch mapping), evaluate once with the nozzle fields unset so the + // non-nozzle prohibitions/warnings still fire as before. + const size_t iterations = mapped_nozzles.empty() ? 1 : mapped_nozzles.size(); + for (size_t n = 0; n < iterations; ++n) { + if (n < mapped_nozzles.size()) { + const DevNozzle &nozzle = mapped_nozzles[n]; + check_info.extruder_id = nozzle.GetExtruderId(); + check_info.nozzle_flow = DevNozzle::GetNozzleFlowTypeString(nozzle.GetNozzleFlowType()); + check_info.nozzle_diameter = nozzle.GetNozzleDiameter(); + } + + const auto &result = DevFilaBlacklist::check_filaments_in_blacklist(check_info); + if (const auto &prohibition_items = result.get_items_by_action("prohibition"); !prohibition_items.empty()) { + for (const auto &item : prohibition_items) { + show_status(PrintDialogStatus::PrintStatusHasFilamentInBlackListError, {item.info_msg}, item.wiki_url); + } return; } - else if (action == "warning") { - show_status(PrintDialogStatus::PrintStatusHasFilamentInBlackListWarning, error_msg, wiki_url);/** warning check **/ - // return; + + if (const auto &warning_items = result.get_items_by_action("warning"); !warning_items.empty()) { + for (const auto &item : warning_items) { + show_status(PrintDialogStatus::PrintStatusHasFilamentInBlackListWarning, {item.info_msg}, item.wiki_url);/** warning check **/ + } + } + + // A rack-managed nozzle skipped the mounted-nozzle hardness gate above; judge the + // filament's hardness against the nozzle the print-dispatch mapping assigned. Caution + // only: the printer picks the swap target, so Send stays enabled. + if (n < mapped_nozzles.size()) { + const DevNozzle &nozzle = mapped_nozzles[n]; + if (_is_rack_managed_nozzle(obj_, nozzle.GetExtruderId()) && nozzle.GetNozzleType() != NozzleType::ntUndefine) { + const int nozzle_hrc = Print::get_hrc_by_nozzle_type(nozzle.GetNozzleType()); + const int filament_hrc = wxGetApp().preset_bundle->get_required_hrc_by_filament_type(filament_type); + if (abs(filament_hrc) > abs(nozzle_hrc)) { + const int pos_id = nozzle.GetNozzlePosId(); + const wxString nozzle_str = (pos_id < 0x10) ? wxString("R") : wxString::Format("R%d", pos_id - 0x10 + 1); + show_status(PrintDialogStatus::PrintStatusFilamentWarningNozzleHRC, + {wxString::Format(_L("The hardness of current material (%s) exceeds the hardness of %s(%s). It may cause nozzle wear, " + "leading to material leakage and unstable flow. Please exercise caution when using it."), + filament_type, nozzle_str, format_steel_name(nozzle.GetNozzleType()))}); + } + } } } } @@ -3610,6 +4297,9 @@ void SelectMachineDialog::update_show_status(MachineObject* obj_) // check extension tool warning UpdateStatusCheckWarning_ExtensionTool(obj_); + // check rack nozzle warning + CheckWarningRackStatus(obj_); + /** normal check **/ show_status(PrintDialogStatus::PrintStatusReadyToGo); } @@ -3664,6 +4354,7 @@ void SelectMachineDialog::reset_ams_material() wxString ams_id = "-"; wxColour ams_col = wxColour(0xEE, 0xEE, 0xEE); m->set_ams_info(ams_col, ams_id); + m->set_nozzle_info(get_mapped_nozzle_str(id)); iter++; } } @@ -3774,6 +4465,7 @@ void SelectMachineDialog::set_default() m_mapping_sugs_sizer->Show(false); m_change_filament_times_sizer->Show(false); m_txt_change_filament_times->Show(false); + m_warn_when_drying_sizer->Show(false); // rset status bar m_status_bar->reset(); @@ -3883,6 +4575,10 @@ void SelectMachineDialog::reset_and_sync_ams_list() m_filaments_map = wxGetApp().plater()->get_partplate_list().get_curr_plate()->get_real_filament_maps(project_config); } + bool selected_any = false; + MaterialItem *first_enabled = nullptr; + int first_enabled_id = -1; + for (auto i = 0; i < extruders.size(); i++) { auto extruder = extruders[i] - 1; auto colour = wxGetApp().preset_bundle->project_config.opt_string("filament_colour", (unsigned int) extruder); @@ -3912,7 +4608,20 @@ void SelectMachineDialog::reset_and_sync_ams_list() item = new MaterialItem(m_filament_panel, colour_rgb, _L(display_materials[extruder])); m_sizer_ams_mapping->Add(item, 0, wxALL, FromDIP(5)); } + + if (!item) continue; + item->SetToolTip(m_ams_tooltip); + + if (!selected_any && extruder == m_current_filament_id && item->m_enable) { + item->on_selected(); + selected_any = true; + } + if (!first_enabled && item->m_enable) { + first_enabled = item; + first_enabled_id = extruder; + } + item->Bind(wxEVT_LEFT_UP, [this, item, materials, extruder](wxMouseEvent &e) {}); item->Bind(wxEVT_LEFT_DOWN, [this, item, materials, extruder](wxMouseEvent &e) { if (!item->m_enable) {return;} @@ -3968,7 +4677,7 @@ void SelectMachineDialog::reset_and_sync_ams_list() m_mapping_popup.set_current_filament_id(extruder); m_mapping_popup.set_tag_texture(materials[extruder]); m_mapping_popup.set_send_win(this);//fix bug:fisrt click is not valid - m_mapping_popup.update(obj_, m_ams_mapping_result); + m_mapping_popup.update(obj_, m_ams_mapping_result, use_dynamic_nozzle_map(), m_print_type); m_mapping_popup.Popup(); } } @@ -3991,6 +4700,11 @@ void SelectMachineDialog::reset_and_sync_ams_list() } } + if (!selected_any && first_enabled) { + m_current_filament_id = first_enabled_id; + first_enabled->on_selected(); + } + if (use_double_extruder) { m_filament_left_panel->Show(); @@ -4401,6 +5115,10 @@ void SelectMachineDialog::set_default_from_sdcard() m_materialList.clear(); m_filaments.clear(); + bool selected_any = false; + MaterialItem *first_enabled = nullptr; + int first_enabled_id = -1; + for (auto i = 0; i < m_required_data_plate_data_list[m_print_plate_idx]->slice_filaments_info.size(); i++) { FilamentInfo fo = m_required_data_plate_data_list[m_print_plate_idx]->slice_filaments_info[i]; @@ -4423,6 +5141,17 @@ void SelectMachineDialog::set_default_from_sdcard() m_sizer_ams_mapping->Add(item, 0, wxALL, FromDIP(5)); } + if (!item) continue; + + if (!selected_any && fo.id == m_current_filament_id && item->m_enable) { + item->on_selected(); + selected_any = true; + } + if (!first_enabled && item->m_enable) { + first_enabled = item; + first_enabled_id = fo.id; + } + item->Bind(wxEVT_LEFT_UP, [this, item, materials](wxMouseEvent& e) {}); item->Bind(wxEVT_LEFT_DOWN, [this, obj_, item, materials, diameters_count, fo](wxMouseEvent& e) { if (!item->m_enable) {return;} @@ -4471,7 +5200,7 @@ void SelectMachineDialog::set_default_from_sdcard() m_mapping_popup.set_current_filament_id(fo.id); m_mapping_popup.set_tag_texture(fo.type); m_mapping_popup.set_send_win(this); - m_mapping_popup.update(obj_, m_ams_mapping_result); + m_mapping_popup.update(obj_, m_ams_mapping_result, use_dynamic_nozzle_map(), m_print_type); m_mapping_popup.Popup(); } } @@ -4499,6 +5228,11 @@ void SelectMachineDialog::set_default_from_sdcard() wxSize screenSize = wxGetDisplaySize(); auto dialogSize = this->GetSize(); + if (!selected_any && first_enabled) { + m_current_filament_id = first_enabled_id; + first_enabled->on_selected(); + } + reset_ams_material(); // basic info diff --git a/src/slic3r/GUI/SelectMachine.hpp b/src/slic3r/GUI/SelectMachine.hpp index ab88240ec0..a62e8de3d2 100644 --- a/src/slic3r/GUI/SelectMachine.hpp +++ b/src/slic3r/GUI/SelectMachine.hpp @@ -28,10 +28,12 @@ #include "boost/bimap/bimap.hpp" #include "AmsMappingPopup.hpp" +#include "GUI_ObjectLayers.hpp" #include "ReleaseNote.hpp" #include "GUI_Utils.hpp" #include "wxExtensions.hpp" #include "DeviceManager.hpp" +#include "DeviceCore/DevNozzleSystem.h" // DevNozzle (get_mapped_nozzles return type) #include "Plater.hpp" #include "BBLStatusBar.hpp" #include "BBLStatusBarPrint.hpp" @@ -61,10 +63,8 @@ namespace Slic3r { namespace GUI { std::string get_nozzle_volume_type_cloud_string(NozzleVolumeType nozzle_volume_type); void print_ams_mapping_result(std::vector<FilamentInfo> &result); -enum PrintFromType { - FROM_NORMAL, - FROM_SDCARD_VIEW, -}; +// enum PrintFromType moved to DeviceCore/DevDefs.h so shared device-mapping GUI +// headers can name it without an include cycle. SelectMachine.hpp still sees it via DeviceManager.hpp. enum PrintPageMode { PrintPageModePrepare = 0, @@ -324,6 +324,7 @@ private: std::vector<MachineObject*> m_list; std::vector<FilamentInfo> m_filaments; std::vector<FilamentInfo> m_ams_mapping_result; + std::unordered_map<int, int> m_nozzle_mapping_result; // cached rack print-dispatch mapping: filament/group id -> physical nozzle pos std::vector<int> m_filaments_map; std::shared_ptr<BBLStatusBarPrint> m_status_bar; std::unique_ptr<Worker> m_worker; @@ -354,6 +355,7 @@ protected: wxBoxSizer* m_sizer_autorefill{ nullptr }; wxBoxSizer* m_mapping_sugs_sizer{ nullptr }; wxBoxSizer* m_change_filament_times_sizer{ nullptr }; + wxBoxSizer* m_warn_when_drying_sizer{ nullptr }; Button* m_button_ensure{ nullptr }; wxStaticBitmap * m_rename_button{nullptr}; wxStaticBitmap* m_staticbitmap{ nullptr }; @@ -387,6 +389,8 @@ protected: CheckBox* m_check_ext_change_assist{ nullptr }; Label* m_label_ext_change_assist{ nullptr }; + Label* m_txt_warn_when_drying{ nullptr }; + PrinterInfoBox* m_printer_box { nullptr}; PrinterMsgPanel * m_text_printer_msg{nullptr}; Label* m_text_printer_msg_tips{ nullptr }; @@ -508,9 +512,43 @@ public: bool build_nozzles_info(std::string& nozzles_info); bool can_hybrid_mapping(DevExtderSystem data); void auto_supply_with_ext(std::vector<DevAmsTray> 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) const; + // Physical nozzle(s) a mapped filament (by filament index / FilamentInfo::id) prints on. + // key: nozzle pos id, value: nozzle. Used by the per-nozzle filament blacklist check loop. + std::map<int, DevNozzle> get_mapped_nozzles(int fila_id) const; + + // Short label of the physical nozzle(s) a filament prints on, shown on its send-dialog card: + // rack slots ("R1", "R2 R3") for a nozzle-rack printer, or "L"/"R"/"L R" for a filament-switcher + // printer. Empty for printers with neither (the card then shows no nozzle row). + wxString get_mapped_nozzle_str(int fila_id) const; + + // Block Send while a rack printer is still reading its hotend information. + bool CheckErrorRackStatus(MachineObject* obj_); + // Warn (without blocking) when the rack inventory looks insufficient for the sliced plate: + // fewer matching hotends than the plate needs, or matches relying on unreliable nozzle info. + void CheckWarningRackStatus(MachineObject* obj_); + // Compare the slicing file's nozzle requirements (validity, flow, diameter) against the + // printer; the rack extruder is checked against its whole inventory (mounted + rack). + bool CheckErrorExtruderNozzleWithSlicing(MachineObject* obj_);//return true if no errors + + // Rack print-dispatch nozzle mapping (H2C): request the printer's auto-mapping and consume the + // result, gating the Send button while the printer computes. Both are no-ops for non-rack printers. + bool CheckErrorSyncNozzleMappingResultV1(MachineObject* obj_); + bool CheckErrorSyncNozzleMappingResultV0(MachineObject* obj_); + void clear_nozzle_mapping(); + bool use_dynamic_nozzle_map() const; + + // Filament Track Switch: warn when the sliced switch state doesn't match the installed + // hardware, and (for dynamic nozzle mapping) block Send when the switch is missing or not + // set up. slicing_with_fila_switch() reports whether the file was sliced assuming a switch. + bool slicing_with_fila_switch() const; + bool CheckErrorDynamicSwitchNozzle(MachineObject* obj_); + void on_flow_cali_option_changed(); + + bool is_ams_drying(MachineObject* obj); + bool is_selected_ams_drying(MachineObject* obj); + PrintFromType get_print_type() {return m_print_type;}; wxString format_steel_name(NozzleType type); PrintDialogStatus get_status() { return m_print_status; } diff --git a/src/slic3r/GUI/Selection.cpp b/src/slic3r/GUI/Selection.cpp index b2caaed55d..5d6a545873 100644 --- a/src/slic3r/GUI/Selection.cpp +++ b/src/slic3r/GUI/Selection.cpp @@ -760,6 +760,9 @@ void Selection::clear() #endif // #et_FIXME fake KillFocus from sidebar + // Skip on shutdown: Plater's pImpl is already freed, so plater()->canvas3D() would use-after-free. + if (wxGetApp().is_closing()) + return; wxGetApp().plater()->canvas3D()->handle_sidebar_focus_event("", false); } diff --git a/src/slic3r/GUI/SendToPrinter.cpp b/src/slic3r/GUI/SendToPrinter.cpp index d478c37f8f..3241a1566c 100644 --- a/src/slic3r/GUI/SendToPrinter.cpp +++ b/src/slic3r/GUI/SendToPrinter.cpp @@ -412,7 +412,7 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater) sizer_error_code->Add(st_title_error_code_doc, 0, wxALL, 0); sizer_error_code->Add(m_st_txt_error_code, 0, wxALL, 0); - auto st_title_error_desc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Error desc")); + auto st_title_error_desc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, _L("Error desc")); auto st_title_error_desc_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": "); m_st_txt_error_desc = new Label(m_sw_print_failed_info, wxEmptyString); st_title_error_desc->SetForegroundColour(0x909090); @@ -429,7 +429,7 @@ SendToPrinterDialog::SendToPrinterDialog(Plater *plater) sizer_error_desc->Add(st_title_error_desc_doc, 0, wxALL, 0); sizer_error_desc->Add(m_st_txt_error_desc, 0, wxALL, 0); - auto st_title_extra_info = new wxStaticText(m_sw_print_failed_info, wxID_ANY, wxT("Extra info")); + auto st_title_extra_info = new wxStaticText(m_sw_print_failed_info, wxID_ANY, _L("Extra info")); auto st_title_extra_info_doc = new wxStaticText(m_sw_print_failed_info, wxID_ANY, ": "); m_st_txt_extra_info = new Label(m_sw_print_failed_info, wxEmptyString); st_title_extra_info->SetForegroundColour(0x909090); diff --git a/src/slic3r/GUI/StatusPanel.cpp b/src/slic3r/GUI/StatusPanel.cpp index 5cbf3e2a83..1bd564b5e1 100644 --- a/src/slic3r/GUI/StatusPanel.cpp +++ b/src/slic3r/GUI/StatusPanel.cpp @@ -34,6 +34,8 @@ #include "DeviceCore/DevManager.h" #include "DeviceCore/DevPrintTaskInfo.h" +#include "DeviceTab/wgtDeviceNozzleRack.h" + #include "PrintOptionsDialog.hpp" @@ -1611,13 +1613,26 @@ wxBoxSizer *StatusBasePanel::create_machine_control_page(wxWindow *parent) wxBoxSizer *bSizer_control = new wxBoxSizer(wxVERTICAL); auto temp_axis_ctrl_sizer = create_temp_axis_group(parent); - auto m_ams_ctrl_sizer = create_ams_group(parent); auto m_filament_load_sizer = create_filament_group(parent); + /* ams control box or live nozzle-rack panel (rack printers switch between the two) */ + wxSizer *ams_rack_sizer = new wxBoxSizer(wxHORIZONTAL); + ams_rack_sizer->Add(create_ams_group(parent), 0, wxEXPAND | wxLEFT); + + m_panel_nozzle_rack = new wgtDeviceNozzleRack(parent); + m_panel_nozzle_rack->Show(false); + ams_rack_sizer->Add(m_panel_nozzle_rack, 0, wxEXPAND | wxLEFT); + + m_ams_rack_switch = new SwitchBoard(parent, _L("Filament"), _L("Hotends"), wxSize(FromDIP(126), FromDIP(26))); + m_ams_rack_switch->updateState("left"); + m_ams_rack_switch->Hide(); + m_ams_rack_switch->Bind(wxCUSTOMEVT_SWITCH_POS, &StatusBasePanel::on_ams_rack_switch, this); + bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(8)); bSizer_control->Add(temp_axis_ctrl_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8)); + bSizer_control->Add(m_ams_rack_switch, 0, wxALIGN_CENTRE|wxTOP, FromDIP(6)); bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(6)); - bSizer_control->Add(m_ams_ctrl_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8)); + bSizer_control->Add(ams_rack_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8)); bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(6)); bSizer_control->Add(m_filament_load_sizer, 0, wxALIGN_CENTER|wxLEFT|wxRIGHT, FromDIP(8)); bSizer_control->Add(0, 0, 0, wxTOP, FromDIP(4)); @@ -2163,7 +2178,19 @@ void StatusBasePanel::expand_filament_loading(wxMouseEvent& e) else if (obj->is_series_o()) { const auto& ext_system = obj->GetExtderSystem(); - if (ext_system->GetTotalExtderCount() == 2) + // Prefer the config-driven filament-load image: H2C ships per-extruder bitmaps, and a printer + // fitted with an induction hotend rack picks the rack-specific set (filament_load_image_nozzle_rack). + // Printers whose profile carries no such key (e.g. H2D) get an empty name here and fall through to + // the generic O-series bitmaps below, so their monitor page stays byte-identical. Rack-driven, so + // there is no behavior change for any non-rack printer. + int cur_ext_id = (ext_system && ext_system->GetTotalExtderCount() > 1) ? ext_system->GetCurrentExtderId() : 0; + bool has_nozzle_rack = obj->GetNozzleSystem()->GetNozzleRack()->IsSupported(); + std::string img_name = DevPrinterConfigUtil::get_filament_load_img(obj->printer_type, cur_ext_id, has_nozzle_rack); + if (!img_name.empty()) + { + m_filament_load_img->SetBitmap(create_scaled_bitmap(img_name, this, load_img_size)); + } + else if (ext_system->GetTotalExtderCount() == 2) { int cur_extder_id = ext_system->GetCurrentExtderId(); if (cur_extder_id == MAIN_EXTRUDER_ID) @@ -2202,6 +2229,10 @@ void StatusBasePanel::show_ams_group(bool show) wxGetApp().mainframe->m_monitor->Layout(); } + // On rack printers, don't clobber the rack view when the user has the switch on "Hotends". + // Inert for every non-rack printer: the switch stays hidden, so this guard never triggers. + if (show && m_ams_rack_switch->IsShown() && (m_ams_rack_switch->switch_left != true)) { return; } + if (m_ams_control_box->IsShown() != show) { m_ams_control_box->Show(show); m_ams_control->Layout(); @@ -2227,7 +2258,7 @@ void StatusBasePanel::show_filament_load_group(bool show) } auto cur_ext = obj->GetExtderSystem()->GetCurrentExtder(); - m_filament_step->SetupSteps(cur_ext ? cur_ext->HasFilamentInExt() : false); + m_filament_step->SetupSteps(obj, cur_ext ? cur_ext->HasFilamentInExt() : false); Layout(); Fit(); @@ -2237,6 +2268,31 @@ void StatusBasePanel::show_filament_load_group(bool show) } } +void StatusBasePanel::jump_to_Rack() +{ + if (obj && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported()) { + m_ams_rack_switch->updateState("right"); + m_ams_control_box->Show(false); + m_panel_nozzle_rack->Show(true); + Layout(); + } +} + +void StatusBasePanel::on_ams_rack_switch(wxCommandEvent &e) +{ + if (!m_ams_control_box->IsShown() && e.GetInt() == 1) { + m_ams_control_box->Show(e.GetInt() == 1); + m_panel_nozzle_rack->Show(e.GetInt() == 0); + Layout(); + } else if (!m_panel_nozzle_rack->IsShown() && e.GetInt() == 0) { + m_ams_control_box->Show(e.GetInt() == 1); + m_panel_nozzle_rack->Show(e.GetInt() == 0); + Layout(); + } + + e.Skip(); +} + void StatusPanel::update_camera_state(MachineObject* obj) { if (!obj) return; @@ -2778,6 +2834,8 @@ void StatusPanel::update(MachineObject *obj) update_ams(obj); update_cali(obj); + update_rack(obj); + if (obj) { //nozzle ui //m_button_left_of_extruder->SetSelected(); @@ -3334,6 +3392,7 @@ void StatusPanel::update_ams(MachineObject *obj) // must select a current can m_ams_control->UpdateAms(obj->get_printer_series_str(), obj->printer_type, ams_info, ext_info, *obj->GetExtderSystem(), obj->get_dev_id(), false); + m_ams_control->UpdateAmsDryControl(obj); last_tray_exist_bits = obj->tray_exist_bits; last_ams_exist_bits = obj->ams_exist_bits; @@ -3412,7 +3471,14 @@ void StatusPanel::update_ams(MachineObject *obj) int tray_id_int = atoi(tray_id.c_str()); // new protocol if (ams_id_int < 128) { - if ((obj->tray_reading_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0) { + if (ams_it->second->IsAmsLiteMixed()) { + // Mixed AMS-Lite (A2L / N9) RFID-reading bits occupy positions 24..27. + if ((obj->tray_reading_bits & (1 << (AMS_LITE_MIXED_TRAY_INDEX_OFFSET + tray_id_int))) != 0) { + m_ams_control->PlayRridLoading(ams_id, tray_id); + } else { + m_ams_control->StopRridLoading(ams_id, tray_id); + } + } else if ((obj->tray_reading_bits & (1 << (ams_id_int * 4 + tray_id_int))) != 0) { m_ams_control->PlayRridLoading(ams_id, tray_id); } else { m_ams_control->StopRridLoading(ams_id, tray_id); @@ -3461,6 +3527,14 @@ void StatusPanel::update_ams_control_state(std::string ams_id, std::string slot_ if (ams_id.empty() || slot_id.empty()) { load_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament."); unload_error_info = _L("Choose an AMS slot then press \"Load\" or \"Unload\" button to automatically load or unload filament."); + } else if (obj->GetFilaSwitch()->IsInstalled() && devPrinterUtil::IsVirtualSlot(ams_id)) { + // Orca: with a Filament Track Switch installed the external spool cannot be routed, so both actions are blocked. + load_error_info = _L("\"Load\" or \"Unload\" is not supported for external spool while using Filament Track Switch."); + unload_error_info = load_error_info; + } else if (obj->GetFilaSwitch()->IsInstalled() && !obj->GetFilaSwitch()->IsReady()) { + // Orca: an un-calibrated Filament Track Switch cannot route filament to either extruder, so block both actions. + load_error_info = _L("The Filament Track Switch has not been setup. Please setup on printer."); + unload_error_info = load_error_info; } else if (ams_id == std::to_string(VIRTUAL_TRAY_MAIN_ID) || ams_id == std::to_string(VIRTUAL_TRAY_DEPUTY_ID)) { for (auto ext : obj->GetExtderSystem()->GetExtruders()) { if (ext.GetSlotNow().ams_id == ams_id && ext.GetSlotNow().slot_id == slot_id) @@ -3470,6 +3544,8 @@ void StatusPanel::update_ams_control_state(std::string ams_id, std::string slot_ } } else { for (auto ext : obj->GetExtderSystem()->GetExtruders()) { + // Orca: with a Filament Track Switch installed a slot is not bound to a single extruder, so skip the "already loaded" identity check. + if (obj->GetFilaSwitch()->IsInstalled()) { continue; } if (ext.GetSlotNow().ams_id == ams_id && ext.GetSlotNow().slot_id == slot_id) { load_error_info = _L("Current slot has already been loaded."); @@ -4166,6 +4242,43 @@ void StatusPanel::on_ams_load_curr() std::string curr_ams_id = m_ams_control->GetCurentAms(); std::string curr_can_id = m_ams_control->GetCurrentCan(curr_ams_id); + std::optional<int> extruder_id = std::nullopt; + if (obj->GetFilaSwitch() && obj->GetFilaSwitch()->IsInstalled()) { + if (!obj->GetFilaSwitch()->IsReady()) { + MessageDialog msg_dlg(nullptr, _L("The Filament Track Switch has not been setup. Please setup on printer."), wxEmptyString, wxICON_WARNING | wxOK); + msg_dlg.ShowModal(); + return; + } + + // Filament Track Switch is calibrated: the load can go to either extruder, so ask the + // user which. Record each extruder's currently-loaded slot so the dialog can grey out a + // side that already holds this filament. + std::vector<std::pair<std::string, std::string>> extruderSlots(2, {"", ""}); + if (auto ext = obj->GetExtderSystem()->GetExtderById(MAIN_EXTRUDER_ID); ext.has_value()) + { + if (ext->HasFilamentInExt()) + { + extruderSlots[MAIN_EXTRUDER_ID] = {ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id}; + } + } + if (auto ext = obj->GetExtderSystem()->GetExtderById(DEPUTY_EXTRUDER_ID); ext.has_value()) + { + if (ext->HasFilamentInExt()) + { + extruderSlots[DEPUTY_EXTRUDER_ID] = {ext->GetSlotNow().ams_id, ext->GetSlotNow().slot_id}; + } + } + + FeedDirectionDialog dialog(nullptr, 2, obj->printer_type); + dialog.SetExtruderMapping(obj, curr_ams_id, curr_can_id, extruderSlots); + auto rtn = dialog.ShowModal(); + + if (rtn != wxID_OK) + { + return; + } + extruder_id = dialog.GetExtruderID(); + } update_load_with_temp(); //virtual tray @@ -4197,11 +4310,11 @@ void StatusPanel::on_ams_load_curr() if (obj->is_enable_np || obj->is_enable_ams_np) { try { if (!curr_ams_id.empty() && !curr_can_id.empty()) { - obj->command_ams_change_filament(true, curr_ams_id, "0", old_temp, new_temp); + obj->command_ams_change_filament(true, curr_ams_id, "0", old_temp, new_temp, extruder_id); } } catch (...) {} } else { - obj->command_ams_change_filament(true, "254", "0", old_temp, new_temp); + obj->command_ams_change_filament(true, "254", "0", old_temp, new_temp, extruder_id); } } @@ -4237,12 +4350,12 @@ void StatusPanel::on_ams_load_curr() if (obj->is_enable_np) { try { if (!curr_ams_id.empty() && !curr_can_id.empty()) { - obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp); + obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp, extruder_id); } } catch (...){} } else { - obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp); + obj->command_ams_change_filament(true, curr_ams_id, curr_can_id, old_temp, new_temp, extruder_id); } } } @@ -5085,6 +5198,9 @@ void StatusPanel::set_default() m_ams_control->Hide(); m_ams_control_box->Hide(); m_ams_control->Reset(); + m_ams_rack_switch->updateState("left"); + m_ams_rack_switch->Hide(); + m_panel_nozzle_rack->Hide(); m_scale_panel->Hide(); m_filament_load_box->Hide(); m_filament_step->Hide(); @@ -5262,6 +5378,7 @@ void StatusPanel::msw_rescale() m_extruder_switching_status->msw_rescale(); m_ams_control->msw_rescale(); + m_panel_nozzle_rack->Rescale(); // m_filament_step->Rescale(); @@ -5283,6 +5400,20 @@ void StatusPanel::msw_rescale() Refresh(); } +void StatusPanel::update_rack(MachineObject *obj) +{ + // Rack switch + live rack panel are shown only for printers whose nozzle system reports a rack + // (H2C). Every other Bambu printer keeps the switch hidden and the panel collapsed -> the AMS + // monitor page is unchanged for X1/P1/A1/H2D/H2S. + if (obj && obj->GetNozzleSystem()->GetNozzleRack()->IsSupported()) { + m_ams_rack_switch->Show(); + m_panel_nozzle_rack->UpdateRackInfo(obj->GetNozzleSystem()->GetNozzleRack()); + } else { + m_ams_rack_switch->Show(false); + m_panel_nozzle_rack->Show(false); + } +} + void StatusPanel::update_filament_loading_panel(MachineObject* obj) { if (!obj) { @@ -5722,7 +5853,7 @@ wxBoxSizer *ScoreDialog::get_photo_btn_sizer() { m_add_photo->Bind(wxEVT_LEFT_DOWN, [this](auto &e) { // add photo logic - wxFileDialog openFileDialog(this, "Select Images", "", "", "Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg", wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE); + wxFileDialog openFileDialog(this, _L("Select Images"), "", "", _L("Image files (*.png;*.jpg;*jpeg)|*.png;*.jpg;*.jpeg"), wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE); if (openFileDialog.ShowModal() == wxID_CANCEL) return; diff --git a/src/slic3r/GUI/StatusPanel.hpp b/src/slic3r/GUI/StatusPanel.hpp index 8065f198e4..d286add1b0 100644 --- a/src/slic3r/GUI/StatusPanel.hpp +++ b/src/slic3r/GUI/StatusPanel.hpp @@ -50,6 +50,7 @@ namespace GUI { // Previous definitions class MessageDialog; +class wgtDeviceNozzleRack; enum CameraRecordingStatus { RECORDING_NONE, @@ -518,11 +519,16 @@ protected: bool m_show_ams_group{false}; bool m_show_filament_group{ false }; + /* AMS control box <-> live nozzle-rack panel toggle (rack printers only) */ + SwitchBoard* m_ams_rack_switch{ nullptr }; + AMSControl* m_ams_control; StaticBox* m_ams_control_box; wxStaticBitmap *m_ams_extruder_img; wxStaticBitmap* m_bitmap_extruder_img; + wgtDeviceNozzleRack* m_panel_nozzle_rack{ nullptr }; + wxPanel * m_panel_separator_right; wxPanel * m_panel_separotor_bottom; wxGridBagSizer *m_tasklist_info_sizer{nullptr}; @@ -611,6 +617,11 @@ public: void show_ams_group(bool show = true); void show_filament_load_group(bool show = true); MediaPlayCtrl* get_media_play_ctrl() {return m_media_play_ctrl;}; + + void jump_to_Rack(); + +private: + void on_ams_rack_switch(wxCommandEvent& event); }; @@ -767,6 +778,7 @@ protected: void update_temp_ctrl(MachineObject *obj); void update_misc_ctrl(MachineObject *obj); void update_ams(MachineObject* obj); + void update_rack(MachineObject* obj); void update_filament_loading_panel(MachineObject* obj); void update_extruder_status(MachineObject* obj); diff --git a/src/slic3r/GUI/StepMeshDialog.cpp b/src/slic3r/GUI/StepMeshDialog.cpp index 33e1c4914a..cd0f4bd423 100644 --- a/src/slic3r/GUI/StepMeshDialog.cpp +++ b/src/slic3r/GUI/StepMeshDialog.cpp @@ -30,7 +30,7 @@ static int _ITEM_WIDTH() { return _scale(30); } #define SLIDER_SCALE_10(val) ((val) / 0.01) #define SLIDER_UNSCALE_10(val) ((val) * 0.01) #define LEFT_RIGHT_PADING FromDIP(20) -#define FONT_COLOR wxColour("#262E30") +#define FONT_COLOR wxColour("#363636") // label color wxDEFINE_EVENT(wxEVT_THREAD_DONE, wxCommandEvent); diff --git a/src/slic3r/GUI/SyncAmsInfoDialog.cpp b/src/slic3r/GUI/SyncAmsInfoDialog.cpp index 535c561b55..704fa9ec2a 100644 --- a/src/slic3r/GUI/SyncAmsInfoDialog.cpp +++ b/src/slic3r/GUI/SyncAmsInfoDialog.cpp @@ -19,6 +19,7 @@ #include "Widgets/Label.hpp" #include "Widgets/Button.hpp" #include "Widgets/CheckBox.hpp" +#include "Widgets/DialogButtons.hpp" #include "CapsuleButton.hpp" #include "PrePrintChecker.hpp" @@ -37,7 +38,7 @@ using namespace Slic3r::GUI; #define SyncAmsInfoDialogWidth FromDIP(675) #define SyncAmsInfoDialogHeightMIN FromDIP(620) #define SyncAmsInfoDialogHeightMIDDLE FromDIP(630) -#define SyncAmsInfoDialogHeightMAX FromDIP(660) +#define SyncAmsInfoDialogHeightMAX FromDIP(700) #define SyncLabelWidth FromDIP(640) #define SyncAttentionTipWidth FromDIP(550) namespace Slic3r { namespace GUI { @@ -282,14 +283,14 @@ wxBoxSizer *SyncAmsInfoDialog::create_sizer_thumbnail(wxButton *image_button, bo if (left) { wxBoxSizer *text_sizer = new wxBoxSizer(wxHORIZONTAL); auto sync_text = new Label(image_button->GetParent(), _CTX(L_CONTEXT("Original", "Sync_AMS"), "Sync_AMS")); - sync_text->SetForegroundColour(wxColour(107, 107, 107, 100)); + sync_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors text_sizer->Add(sync_text, 0, wxALIGN_CENTER | wxALL, 0); sizer_thumbnail->Add(sync_text, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(4)); } else { wxBoxSizer *text_sizer = new wxBoxSizer(wxHORIZONTAL); m_after_map_text = new Label(image_button->GetParent(), _L("After mapping")); - m_after_map_text->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_after_map_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors text_sizer->Add(m_after_map_text, 0, wxALIGN_CENTER | wxALL, 0); sizer_thumbnail->Add(m_after_map_text, FromDIP(0), wxALIGN_CENTER | wxALL, FromDIP(4)); } @@ -655,10 +656,6 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : // font SetFont(wxGetApp().normal_font()); - // icon - std::string icon_path = (boost::format("%1%/images/OrcaSlicerTitle.ico") % resources_dir()).str(); - SetIcon(wxIcon(encode_path(icon_path.c_str()), wxBITMAP_TYPE_ICO)); - Freeze(); SetBackgroundColour(m_colour_def_color); @@ -733,7 +730,7 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_colormap_btn->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::update_when_change_map_mode,this); // update_when_change_map_mode(e.GetSelection()); m_override_btn->Bind(wxEVT_BUTTON, &SyncAmsInfoDialog::update_when_change_map_mode,this); - bSizer->Add(m_mode_combox_sizer, FromDIP(0), wxEXPAND | wxTOP, FromDIP(10)); + bSizer->Add(m_mode_combox_sizer, FromDIP(0), wxEXPAND | wxTOP | wxBOTTOM, FromDIP(10)); } m_basic_panel = new wxPanel(m_scrolledWindow, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL); @@ -847,8 +844,8 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : sizer_advanced_options_title = new wxBoxSizer(wxHORIZONTAL); auto advanced_options_title = new Label(m_scrolledWindow, _L("Advanced Options")); - advanced_options_title->SetFont(::Label::Body_13); - advanced_options_title->SetForegroundColour(wxColour(38, 46, 48)); + advanced_options_title->SetFont(::Label::Head_14); // ORCA + advanced_options_title->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors sizer_advanced_options_title->Add(0, 0, 1, wxEXPAND, 0); sizer_advanced_options_title->Add(advanced_options_title, 0, wxALIGN_CENTER, 0); @@ -914,13 +911,15 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : {//new content//tip confirm ok button wxBoxSizer *tip_sizer = new wxBoxSizer(wxHORIZONTAL); m_attention_text = new wxStaticText(m_scrolledWindow, wxID_ANY, _L("Tip") + ": "); + m_attention_text->SetFont(::Label::Head_14); + m_attention_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#009688"))); // ORCA match label colors tip_sizer->Add(m_attention_text, 0, wxALIGN_LEFT | wxTOP, FromDIP(2)); m_tip_attention_color_map = _L("Only synchronize filament type and color, not including AMS slot information."); m_tip_attention_override = _L("Replace the project filaments list sequentially based on printer filaments. And unused printer filaments will be automatically added to the end of the list."); m_tip_text = new Label(m_scrolledWindow, m_tip_attention_color_map, LB_AUTO_WRAP); m_tip_text->SetMinSize(wxSize(SyncAttentionTipWidth, -1)); m_tip_text->SetMaxSize(wxSize(SyncAttentionTipWidth, -1)); - m_tip_text->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_tip_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors tip_sizer->Add(m_tip_text, 0, wxALIGN_LEFT | wxTOP, FromDIP(2)); tip_sizer->AddSpacer(FromDIP(20)); bSizer->Add(tip_sizer, 0, wxEXPAND | wxLEFT, FromDIP(25)); @@ -931,7 +930,8 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_advace_setting_sizer = new wxBoxSizer(wxHORIZONTAL); m_more_setting_tips = new wxStaticText(m_scrolledWindow, wxID_ANY, _L("Advanced settings")); - m_more_setting_tips->SetForegroundColour(wxColour(0, 137, 123)); + m_more_setting_tips->SetFont(::Label::Head_14); // ORCA + m_more_setting_tips->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_more_setting_tips->Bind(wxEVT_LEFT_DOWN, [this](wxMouseEvent &e) { m_expand_more_settings = !m_expand_more_settings; update_more_setting(true,true); @@ -959,6 +959,7 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_append_color_sizer->Add(m_append_color_checkbox, 0, wxALIGN_LEFT | wxTOP, FromDIP(4)); const int gap_between_checebox_and_text = 2; m_append_color_text = new Label(m_scrolledWindow, _L("Add unused AMS filaments to filaments list.")); + m_append_color_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_append_color_text->Hide(); m_append_color_sizer->AddSpacer(FromDIP(gap_between_checebox_and_text)); m_append_color_sizer->Add(m_append_color_text, 0, wxALIGN_LEFT | wxTOP, FromDIP(4)); @@ -981,6 +982,7 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_merge_color_text = new Label(m_scrolledWindow, _L("Automatically merge the same colors in the model after mapping.")); + m_merge_color_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_merge_color_text->Hide(); m_merge_color_sizer->AddSpacer(FromDIP(gap_between_checebox_and_text)); m_merge_color_sizer->Add(m_merge_color_text, 0, wxALIGN_LEFT | wxTOP, FromDIP(2)); @@ -994,17 +996,19 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_override_undone_str = _L("After being synced, this action cannot be undone."); m_undone_str = _L("After being synced, the project's filament presets and colors will be replaced with the mapped filament types and colors. This action cannot be undone."); m_confirm_title = new Label(m_scrolledWindow, m_undone_str, LB_AUTO_WRAP); + m_confirm_title->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_confirm_title->SetMinSize(wxSize(SyncLabelWidth, -1)); m_confirm_title->SetMaxSize(wxSize(SyncLabelWidth, -1)); - confirm_boxsizer->Add(m_confirm_title, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxTOP | wxRIGHT, FromDIP(10)); + confirm_boxsizer->Add(m_confirm_title, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL | wxTOP | wxRIGHT | wxBOTTOM, FromDIP(10)); m_are_you_sure_title = new wxStaticText(m_scrolledWindow, wxID_ANY, _L("Are you sure to synchronize the filaments?")); + m_are_you_sure_title->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors //m_are_you_sure_title->SetFont(Label::Head_14); confirm_boxsizer->Add(m_are_you_sure_title, 0, wxALIGN_LEFT | wxTOP, FromDIP(0)); bSizer->Add(confirm_boxsizer, 0, wxALIGN_LEFT | wxLEFT , FromDIP(25)); wxBoxSizer *warning_sizer = new wxBoxSizer(wxHORIZONTAL); m_warning_text = new wxStaticText(m_scrolledWindow, wxID_ANY, _L("Error") + ":"); - m_warning_text->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_warning_text->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_warning_text->Hide(); warning_sizer->Add(m_warning_text, 0, wxALIGN_CENTER | wxTOP, FromDIP(2)); bSizer->Add(warning_sizer, 0, wxEXPAND | wxLEFT, FromDIP(25)); @@ -1012,46 +1016,22 @@ SyncAmsInfoDialog::SyncAmsInfoDialog(wxWindow *parent, SyncInfo &info) : m_scrolledWindow->SetSizerAndFit(m_sizer_main); m_sizer_show_page->Add(m_scrolledWindow, 1, wxEXPAND, 0); - wxBoxSizer *bSizer_button = new wxBoxSizer(wxHORIZONTAL); - bSizer_button->SetMinSize(wxSize(FromDIP(100), -1)); - /* m_checkbox = new wxCheckBox(this, wxID_ANY, _L("Don't show again"), wxDefaultPosition, wxDefaultSize, 0); - bSizer_button->Add(m_checkbox, 0, wxALIGN_LEFT);*/ - bSizer_button->AddStretchSpacer(1); - StateColor btn_bg_green(std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed), std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered), - std::pair<wxColour, int>(AMS_CONTROL_BRAND_COLOUR, StateColor::Normal)); - m_button_ok = new Button(m_show_page, _L("Synchronize now")); - m_button_ok->SetBackgroundColor(btn_bg_green); - m_button_ok->SetBorderColor(*wxWHITE); - m_button_ok->SetTextColor(wxColour("#FFFFFE")); - m_button_ok->SetFont(Label::Body_12); - m_button_ok->SetSize(OK_BUTTON_SIZE); - m_button_ok->SetMinSize(OK_BUTTON_SIZE); - m_button_ok->SetCornerRadius(FromDIP(12)); - bSizer_button->Add(m_button_ok, 0, wxALIGN_RIGHT | wxLEFT | wxTOP, FromDIP(10)); - + auto* dlg_btns = new DialogButtons(m_show_page, {"OK", "Cancel"}); + m_button_ok = dlg_btns->GetOK(); + m_button_ok->SetLabel(_L("Synchronize now")); m_button_ok->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent &e) { deal_ok(); EndModal(wxID_YES); SetFocusIgnoringChildren(); }); - StateColor btn_bg_white(std::pair<wxColour, int>(wxColour(206, 206, 206), StateColor::Pressed), std::pair<wxColour, int>(wxColour(238, 238, 238), StateColor::Hovered), - std::pair<wxColour, int>(*wxWHITE, StateColor::Normal)); - - m_button_cancel = new Button(m_show_page, m_input_info.cancel_text_to_later ? _L("Later") : _L("Cancel")); - m_button_cancel->SetBackgroundColor(btn_bg_white); - m_button_cancel->SetBorderColor(wxColour(38, 46, 48)); - m_button_cancel->SetFont(Label::Body_12); - m_button_cancel->SetSize(CANCEL_BUTTON_SIZE); - m_button_cancel->SetMinSize(CANCEL_BUTTON_SIZE); - m_button_cancel->SetCornerRadius(FromDIP(12)); - bSizer_button->Add(m_button_cancel, 0, wxALIGN_RIGHT | wxLEFT | wxTOP, FromDIP(10)); - + m_button_cancel = dlg_btns->GetCANCEL(); + m_button_cancel->SetLabel(m_input_info.cancel_text_to_later ? _L("Later") : _L("Cancel")); m_button_cancel->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [this](wxCommandEvent &e) { EndModal(wxID_CANCEL); }); - m_sizer_show_page->Add(bSizer_button, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, FromDIP(20)); + m_sizer_show_page->Add(dlg_btns, 0, wxEXPAND); m_show_page->SetSizer(m_sizer_show_page); } show_print_failed_info(false); @@ -1547,6 +1527,8 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err NozzleVolumeType nozzle_volume_type = (NozzleVolumeType) (nozzle_volume_type_opt->get_at(used_extruders[i])); if (nozzle_volume_type == NozzleVolumeType::nvtStandard) { used_extruders_flow[used_extruders[i]] = "Standard"; + } else if (nozzle_volume_type == NozzleVolumeType::nvtTPUHighFlow) { + used_extruders_flow[used_extruders[i]] = "TPU High Flow"; } else { used_extruders_flow[used_extruders[i]] = "High Flow"; } @@ -1562,6 +1544,8 @@ bool SyncAmsInfoDialog::is_nozzle_type_match(DevExtderSystem data, wxString &err flow_type_of_machine.push_back("High Flow"); } else if (it->GetNozzleFlowType() == NozzleFlowType::S_FLOW) { flow_type_of_machine.push_back("Standard"); + } else if (it->GetNozzleFlowType() == NozzleFlowType::U_FLOW) { + flow_type_of_machine.push_back("TPU High Flow"); } } @@ -2480,10 +2464,10 @@ void SyncAmsInfoDialog::on_dpi_changed(const wxRect &suggested_rect) } m_swipe_left_button->msw_rescale(); m_swipe_right_button->msw_rescale(); - m_button_ok->SetMinSize(OK_BUTTON_SIZE); - m_button_ok->SetCornerRadius(FromDIP(12)); - m_button_cancel->SetMinSize(CANCEL_BUTTON_SIZE); - m_button_cancel->SetCornerRadius(FromDIP(12)); + //m_button_ok->SetMinSize(OK_BUTTON_SIZE); // ORCA DialogButtons automatically manages style and size + //m_button_ok->SetCornerRadius(FromDIP(12)); + //m_button_cancel->SetMinSize(CANCEL_BUTTON_SIZE); + //m_button_cancel->SetCornerRadius(FromDIP(12)); m_merge_color_checkbox->Rescale(); m_append_color_checkbox->Rescale(); m_combobox_plate->Rescale(); @@ -2628,14 +2612,14 @@ void SyncAmsInfoDialog::reset_and_sync_ams_list() is_first_row = false; if (!m_original_in_colormap) { m_original_in_colormap = new wxStaticText(m_filament_panel, wxID_ANY, _CTX(L_CONTEXT("Original", "Sync_AMS"), "Sync_AMS") + ":"); - m_original_in_colormap->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_original_in_colormap->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_original_in_colormap->SetFont(::Label::Head_12); } ams_tip_sizer->Add(m_original_in_colormap, 0, wxALIGN_LEFT | wxTOP, FromDIP(6)); if (!m_ams_or_ext_text_in_colormap) { m_ams_or_ext_text_in_colormap = new wxStaticText(m_filament_panel, wxID_ANY, _L("AMS") + ":"); - m_ams_or_ext_text_in_colormap->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_ams_or_ext_text_in_colormap->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_ams_or_ext_text_in_colormap->SetFont(::Label::Head_12); } ams_tip_sizer->Add(m_ams_or_ext_text_in_colormap, 0, wxALIGN_LEFT | wxTOP, FromDIP(9)); @@ -2840,7 +2824,7 @@ void SyncAmsInfoDialog::generate_override_fix_ams_list() is_first_row = false; if (!m_original_in_override) { m_original_in_override = new wxStaticText(m_fix_filament_panel, wxID_ANY, _CTX(L_CONTEXT("Original", "Sync_AMS"), "Sync_AMS") + ":"); - m_original_in_override->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_original_in_override->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_original_in_override->SetFont(::Label::Head_12); } ams_tip_sizer->Add(m_original_in_override, 0, wxALIGN_LEFT | wxTOP, FromDIP(6)); @@ -2848,7 +2832,7 @@ void SyncAmsInfoDialog::generate_override_fix_ams_list() if (!m_ams_or_ext_text_in_override) { auto text = (m_only_exist_ext_spool_flag ? _L("Ext spool") : _L("AMS")) + ":"; m_ams_or_ext_text_in_override = new wxStaticText(m_fix_filament_panel, wxID_ANY, text); - m_ams_or_ext_text_in_override->SetForegroundColour(wxColour(107, 107, 107, 100)); + m_ams_or_ext_text_in_override->SetForegroundColour(StateColor::darkModeColorFor(wxColour("#363636"))); // ORCA match label colors m_ams_or_ext_text_in_override->SetFont(::Label::Head_12); } ams_tip_sizer->Add(m_ams_or_ext_text_in_override, 0, wxALIGN_LEFT | wxTOP, FromDIP(9)); @@ -3236,10 +3220,12 @@ SyncNozzleAndAmsDialog::SyncNozzleAndAmsDialog(InputInfo &input_info) wxGetApp().preset_bundle->get_printer_extruder_count() == 1 ? 370 :320, input_info.dialog_pos, 90, + ( wxGetApp().preset_bundle->get_printer_extruder_count() == 1 ? _L("Successfully synchronized nozzle information.") : - _L("Successfully synchronized nozzle and AMS number information."), - _L("Continue to sync filaments"), - _CTX(L_CONTEXT("Cancel", "Sync_Nozzle_AMS"), "Sync_Nozzle_AMS"), + _L("Successfully synchronized nozzle and AMS number information.") + ) + "\n\n" + _L("Do you want to continue to sync filaments?"), + _L("Yes"), // ORCA use shorter text for buttons + _CTX(L_CONTEXT(_L("No"), "Sync_Nozzle_AMS"), "Sync_Nozzle_AMS"), DisappearanceMode::TimedDisappearance) , m_input_info(input_info) { diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index 52537d9331..5410d663f2 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -46,6 +46,7 @@ #include "Widgets/ComboBox.hpp" #include "Widgets/Label.hpp" +#include "Widgets/MultiNozzleSync.hpp" #include "Widgets/SwitchButton.hpp" #include "Widgets/TabCtrl.hpp" #include "Widgets/ComboBox.hpp" @@ -616,26 +617,25 @@ void Tab::parse_extruder_selection(int selection, int &extruder_id, NozzleVolume for (int i = 0; i < extruder_nums; ++i) { NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]); - // TODO: Orca: Support hybrid - //if (volume_type == NozzleVolumeType::nvtHybrid) { - // if (selection == current_index) { - // extruder_id = i; - // nozzle_type = NozzleVolumeType::nvtStandard; - // return; - // } else if (selection == current_index + 1) { - // extruder_id = i; - // nozzle_type = NozzleVolumeType::nvtHighFlow; - // return; - // } - // current_index += 2; - //} else { + if (volume_type == NozzleVolumeType::nvtHybrid) { + if (selection == current_index) { + extruder_id = i; + nozzle_type = NozzleVolumeType::nvtStandard; + return; + } else if (selection == current_index + 1) { + extruder_id = i; + nozzle_type = NozzleVolumeType::nvtHighFlow; + return; + } + current_index += 2; + } else { if (selection == current_index) { extruder_id = i; nozzle_type = volume_type; return; } current_index += 1; - //} + } } extruder_id = 0; @@ -651,17 +651,16 @@ int Tab::calculate_selection_index_for_extruder(int extruder_id, NozzleVolumeTyp for (int i = 0; i < extruder_nums; ++i) { if (i == extruder_id) { - // TODO: Orca: Support hybrid NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]); - /*if (volume_type == NozzleVolumeType::nvtHybrid) { + if (volume_type == NozzleVolumeType::nvtHybrid) { return nozzle_type == NozzleVolumeType::nvtHighFlow ? index + 1 : index; - } else*/ { + } else { return index; } } NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]); - index += /*(volume_type == NozzleVolumeType::nvtHybrid) ? 2 :*/ 1; + index += (volume_type == NozzleVolumeType::nvtHybrid) ? 2 : 1; } return 0; @@ -1184,7 +1183,7 @@ void Tab::update_extruder_switch_colors() void Tab::check_extruder_options_status(int index, bool &sys_extruder, bool &modified_extruder, const std::vector<PageShp>& pages_to_check) { int config_index = index; - if (m_type == Preset::TYPE_PRINT || m_type == Preset::TYPE_PRINTER) { + if (m_type == Preset::TYPE_PRINT || m_type == Preset::TYPE_PRINTER || m_type == Preset::TYPE_MODEL) { int extruder_id; NozzleVolumeType nozzle_type; parse_extruder_selection(index, extruder_id, nozzle_type); @@ -1773,6 +1772,10 @@ static wxString pad_combo_value_for_config(const DynamicPrintConfig &config) void Tab::on_value_change(const std::string& opt_key, const boost::any& value) { + // Orca: + // TODO: Move filament-specific checks to TabFilament::on_value_change() + // TODO: Move printer-specific checks to TabPrinter::on_value_change() + if (wxGetApp().plater() == nullptr) { return; } @@ -1847,6 +1850,27 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) if (opt_key == "enable_prime_tower") { auto timelapse_type = m_config->option<ConfigOptionEnum<TimelapseType>>("timelapse_type"); bool timelapse_enabled = timelapse_type->value == TimelapseType::tlSmooth; + if (!boost::any_cast<bool>(value)) { + // Disabling the prime tower on a multi-nozzle printer degrades quality because nozzle changes rely + // on it. Gate on any extruder having extruder_max_nozzle_count > 1 so single-nozzle and dual-extruder + // (H2D, {1,1}) printers keep their exact existing behavior. + // Orca: gate on any_of(count > 1) rather than the sum of counts >= 2. The sum form would also fire for + // H2D ({1,1} sums to 2); any_of(>1) preserves H2D's current no-dialog behavior. + auto *max_nozzle_counts_opt = wxGetApp().preset_bundle->printers.get_edited_preset().config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + const bool has_multiple_nozzle = max_nozzle_counts_opt && + std::any_of(max_nozzle_counts_opt->values.begin(), max_nozzle_counts_opt->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); }); + if (has_multiple_nozzle) { + MessageDialog dlg(wxGetApp().plater(), + _L("Prime tower is required for nozzle changing. There may be flaws on the model without prime tower. Are you sure you want to disable prime tower?"), + _L("Warning"), wxICON_WARNING | wxYES | wxNO); + if (dlg.ShowModal() == wxID_NO) { + DynamicPrintConfig new_conf = *m_config; + new_conf.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); + m_config_manipulation.apply(m_config, &new_conf); + } + } + } if (!boost::any_cast<bool>(value) && timelapse_enabled) { bool set_enable_prime_tower = false; MessageDialog dlg(wxGetApp().plater(), _L("A prime tower is required for smooth timelapse mode. There may be flaws on the model without a prime tower. Are you sure you want to disable the prime tower\?"), @@ -2658,7 +2682,7 @@ void TabPrint::build() optgroup->append_single_option_line("ironing_angle", "quality_settings_ironing#angle-offset"); optgroup->append_single_option_line("ironing_angle_fixed", "quality_settings_ironing#fixed-angle"); - optgroup = page->new_optgroup(L("Z contouring"), L"param_advanced"); + optgroup = page->new_optgroup(L("Z contouring"), L"param_z_contouring"); 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"); @@ -2742,12 +2766,18 @@ void TabPrint::build() optgroup->append_single_option_line("top_shell_thickness", "strength_settings_top_bottom_shells#shell-thickness"); optgroup->append_single_option_line("top_surface_density", "strength_settings_top_bottom_shells#surface-density"); optgroup->append_single_option_line("top_surface_pattern", "strength_settings_top_bottom_shells#surface-pattern"); - optgroup->append_single_option_line("top_layer_direction", "strength_settings_infill#top-direction"); + optgroup->append_single_option_line("top_surface_fill_order", "strength_settings_top_bottom_shells#fill-order"); + optgroup->append_single_option_line("top_layer_direction", "strength_settings_infill#top-bottom-direction"); + optgroup->append_single_option_line("top_surface_expansion", "strength_settings_top_bottom_shells#surface-expansion"); + optgroup->append_single_option_line("top_surface_expansion_margin", "strength_settings_top_bottom_shells#surface-expansion-margin"); + optgroup->append_single_option_line("top_surface_expansion_direction", "strength_settings_top_bottom_shells#surface-expansion-direction"); optgroup->append_single_option_line("bottom_shell_layers", "strength_settings_top_bottom_shells#shell-layers"); optgroup->append_single_option_line("bottom_shell_thickness", "strength_settings_top_bottom_shells#shell-thickness"); optgroup->append_single_option_line("bottom_surface_density", "strength_settings_top_bottom_shells#surface-density"); optgroup->append_single_option_line("bottom_surface_pattern", "strength_settings_top_bottom_shells#surface-pattern"); - optgroup->append_single_option_line("bottom_layer_direction", "strength_settings_infill#direction"); + optgroup->append_single_option_line("bottom_surface_fill_order", "strength_settings_top_bottom_shells#fill-order"); + optgroup->append_single_option_line("bottom_layer_direction", "strength_settings_infill#top-bottom-direction"); + optgroup->append_single_option_line("center_of_surface_pattern", "strength_settings_top_bottom_shells#center-surface-pattern-on"); optgroup->append_single_option_line("top_bottom_infill_wall_overlap", "strength_settings_top_bottom_shells#infillwall-overlap"); optgroup = page->new_optgroup(L("Infill"), L"param_infill"); @@ -2778,10 +2808,11 @@ void TabPrint::build() optgroup->append_single_option_line("solid_infill_rotate_template", "strength_settings_infill_rotation_template_metalanguage"); optgroup->append_single_option_line("gap_fill_target", "strength_settings_infill#apply-gap-fill"); optgroup->append_single_option_line("filter_out_gap_fill", "strength_settings_infill#filter-out-tiny-gaps"); + optgroup->append_single_option_line("separated_infills", "strength_settings_infill#separated-infills"); optgroup->append_single_option_line("infill_wall_overlap", "strength_settings_infill#infill-wall-overlap"); optgroup = page->new_optgroup(L("Advanced"), L"param_advanced"); - optgroup->append_single_option_line("align_infill_direction_to_model", "strength_settings_advanced#align-infill-direction-to-model"); + optgroup->append_single_option_line("align_infill_direction_to_model", "strength_settings_advanced#align-directions-to-model"); optgroup->append_single_option_line("extra_solid_infills", "strength_settings_infill#extra-solid-infill"); optgroup->append_single_option_line("bridge_angle", "strength_settings_advanced#bridge-infill-direction"); optgroup->append_single_option_line("internal_bridge_angle", "strength_settings_advanced#bridge-infill-direction"); // ORCA: Internal bridge angle override @@ -2976,6 +3007,7 @@ void TabPrint::build() optgroup->append_single_option_line("flush_into_support", "multimaterial_settings_flush_options#flush-into-objects-support"); optgroup = page->new_optgroup(L("Advanced"), L"advanced"); optgroup->append_single_option_line("interlocking_beam", "multimaterial_settings_advanced#interlocking-beam"); + optgroup->append_single_option_line("toolchange_ordering", "multimaterial_settings_advanced#toolchange-ordering"); optgroup->append_single_option_line("interface_shells", "multimaterial_settings_advanced#interface-shells"); optgroup->append_single_option_line("mmu_segmented_region_max_width", "multimaterial_settings_advanced#maximum-width-of-segmented-region"); optgroup->append_single_option_line("mmu_segmented_region_interlocking_depth", "multimaterial_settings_advanced#interlocking-depth-of-segmented-region"); @@ -3959,9 +3991,12 @@ void TabFilament::add_filament_overrides_page() "filament_retraction_minimum_travel", "filament_retract_when_changing_layer", "filament_wipe", - //BBS + // BBS "filament_wipe_distance", "filament_retract_before_wipe", + // Orca + "filament_retract_after_wipe", + // BBS "filament_long_retractions_when_cut", "filament_retraction_distances_when_cut" //SoftFever @@ -4085,9 +4120,12 @@ void TabFilament::update_filament_overrides_page(const DynamicPrintConfig* print "filament_retraction_minimum_travel", "filament_retract_when_changing_layer", "filament_wipe", - //BBS + // BBS "filament_wipe_distance", "filament_retract_before_wipe", + // Orca + "filament_retract_after_wipe", + // BBS "filament_long_retractions_when_cut", "filament_retraction_distances_when_cut" //SoftFever @@ -4739,6 +4777,69 @@ void TabFilament::clear_pages() m_overrides_options.clear(); } +// Orca: +void TabFilament::on_value_change(const std::string& opt_key, const boost::any& value) +{ + if (wxGetApp().plater() == nullptr || m_config_manipulation.is_applying()) + return; + + const int pos = opt_key.find("#"); + + if (pos > 0) { + std::string temp_str = opt_key; + boost::erase_head(temp_str, pos + 1); + int orig_opt_idx = static_cast<size_t>(atoi(temp_str.c_str())); + int opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0; + + std::string opt_key_pure = opt_key; + boost::erase_tail(opt_key_pure, opt_key_pure.size() - pos); + + if (opt_key_pure == "filament_retract_after_wipe" || opt_key_pure == "filament_retract_before_wipe") { + double dvalue = boost::any_cast<double>(value); + auto percent_value_clamp = [](double percent_value) { return std::clamp(percent_value, 0., 100.); }; + auto get_value_by_opt_key = [&](const std::string& opt_key) { + if (opt_key_pure == opt_key && !std::isnan(dvalue)) { + // Return the incoming value (if it is valid) if the opt_key equals the key of the changed option. + return percent_value_clamp(dvalue); + } else if (!m_config->option<ConfigOptionPercents>(opt_key)->is_nil(opt_idx)) { + // Return the overridden value if the option value for the opt_key was overridden for the given filament. + return percent_value_clamp(m_config->option<ConfigOptionPercents>(opt_key)->get_at(opt_idx)); + } else { + // Return the value of the option value for opt_key from the printer setting if it was not overridden for the filament. + const auto& printer_config = m_preset_bundle->printers.get_edited_preset().config; + const std::string printer_opt_key = opt_key.substr(strlen("filament_")); + return percent_value_clamp(printer_config.option<ConfigOptionPercents>(printer_opt_key)->get_at(opt_idx)); + } + + return 0.; + }; + + double retract_before_wipe = get_value_by_opt_key("filament_retract_before_wipe"); + double retract_after_wipe = get_value_by_opt_key("filament_retract_after_wipe"); + + bool need_to_reload_config = false; + + if (percent_value_clamp(dvalue) != dvalue) { + change_opt_value(*m_config, opt_key_pure, percent_value_clamp(dvalue), opt_idx); + need_to_reload_config = true; + } + + if (retract_after_wipe > 100. - retract_before_wipe) { + change_opt_value(*m_config, "filament_retract_after_wipe", 100. - retract_before_wipe, opt_idx); + need_to_reload_config = true; + } + + if (need_to_reload_config && !m_postpone_update_ui) { + update_dirty(); + reload_config(); + update_tab_ui(); + } + } + } + + Tab::on_value_change(opt_key, value); +} + wxSizer* Tab::description_line_widget(wxWindow* parent, ogStaticText* *StaticText, wxString text /*= wxEmptyString*/) { *StaticText = new ogStaticText(parent, text); @@ -4928,8 +5029,10 @@ void TabPrinter::build_fff() optgroup->append_single_option_line("nozzle_type", "printer_basic_information_accessory#nozzle-type"); optgroup->append_single_option_line("nozzle_hrc", "printer_basic_information_accessory#nozzle-hrc"); optgroup->append_single_option_line("auxiliary_fan", "printer_basic_information_accessory#auxiliary-part-cooling-fan"); + optgroup->append_single_option_line("fan_direction"); optgroup->append_single_option_line("support_chamber_temp_control", "printer_basic_information_accessory#support-controlling-chamber-temperature"); optgroup->append_single_option_line("support_air_filtration", "printer_basic_information_accessory#support-air-filtration"); + optgroup->append_single_option_line("cooling_filter_enabled"); auto edit_custom_gcode_fn = [this](const t_config_option_key& opt_key) { edit_custom_gcode(opt_key); }; @@ -5501,6 +5604,8 @@ if (is_marlin_flavor) optgroup->append_single_option_line("wipe", "printer_extruder_retraction#wipe-while-retracting", extruder_idx); optgroup->append_single_option_line("wipe_distance", "printer_extruder_retraction#wipe-distance", extruder_idx); optgroup->append_single_option_line("retract_before_wipe", "printer_extruder_retraction#retract-amount-before-wipe", extruder_idx); + // Orca + optgroup->append_single_option_line("retract_after_wipe", "printer_extruder_retraction#retract-amount-after-wipe", extruder_idx); optgroup = page->new_optgroup(L("Z-Hop"), L"param_extruder_lift_enforcement"); optgroup->append_single_option_line("retract_lift_enforce", "printer_extruder_z_hop#on-surfaces", extruder_idx); @@ -5615,7 +5720,53 @@ void TabPrinter::on_preset_loaded() if (use_default_nozzle_volume_type) { m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")->values = current_printer.config.option<ConfigOptionEnumsGeneric>("default_nozzle_volume_type")->values; } + + // Changing printer model drops any Filament Track Switch context from the previous + // printer; clear both device-derived flags so a switch-less printer never inherits a + // stale installed/active state (re-derived by device sync when a printer is connected). + if (auto* has_switcher = m_preset_bundle->project_config.opt<ConfigOptionBool>("has_filament_switcher")) + has_switcher->value = false; + if (auto* dynamic_map = m_preset_bundle->project_config.opt<ConfigOptionBool>("enable_filament_dynamic_map")) + dynamic_map->value = false; + // Orca: also clear the sidebar switcher status icon on printer-model change (mirrors BBS's + // reset_fila_switch on machine change); it re-derives from device sync once a printer connects. + if (wxGetApp().plater()) + wxGetApp().plater()->sidebar().reset_fila_switch(); } + + // Purge mode selection is only meaningful for printers with multiple sub-nozzles per + // extruder (prime saving) or fast-purge support; reset stale project values that the + // current printer cannot honor and toggle the sidebar button accordingly. + auto extruder_max_nozzle_count = current_printer.config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + bool has_multiple_nozzle = extruder_max_nozzle_count && + std::any_of(extruder_max_nozzle_count->values.begin(), extruder_max_nozzle_count->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); }); + auto support_fast_purge_opt = current_printer.config.option<ConfigOptionBool>("support_fast_purge_mode"); + bool support_fast_purge = support_fast_purge_opt ? support_fast_purge_opt->value : false; + bool show_purge_mode = has_multiple_nozzle || support_fast_purge; + if (auto *prime_volume_mode = m_preset_bundle->project_config.option<ConfigOptionEnum<PrimeVolumeMode>>("prime_volume_mode")) { + if (!show_purge_mode) + prime_volume_mode->value = PrimeVolumeMode::pvmDefault; + else if (!has_multiple_nozzle && prime_volume_mode->value == PrimeVolumeMode::pvmSaving) + prime_volume_mode->value = PrimeVolumeMode::pvmDefault; + else if (!support_fast_purge && prime_volume_mode->value == PrimeVolumeMode::pvmFast) + prime_volume_mode->value = PrimeVolumeMode::pvmDefault; + } + if (wxGetApp().plater()) + wxGetApp().plater()->sidebar().enable_purge_mode_btn(show_purge_mode); + + // Sidebar nozzle-count badge on the extruder cards. The `extruder_nozzle_stats` key is session-only — + // saved presets never carry it, so any preset switch rebuilds the edited config without it — so + // re-baseline it whenever it is missing (each extruder gets extruder_max_nozzle_count nozzles of its + // selected volume type), then refresh the badges. Idempotent, so run on every preset load. + if (wxGetApp().plater()) + wxGetApp().plater()->sidebar().enable_nozzle_count_edit(has_multiple_nozzle); + const auto *nozzle_stats = m_preset_bundle->printers.get_edited_preset().config.option<ConfigOptionStrings>("extruder_nozzle_stats"); + if (nozzle_stats == nullptr || nozzle_stats->values.empty()) + seedExtruderNozzleStats(m_preset_bundle); + if (auto *nozzle_volume_type = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type")) + for (size_t idx = 0; idx < nozzle_volume_type->values.size(); ++idx) + updateNozzleCountDisplay(m_preset_bundle, idx, NozzleVolumeType(nozzle_volume_type->values[idx])); } void TabPrinter::update_pages() @@ -5831,6 +5982,12 @@ void TabPrinter::toggle_options() const bool support_parallel_printheads = printer_cfg.opt_bool("support_parallel_printheads"); toggle_line("parallel_printheads_count", support_parallel_printheads); + + toggle_line("fan_direction", m_config->opt_bool("auxiliary_fan")); + + // The cooling filter and air filtration are alternative accessories: show only the one the printer supports. + toggle_line("support_air_filtration", !m_config->opt_bool("support_cooling_filter")); + toggle_line("cooling_filter_enabled", m_config->opt_bool("support_cooling_filter")); } @@ -5908,16 +6065,20 @@ void TabPrinter::toggle_options() // some options only apply when not using firmware retraction vec.resize(0); - vec = {"retraction_speed", "deretraction_speed", "retract_before_wipe", - "retract_length", "retract_restart_extra", - "wipe_distance"}; + vec = {"retraction_speed", "deretraction_speed", "retract_before_wipe", "retract_after_wipe", + "retract_length", "retract_restart_extra", "wipe_distance"}; for (auto el : vec) //BBS toggle_option(el, retraction && !use_firmware_retraction, i); bool wipe = retraction && m_config->opt_bool("wipe", variant_index); - toggle_option("retract_before_wipe", wipe, i); - float retract_before_wipe = static_cast<ConfigOptionPercents*>(m_config->option("retract_before_wipe"))->values[variant_index]; + + // Orca: + double retract_before_wipe = m_config->option<ConfigOptionPercents>("retract_before_wipe")->get_at(variant_index); + double retract_after_wipe = m_config->option<ConfigOptionPercents>("retract_after_wipe")->get_at(variant_index); + + toggle_option("retract_before_wipe", wipe && !is_approx(retract_after_wipe, 100.), i); + toggle_option("retract_after_wipe", wipe && !is_approx(retract_before_wipe, 100.), i); if (use_firmware_retraction && wipe && retract_before_wipe < 100.0) { //wxMessageDialog dialog(parent(), @@ -6020,6 +6181,56 @@ void TabPrinter::toggle_options() } } +// Orca: +void TabPrinter::on_value_change(const std::string& opt_key, const boost::any& value) +{ + if (wxGetApp().plater() == nullptr || m_config_manipulation.is_applying()) + return; + + const int pos = opt_key.find("#"); + + if (pos > 0) { + std::string temp_str = opt_key; + boost::erase_head(temp_str, pos + 1); + int orig_opt_idx = static_cast<size_t>(atoi(temp_str.c_str())); + int opt_idx = orig_opt_idx >= 0 ? orig_opt_idx : 0; + + std::string opt_key_pure = opt_key; + boost::erase_tail(opt_key_pure, opt_key_pure.size() - pos); + + if (opt_key_pure == "retract_after_wipe" || opt_key_pure == "retract_before_wipe") { + auto percent_value_clamp = [](double percent_value) { return std::clamp(percent_value, 0., 100.); }; + double dvalue = boost::any_cast<double>(value); + + double retract_before_wipe = percent_value_clamp(opt_key_pure == "retract_before_wipe" + ? dvalue : m_config->option<ConfigOptionPercents>("retract_before_wipe")->get_at(opt_idx)); + + double retract_after_wipe = percent_value_clamp(opt_key_pure == "retract_after_wipe" + ? dvalue : m_config->option<ConfigOptionPercents>("retract_after_wipe")->get_at(opt_idx)); + + bool need_to_reload_config = false; + + if (percent_value_clamp(dvalue) != dvalue) { + change_opt_value(*m_config, opt_key_pure, percent_value_clamp(dvalue), opt_idx); + need_to_reload_config = true; + } + + if (retract_after_wipe > 100. - retract_before_wipe) { + change_opt_value(*m_config, "retract_after_wipe", 100. - retract_before_wipe, opt_idx); + need_to_reload_config = true; + } + + if (need_to_reload_config && !m_postpone_update_ui) { + update_dirty(); + reload_config(); + update_tab_ui(); + } + } + } + + Tab::on_value_change(opt_key, value); +} + void TabPrinter::update() { m_update_cnt++; @@ -7433,11 +7644,11 @@ wxSizer* Tab::compatible_widget_create(wxWindow* parent, PresetDependencies &dep } if(deps.type == Preset::TYPE_PRINTER){ - deps.dialog_title = "Compatible printers"; - deps.dialog_label = "Select printers"; + deps.dialog_title = _L("Compatible printers"); + deps.dialog_label = _L("Select printers"); }else{ - deps.dialog_title = "Compatible process profiles"; - deps.dialog_label = "Select profiles"; + deps.dialog_title = _L("Compatible process profiles"); + deps.dialog_label = _L("Select profiles"); } MultiChoiceDialog dlg(parent, deps.dialog_label, deps.dialog_title, presets); @@ -7484,12 +7695,23 @@ void TabPrinter::set_extruder_volume_type(int extruder_id, NozzleVolumeType type auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); assert(nozzle_volumes->values.size() > (size_t)extruder_id); nozzle_volumes->values[extruder_id] = type; + + // Carry the extruder's nozzle count over to the new flow type and refresh the sidebar badge. + onNozzleVolumeTypeSwitch(m_preset_bundle, extruder_id, type); + updateNozzleCountDisplay(m_preset_bundle, extruder_id, type); + on_value_change((boost::format("nozzle_volume_type#%1%") % extruder_id).str(), int(type)); //save to app config if (!m_base_preset_name.empty()) { - ConfigOptionEnumsGeneric* nozzle_volume_type_option = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); - std::string nozzle_volume_type_str = nozzle_volume_type_option->serialize(); + // do not save hybrid flow status to config: it depends on the nozzles currently installed + // on the connected printer, so it must not be restored in a later session + ConfigOptionEnumsGeneric nozzle_volume_type_option = *m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); + for (size_t i = 0; i < nozzle_volume_type_option.values.size(); i++) { + if (nozzle_volume_type_option.values[i] == (int) nvtHybrid) + nozzle_volume_type_option.values[i] = (int) nvtStandard; + } + std::string nozzle_volume_type_str = nozzle_volume_type_option.serialize(); wxGetApp().app_config->save_nozzle_volume_types_to_config(m_base_preset_name, nozzle_volume_type_str); } @@ -7659,7 +7881,7 @@ bool Tab::validate_filament_temperature_pairs() if (delta <= rule.max_delta) continue; - const wxString deg_c = wxString::FromUTF8("°C"); + const wxString deg_c = wxString::FromUTF8("℃"); const wxString bullet = wxString::FromUTF8("•"); invalid_pairs += wxString::Format(_L(" - %s:\n %s first layer %d %s, other layers %d %s\n %s max delta %d %s, current delta %d %s\n"), rule.label, bullet, first_temp, deg_c, other_temp, deg_c, bullet, rule.max_delta, deg_c, delta, deg_c); @@ -7677,7 +7899,7 @@ bool Tab::validate_filament_temperature_pairs() RichMessageDialog dialog(parent(), msg_text, _L("Temperature Safety Check"), wxYES | wxNO | wxICON_WARNING); dialog.SetButtonLabel(wxID_YES, _L("Continue"), true); - dialog.SetButtonLabel(wxID_NO, _L("Back")); + dialog.SetButtonLabel(wxID_NO, _CTX("Back", "Navigation")); dialog.ShowCheckBox(_L("Don't warn again for this preset")); const int answer = dialog.ShowModal(); // Session-only suppression (does not modify/save filament preset data). @@ -7713,6 +7935,11 @@ void Tab::update_extruder_variants(int extruder_id, bool reload) auto nozzle_volumes = m_preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); int extruder_nums = m_preset_bundle->get_printer_extruder_count(); nozzle_volumes->values.resize(extruder_nums); + + // Orca: update `m_actual_nozzle_volumes` to current selected ones + m_actual_nozzle_volumes.resize(extruder_nums, NozzleVolumeType::nvtStandard); + for (int i = 0; i < extruder_nums; i++) m_actual_nozzle_volumes[i] = (NozzleVolumeType)nozzle_volumes->values[i]; + if (extruder_nums == 2) { auto options = generate_extruder_options(); m_extruder_switch->SetOptions(options); @@ -7819,12 +8046,11 @@ std::vector<wxString> Tab::generate_extruder_options() wxString extruder_name = _L(DevPrinterConfigUtil::get_toolhead_display_name( pt, ext_id, ToolHeadComponent::Nozzle, ToolHeadNameCase::TitleCase, true)); NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volumes->values[i]); - - // TODO: Orca: Support hybrid - /*if (volume_type == NozzleVolumeType::nvtHybrid) { + + if (volume_type == NozzleVolumeType::nvtHybrid) { options.push_back(wxString::Format(_L("%s: %s"), extruder_name, _L("Standard"))); options.push_back(wxString::Format(_L("%s: %s"), extruder_name, _L("High Flow"))); - } else*/ { + } else { wxString volume_name = get_nozzle_volume_type_name(volume_type); options.push_back(wxString::Format(_L("%s: %s"), extruder_name, volume_name)); } @@ -7873,36 +8099,35 @@ bool Tab::get_extruder_sync_enable_state(int extruder_id) if (left_nozzle == right_nozzle) { return true; } - - // TODO: Orca: Support hybrid - //if (left_nozzle != NozzleVolumeType::nvtHybrid && right_nozzle != NozzleVolumeType::nvtHybrid) { - // return false; - //} - //if (left_nozzle == NozzleVolumeType::nvtHybrid && right_nozzle == NozzleVolumeType::nvtHybrid) { - // return true; - //} + if (left_nozzle != NozzleVolumeType::nvtHybrid && right_nozzle != NozzleVolumeType::nvtHybrid) { + return false; + } - //// Hybrid rules - //auto current_nozzle = get_actual_nozzle_volume_type(extruder_id); - //if (left_nozzle != NozzleVolumeType::nvtHybrid) { - // if (extruder_id == 0) { - // return true; - // } - // if (extruder_id == 1 && current_nozzle == left_nozzle) { - // return true; - // } - // return false; - //} - //if (right_nozzle != NozzleVolumeType::nvtHybrid) { - // if (extruder_id == 1) { - // return true; - // } - // if (extruder_id == 0 && current_nozzle == right_nozzle) { - // return true; - // } - // return false; - //} + if (left_nozzle == NozzleVolumeType::nvtHybrid && right_nozzle == NozzleVolumeType::nvtHybrid) { + return true; + } + + // Hybrid rules + auto current_nozzle = get_actual_nozzle_volume_type(extruder_id); + if (left_nozzle != NozzleVolumeType::nvtHybrid) { + if (extruder_id == 0) { + return true; + } + if (extruder_id == 1 && current_nozzle == left_nozzle) { + return true; + } + return false; + } + if (right_nozzle != NozzleVolumeType::nvtHybrid) { + if (extruder_id == 1) { + return true; + } + if (extruder_id == 0 && current_nozzle == right_nozzle) { + return true; + } + return false; + } return false; } diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index f80e67f06b..c5344131ab 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -608,6 +608,8 @@ public: void clear_pages() override; bool supports_printer_technology(const PrinterTechnology tech) const override { return tech == ptFFF; } + void on_value_change(const std::string& opt_key, const boost::any& value) override; + const std::string& get_custom_gcode(const t_config_option_key& opt_key) override; void set_custom_gcode(const t_config_option_key& opt_key, const std::string& value) override; }; @@ -666,11 +668,11 @@ public: bool supports_printer_technology(const PrinterTechnology /* tech */) const override { return true; } void set_extruder_volume_type(int extruder_id, NozzleVolumeType type); + void on_value_change(const std::string& opt_key, const boost::any& value) override; wxSizer* create_bed_shape_widget(wxWindow* parent); void cache_extruder_cnt(const DynamicPrintConfig* config = nullptr); bool apply_extruder_cnt_from_cache(); - }; class TabSLAMaterial : public Tab diff --git a/src/slic3r/GUI/UnsavedChangesDialog.cpp b/src/slic3r/GUI/UnsavedChangesDialog.cpp index 2da4beea23..d4287b9c35 100644 --- a/src/slic3r/GUI/UnsavedChangesDialog.cpp +++ b/src/slic3r/GUI/UnsavedChangesDialog.cpp @@ -2281,7 +2281,7 @@ void DiffPresetDialog::update_tree() const Preset* left_preset = presets->find_preset(get_selection(preset_combos.presets_left)); const Preset* right_preset = presets->find_preset(get_selection(preset_combos.presets_right)); if (!left_preset || !right_preset) { - bottom_info = "One of the presets does not exist"; + bottom_info = _L("One of the presets does not exist"); preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "question")); preset_combos.equal_bmp->SetToolTip(bottom_info); continue; @@ -2292,7 +2292,7 @@ void DiffPresetDialog::update_tree() const DynamicPrintConfig& right_congig = right_preset->config; if (left_pt != right_preset->printer_technology()) { - bottom_info = "Compared presets has different printer technology"; + bottom_info = _L("Compared presets has different printer technology"); preset_combos.equal_bmp->SetBitmap_(ScalableBitmap(this, "question")); preset_combos.equal_bmp->SetToolTip(bottom_info); continue; @@ -2336,7 +2336,7 @@ void DiffPresetDialog::update_tree() wxString left_val = from_u8((boost::format("%1%") % left_config.opt<ConfigOptionStrings>("extruder_colour")->values.size()).str()); wxString right_val = from_u8((boost::format("%1%") % right_congig.opt<ConfigOptionStrings>("extruder_colour")->values.size()).str()); - m_tree->Append("extruders_count", type, "General", "Capabilities", local_label, left_val, right_val, + m_tree->Append("extruders_count", type, _L("General"), _L("Capabilities"), local_label, left_val, right_val, get_category_icon("Basic information")); } diff --git a/src/slic3r/GUI/UpgradePanel.cpp b/src/slic3r/GUI/UpgradePanel.cpp index 4a4ad9e947..16fe0420d8 100644 --- a/src/slic3r/GUI/UpgradePanel.cpp +++ b/src/slic3r/GUI/UpgradePanel.cpp @@ -3,6 +3,7 @@ #include <slic3r/GUI/Widgets/Label.hpp> #include <slic3r/GUI/I18N.hpp> #include "slic3r/GUI/DeviceTab/uiDeviceUpdateVersion.h" +#include "slic3r/GUI/DeviceTab/wgtDeviceNozzleRackUpdate.h" #include "GUI.hpp" #include "GUI_App.hpp" @@ -27,6 +28,7 @@ static const std::unordered_map<wxString, wxString> ACCESSORY_DISPLAY_STR = { {"O2L_ACM", "Active Cutting Module"}, {"O2L_UCM", "Ultrasonic Cutting Module"}, {"O2L-AFP", L("Auto Fire Extinguishing System")}, + {"O2L-FTS", L("Filament Track Switch")}, }; enum FIRMWARE_STASUS @@ -216,6 +218,10 @@ MachineInfoPanel::MachineInfoPanel(wxWindow* parent, wxWindowID id, const wxPoin createLaserWidgets(m_main_left_sizer); createAirPumpWidgets(m_main_left_sizer); createExtinguishWidgets(m_main_left_sizer); + createFilaTrackSwitchWidgets(m_main_left_sizer); + + // nozzle rack widgets (H2C induction hotend rack; hidden unless GetNozzleRack()->IsSupported()) + createNozzleRackWidgets(m_main_left_sizer); m_main_sizer->Add(m_main_left_sizer, 1, wxEXPAND, 0); @@ -402,6 +408,27 @@ void MachineInfoPanel::createExtinguishWidgets(wxBoxSizer* main_left_sizer) main_left_sizer->Add(m_extinguish_sizer, 0, wxEXPAND, 0); } +void MachineInfoPanel::createFilaTrackSwitchWidgets(wxBoxSizer* main_left_sizer) +{ + m_filatrack_line_above = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL); + m_filatrack_line_above->SetBackgroundColour(wxColour(206, 206, 206)); + main_left_sizer->Add(m_filatrack_line_above, 0, wxEXPAND | wxLEFT, FromDIP(40)); + + m_filatrack_img = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(200), FromDIP(200))); + m_filatrack_img->SetBitmap(m_img_filatrack.bmp()); + + wxBoxSizer* content_sizer = new wxBoxSizer(wxVERTICAL); + content_sizer->Add(0, 40, 0, wxEXPAND, FromDIP(5)); + m_filatrack_version = new uiDeviceUpdateVersion(this, wxID_ANY); + content_sizer->Add(m_filatrack_version, 0, wxEXPAND, 0); + + m_filatrack_sizer = new wxBoxSizer(wxHORIZONTAL); + m_filatrack_sizer->Add(m_filatrack_img, 0, wxALIGN_TOP | wxALL, FromDIP(5)); + m_filatrack_sizer->Add(content_sizer, 1, wxEXPAND, 0); + + main_left_sizer->Add(m_filatrack_sizer, 0, wxEXPAND, 0); +} + void MachineInfoPanel::msw_rescale() { rescale_bitmaps(); @@ -431,6 +458,8 @@ void MachineInfoPanel::init_bitmaps() m_img_laser = ScalableBitmap(this, "laser", 160); m_img_cutting = ScalableBitmap(this, "cut", 160); m_img_extinguish = ScalableBitmap(this, "extinguish", 160); + m_img_filatrack = ScalableBitmap(this, "filament_track_switch", 160); + m_img_nozzle_rack = ScalableBitmap(this, "nozzle_rack", 160); upgrade_green_icon = ScalableBitmap(this, "monitor_upgrade_online", 5); upgrade_gray_icon = ScalableBitmap(this, "monitor_upgrade_offline", 5); @@ -539,6 +568,8 @@ void MachineInfoPanel::update(MachineObject* obj) update_cut(obj); update_laszer(obj); update_extinguish(obj); + update_filatrack(obj); + update_nozzle_rack(obj); //update progress int upgrade_percent = obj->get_upgrade_percent(); @@ -1123,6 +1154,19 @@ void MachineInfoPanel::update_extinguish(MachineObject* obj) } } +void MachineInfoPanel::update_filatrack(MachineObject* obj) +{ + if (obj && obj->filatrack_version_info.isValid()) + { + m_filatrack_version->UpdateInfo(obj->filatrack_version_info); + show_filatrack(true); + } + else + { + show_filatrack(false); + } +} + void MachineInfoPanel::show_status(int status, std::string upgrade_status_str) { if (last_status == status && last_status_str == upgrade_status_str) return; @@ -1257,6 +1301,90 @@ void MachineInfoPanel::show_extinguish(bool show) } } +void MachineInfoPanel::show_filatrack(bool show) +{ + if (m_filatrack_version->IsShown() != show) + { + m_filatrack_img->Show(show); + m_filatrack_line_above->Show(show); + m_filatrack_version->Show(show); + } +} + +void MachineInfoPanel::createNozzleRackWidgets(wxBoxSizer *main_left_sizer) +{ + // horizontal line above + m_nozzle_rack_line_above = new wxStaticLine(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL); + m_nozzle_rack_line_above->SetBackgroundColour(wxColour(206, 206, 206)); + main_left_sizer->Add(m_nozzle_rack_line_above, 0, wxEXPAND | wxLEFT, FromDIP(40)); + + m_nozzle_rack_sizer = new wxBoxSizer(wxHORIZONTAL); + + // left placeholder icon (keep consistent spacing with others) + m_nozzle_rack_img = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap, wxDefaultPosition, wxSize(FromDIP(200), FromDIP(200))); + m_nozzle_rack_img->SetBitmap(m_img_nozzle_rack.bmp()); + m_nozzle_rack_sizer->Add(m_nozzle_rack_img, 0, wxALIGN_CENTER_VERTICAL | wxALL, FromDIP(5)); + + // right content: label + update button + auto *content_sizer = new wxBoxSizer(wxHORIZONTAL); + m_nozzle_rack_text = new wxStaticText(this, wxID_ANY, _L("Hotends on Rack"), wxDefaultPosition, wxDefaultSize, 0); + m_nozzle_rack_text->Wrap(-1); + m_nozzle_rack_text->SetFont(Label::Head_14); + content_sizer->Add(m_nozzle_rack_text, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, FromDIP(50)); + + m_nozzle_rack_update_btn = new Button(this, _L("Info")); + StateColor btn_bg(std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Disabled), std::pair<wxColour, int>(wxColour(200, 200, 200), StateColor::Pressed), + std::pair<wxColour, int>(wxColour(240, 240, 240), StateColor::Hovered), std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Enabled), + std::pair<wxColour, int>(wxColour(255, 255, 255), StateColor::Normal)); + StateColor btn_bd(std::pair<wxColour, int>(wxColour(200, 200, 200), StateColor::Disabled), std::pair<wxColour, int>(wxColour(150, 150, 150), StateColor::Enabled)); + StateColor btn_text(std::pair<wxColour, int>(wxColour(150, 150, 150), StateColor::Disabled), std::pair<wxColour, int>(wxColour(0, 0, 0), StateColor::Enabled)); + m_nozzle_rack_update_btn->SetBackgroundColor(btn_bg); + m_nozzle_rack_update_btn->SetBorderColor(btn_bd); + m_nozzle_rack_update_btn->SetTextColor(btn_text); + m_nozzle_rack_update_btn->SetFont(Label::Body_10.Bold()); + m_nozzle_rack_update_btn->SetMinSize(wxSize(FromDIP(-1), FromDIP(24))); + m_nozzle_rack_update_btn->SetCornerRadius(FromDIP(12)); + m_nozzle_rack_update_btn->Bind(wxEVT_BUTTON, &MachineInfoPanel::on_nozzle_rack_update, this); + content_sizer->Add(m_nozzle_rack_update_btn, 0, wxALIGN_CENTER_VERTICAL | wxLEFT, FromDIP(350)); + + m_nozzle_rack_sizer->Add(content_sizer, 1, wxEXPAND, 0); + + main_left_sizer->Add(m_nozzle_rack_sizer, 0, wxEXPAND, 0); +} + +void MachineInfoPanel::update_nozzle_rack(MachineObject* obj) +{ + if (obj && obj->GetNozzleSystem()) { + auto rack = obj->GetNozzleSystem()->GetNozzleRack(); + if (rack && rack->IsSupported()) { + show_nozzle_rack(true); + } + else { + show_nozzle_rack(false); + } + } +} + +void MachineInfoPanel::show_nozzle_rack(bool show) +{ + if (m_nozzle_rack_img->IsShown() != show) { + m_nozzle_rack_line_above->Show(show); + m_nozzle_rack_update_btn->Show(show); + m_nozzle_rack_img->Show(show); + m_nozzle_rack_text->Show(show); + } +} + +void MachineInfoPanel::on_nozzle_rack_update(wxCommandEvent &event) +{ + if (!m_obj || !m_obj->GetNozzleSystem()) return; + auto rack = m_obj->GetNozzleSystem()->GetNozzleRack(); + if (!rack) return; + + wgtDeviceNozzleRackUpgradeDlg dlg(this, rack); + dlg.ShowModal(); +} + void MachineInfoPanel::on_sys_color_changed() { diff --git a/src/slic3r/GUI/UpgradePanel.hpp b/src/slic3r/GUI/UpgradePanel.hpp index 2fb0f8dcb1..0cf88ae080 100644 --- a/src/slic3r/GUI/UpgradePanel.hpp +++ b/src/slic3r/GUI/UpgradePanel.hpp @@ -134,6 +134,19 @@ protected: wxStaticLine* m_extinguish_line_above = nullptr;; uiDeviceUpdateVersion* m_extinguish_version = nullptr; + /* filament track switch info*/ + wxBoxSizer* m_filatrack_sizer = nullptr; + wxStaticBitmap* m_filatrack_img = nullptr; + wxStaticLine* m_filatrack_line_above = nullptr; + uiDeviceUpdateVersion* m_filatrack_version = nullptr; + + /* nozzle rack (H2C induction hotend rack) — opens wgtDeviceNozzleRackUpgradeDlg */ + wxBoxSizer* m_nozzle_rack_sizer = nullptr; + wxStaticBitmap* m_nozzle_rack_img = nullptr; + wxStaticLine* m_nozzle_rack_line_above = nullptr; + wxStaticText* m_nozzle_rack_text = nullptr; + Button* m_nozzle_rack_update_btn = nullptr; + /* upgrade widgets */ wxBoxSizer* m_upgrading_sizer; wxStaticText * m_staticText_upgrading_info; @@ -155,6 +168,8 @@ protected: ScalableBitmap m_img_cutting; ScalableBitmap m_img_laser; ScalableBitmap m_img_extinguish; + ScalableBitmap m_img_filatrack; + ScalableBitmap m_img_nozzle_rack; ScalableBitmap upgrade_gray_icon; ScalableBitmap upgrade_green_icon; ScalableBitmap upgrade_yellow_icon; @@ -212,16 +227,24 @@ private: void createCuttingWidgets(wxBoxSizer* main_left_sizer); void createLaserWidgets(wxBoxSizer* main_left_sizer); void createExtinguishWidgets(wxBoxSizer* main_left_sizer); + void createFilaTrackSwitchWidgets(wxBoxSizer* main_left_sizer); + void createNozzleRackWidgets(wxBoxSizer* main_left_sizer); void update_air_pump(MachineObject* obj); void update_cut(MachineObject* obj); void update_laszer(MachineObject* obj); void update_extinguish(MachineObject* obj); + void update_filatrack(MachineObject* obj); + void update_nozzle_rack(MachineObject* obj); void show_air_pump(bool show = true); void show_cut(bool show = true); void show_laszer(bool show = true); void show_extinguish(bool show = true); + void show_filatrack(bool show = true); + void show_nozzle_rack(bool show = true); + + void on_nozzle_rack_update(wxCommandEvent& event); }; //enum UpgradeMode { diff --git a/src/slic3r/GUI/WebUserLoginDialog.cpp b/src/slic3r/GUI/WebUserLoginDialog.cpp index 4b8acc9455..4222ce745b 100644 --- a/src/slic3r/GUI/WebUserLoginDialog.cpp +++ b/src/slic3r/GUI/WebUserLoginDialog.cpp @@ -506,7 +506,7 @@ void ZUserLogin::OnScriptMessage(wxWebViewEvent &evt) return; } } catch (std::exception &e) { - wxMessageBox(e.what(), "parse json failed", wxICON_WARNING); + wxMessageBox(e.what(), _L("parse json failed"), wxICON_WARNING); Close(); } } diff --git a/src/slic3r/GUI/WebViewDialog.cpp b/src/slic3r/GUI/WebViewDialog.cpp index 20ed70e799..d10eaedef5 100644 --- a/src/slic3r/GUI/WebViewDialog.cpp +++ b/src/slic3r/GUI/WebViewDialog.cpp @@ -47,7 +47,7 @@ WebViewPanel::WebViewPanel(wxWindow *parent) // Create the button bSizer_toolbar = new wxBoxSizer(wxHORIZONTAL); - m_button_back = new wxButton(this, wxID_ANY, _L("Back"), wxDefaultPosition, wxDefaultSize, 0); + m_button_back = new wxButton(this, wxID_ANY, _CTX("Back", "Navigation"), wxDefaultPosition, wxDefaultSize, 0); m_button_back->Enable(false); bSizer_toolbar->Add(m_button_back, 0, wxALL, 5); diff --git a/src/slic3r/GUI/Widgets/AMSControl.cpp b/src/slic3r/GUI/Widgets/AMSControl.cpp index a3913dc4e4..7334cb960a 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.cpp +++ b/src/slic3r/GUI/Widgets/AMSControl.cpp @@ -9,9 +9,11 @@ #include "slic3r/GUI/DeviceCore/DevManager.h" #include "slic3r/GUI/DeviceCore/DevFilaSystem.h" +#include "slic3r/GUI/DeviceCore/DevFilaSwitch.h" #include <wx/simplebook.h> #include <wx/dcgraph.h> +#include <wx/artprov.h> #include <boost/log/trivial.hpp> @@ -29,6 +31,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons , m_Humidity_tip_popup(AmsHumidityTipPopup(this)) , m_percent_humidity_dry_popup(new uiAmsPercentHumidityDryPopup(this)) , m_ams_introduce_popup(AmsIntroducePopup(this)) + , m_ams_dry_ctr_win(new AMSDryCtrWin(this)) { Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); if (dev) { @@ -39,7 +42,7 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons SetBackgroundColour(*wxWHITE); // normal mode //Freeze(); - wxBoxSizer *m_sizer_body = new wxBoxSizer(wxVERTICAL); + m_sizer_body = new wxBoxSizer(wxVERTICAL); m_amswin = new wxWindow(this, wxID_ANY); m_amswin->SetBackgroundColour(*wxWHITE); m_amswin->SetSize(wxSize(FromDIP(578), -1)); @@ -151,6 +154,12 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons m_extruder = new AMSextruder(m_amswin, wxID_ANY, m_total_ext_count, wxDefaultPosition, AMS_EXTRUDER_SIZE); m_sizer_option_mid->Add( m_extruder, 0, wxALIGN_CENTER, 0 ); + // Orca: filament-switch routing glyph; hidden by default so it stays inert (zero layout impact) + // on any printer without a Filament Track Switch. Shown from UpdateAms only when installed. + m_switcher = new SwitcherImage(m_amswin, wxID_ANY, "fila_switch", wxSize(FromDIP(29), FromDIP(16)), wxDefaultPosition); + m_switcher->Hide(); + m_sizer_option_mid->Add(m_switcher, 0, wxALIGN_CENTER | wxLEFT, FromDIP(6)); + /*option right*/ m_button_extruder_feed = new Button(m_panel_option_right, _L("Load")); @@ -244,6 +253,12 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons uiAmsHumidityInfo *info = (uiAmsHumidityInfo *) evt.GetClientData(); if (info) { + Slic3r::DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + MachineObject *obj = nullptr; + if (dev) { + obj = dev->get_selected_machine(); + } + if (info->ams_type == AMSModel::GENERIC_AMS) { wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); @@ -253,9 +268,14 @@ AMSControl::AMSControl(wxWindow *parent, wxWindowID id, const wxPoint &pos, cons int humidity_value = info->humidity_display_idx; if (humidity_value > 0 && humidity_value <= 5) { m_Humidity_tip_popup.set_humidity_level(humidity_value); } m_Humidity_tip_popup.Popup(); - } - else - { + } else if (obj && obj->is_support_remote_dry && (info->ams_type == AMSModel::N3F_AMS || info->ams_type == AMSModel::N3S_AMS)){ + m_ams_dry_ctr_win->set_ams_id(info->ams_id); + + wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); + wxPoint popup_pos(img_pos.x - m_ams_dry_ctr_win->GetSize().GetWidth() + FromDIP(150), img_pos.y - FromDIP(80)); + m_ams_dry_ctr_win->Move(popup_pos); + m_ams_dry_ctr_win->ShowModal(); + } else { m_percent_humidity_dry_popup->Update(info); wxPoint img_pos = ClientToScreen(wxPoint(0, 0)); @@ -275,7 +295,12 @@ void AMSControl::on_retry() post_event(wxCommandEvent(EVT_AMS_RETRY)); } -AMSControl::~AMSControl() {} +AMSControl::~AMSControl() +{ + if (m_ams_dry_ctr_win) { + delete m_ams_dry_ctr_win; + } +} std::string AMSControl::GetCurentAms() { return m_current_ams; @@ -493,6 +518,10 @@ void AMSControl::msw_rescale() m_percent_humidity_dry_popup->msw_rescale(); } + if (m_ams_dry_ctr_win) { + m_ams_dry_ctr_win->msw_rescale(); + } + m_Humidity_tip_popup.msw_rescale(); Layout(); @@ -816,6 +845,27 @@ void AMSControl::show_vams_kn_value(bool show) //m_vams_lib->show_kn_value(show); } +void AMSControl::UpdateAmsDryControl(MachineObject* obj) +{ + if (!m_ams_dry_ctr_win->IsShown()) { + return; + } + + if (!obj || !obj->GetFilaSystem()) { + m_ams_dry_ctr_win->Close(); + return; + } + + std::weak_ptr<DevFilaSystem> weak_fila_system = obj->GetFilaSystem(); + + if (auto locaked_fila_system = weak_fila_system.lock()) { + m_ams_dry_ctr_win->update(locaked_fila_system, obj); + } else { + m_ams_dry_ctr_win->Close(); + return; + } +} + std::vector<AMSinfo> AMSControl::GenerateSimulateData() { auto caninfo0_0 = Caninfo{ "0", (""), *wxRED, AMSCanType::AMS_CAN_TYPE_VIRTUAL }; auto caninfo0_1 = Caninfo{ "1", (""), *wxGREEN, AMSCanType::AMS_CAN_TYPE_VIRTUAL }; @@ -975,6 +1025,32 @@ void AMSControl::UpdateAms(const std::string &series_name, { m_amswin->Layout(); } + + /*update switch status*/ + // Orca: inert on any printer without a Filament Track Switch — install is false, so the banner is + // never materialized, the glyph stays hidden, and every ShowRoad(true) below is a no-op. + const auto [install, ready] = isFilaSwitchReady(); + show_switcher_status(install && (!ready)); + bool isShow = install && m_total_ext_count >= 2; + if (m_switcher->IsShown() != isShow) + { + m_switcher->Show(isShow); + m_sizer_body->Layout(); + m_sizer_body->Fit(this); + this->Layout(); + this->Refresh(true); + this->Update(); + } + + /*update ext road visibility when fila switch installed*/ + bool road_visibility_changed = false; + for (auto& [ams_id, ams_item] : m_ams_item_list) { + if (!ams_item) continue; + // Orca: drop the external-spool road (AMSModel::EXT_AMS) while the switch routes all filament. + const bool should_show_road = !(install && ams_item->get_ams_model() == AMSModel::EXT_AMS); + if (ams_item->ShowRoad(should_show_road)) { road_visibility_changed = true; } + } + if (road_visibility_changed) { m_amswin->Layout(); } } void AMSControl::AddAmsPreview(AMSinfo info, AMSModel type) @@ -1596,6 +1672,54 @@ void AMSControl::on_ams_setting_click(wxMouseEvent &event) post_event(SimpleEvent(EVT_AMS_SETTINGS)); } +std::tuple<bool, bool> AMSControl::isFilaSwitchReady() +{ + DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager(); + if (!dev) return {false, false}; + MachineObject* obj = dev->get_selected_machine(); + if (!obj) return {false, false}; + // Orca: GetFilaSwitch() is a raw non-null accessor (BBS returns a shared_ptr). + DevFilaSwitch* fila_switch = obj->GetFilaSwitch(); + if (fila_switch) + { + return {fila_switch->IsInstalled(), fila_switch->IsReady()}; + } + return {false, false}; +} + +void AMSControl::show_switcher_status(bool show) +{ + // Orca: never materialize the banner on printers that never request it, so the AMS control is + // byte-identical without a Filament Track Switch (UpdateAms calls this with show=false every refresh). + if (!show && tipPanel == nullptr) { return; } + + if (tipPanel == nullptr) + { + m_sizer_body->Add(0, 0, 1, wxEXPAND | wxTOP, FromDIP(5)); + tipPanel = new wxPanel(m_amswin); + tipPanel->SetBackgroundColour(wxColour(255, 153, 0)); + tipSizer = new wxBoxSizer(wxHORIZONTAL); + tipPanel->SetSizer(tipSizer); + icon = new wxStaticBitmap(tipPanel, wxID_ANY, + wxArtProvider::GetBitmap(wxART_INFORMATION, wxART_MESSAGE_BOX, wxSize(FromDIP(16), FromDIP(16)))); + tipSizer->Add(icon, 0, wxALL, FromDIP(8)); + tipText = new wxStaticText(tipPanel, wxID_ANY, _L("AMS has not been initialized. Please initialize it before use.")); + tipText->SetForegroundColour(wxColour(255, 255, 255)); + tipText->SetFont(wxFont(10, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD)); + tipText->Wrap(-1); + tipText->SetMinSize(wxSize(-1, -1)); + tipSizer->Add(tipText, 0, wxALL | wxALIGN_CENTER_VERTICAL | wxEXPAND, FromDIP(8)); + m_sizer_body->Add(tipPanel, 1, wxEXPAND, 0); + } + if (tipPanel->IsShown() == show) + { + return; + } + tipPanel->Show(show); + m_amswin->Layout(); + m_amswin->Fit(); +} + void AMSControl::parse_object(MachineObject* obj) { if (!obj || obj->GetFilaSystem()->GetAmsList().size() == 0) { diff --git a/src/slic3r/GUI/Widgets/AMSControl.hpp b/src/slic3r/GUI/Widgets/AMSControl.hpp index 31c6b86feb..1fe8876eba 100644 --- a/src/slic3r/GUI/Widgets/AMSControl.hpp +++ b/src/slic3r/GUI/Widgets/AMSControl.hpp @@ -13,8 +13,10 @@ #include <wx/hyperlink.h> #include <wx/animate.h> #include <wx/dynarray.h> +#include <tuple> #include "slic3r/GUI/DeviceCore/DevExtruderSystem.h" +#include "slic3r/GUI/AMSDryControl.hpp" namespace Slic3r { namespace GUI { @@ -51,8 +53,16 @@ protected: int m_total_ext_count = 1; AMSextruder *m_extruder{nullptr}; + SwitcherImage *m_switcher{nullptr}; // Orca: filament-switch routing glyph (hidden unless a switch is installed) AMSRoadDownPart* m_down_road{ nullptr }; + // Orca: "AMS not initialized" warning banner, materialized lazily only when a switch needs it (see show_switcher_status) + wxBoxSizer* m_sizer_body{nullptr}; + wxPanel* tipPanel{nullptr}; + wxBoxSizer* tipSizer{nullptr}; + wxStaticBitmap* icon{nullptr}; + wxStaticText* tipText{nullptr}; + /*items*/ wxBoxSizer* m_sizer_ams_items{nullptr}; wxScrolledWindow* m_panel_prv_left {nullptr}; @@ -118,6 +128,7 @@ protected: AmsHumidityTipPopup m_Humidity_tip_popup; uiAmsPercentHumidityDryPopup* m_percent_humidity_dry_popup; + AMSDryCtrWin* m_ams_dry_ctr_win; std::string m_last_ams_id = ""; std::string m_last_tray_id = ""; @@ -151,11 +162,17 @@ public: void StopRridLoading(wxString amsid, wxString canid); void ShowFilamentTip(bool hasams = true); + // Orca: Filament Track Switch awareness. isFilaSwitchReady() resolves the selected machine and + // returns {installed, ready}; show_switcher_status() toggles the "AMS not initialized" banner. + std::tuple<bool, bool> isFilaSwitchReady(); + void show_switcher_status(bool show); + void UpdatePassRoad(string ams_id, AMSPassRoadType type, AMSPassRoadSTEP step); void CreateAms(); void CreateAmsDoubleNozzle(const std::string &series_name, const std::string& printer_type); void CreateAmsSingleNozzle(const std::string &series_name, const std::string &printer_type); void ClearAms(); + void UpdateAmsDryControl(MachineObject* obj); void UpdateAms(const std::string &series_name, const std::string &printer_type, std::vector<AMSinfo> ams_info, diff --git a/src/slic3r/GUI/Widgets/AMSItem.cpp b/src/slic3r/GUI/Widgets/AMSItem.cpp index 129eec9c61..2e47f01d6c 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.cpp +++ b/src/slic3r/GUI/Widgets/AMSItem.cpp @@ -742,6 +742,63 @@ void AMSExtImage::doRender(wxDC& dc) } +// Orca: SwitcherImage — routing glyph drawn when a Filament Track Switch is installed. +void SwitcherImage::paintEvent(wxPaintEvent &evt) +{ + wxPaintDC dc(this); + render(dc); +} + +void SwitcherImage::render(wxDC &dc) +{ +#ifdef __WXMSW__ + wxSize size = GetSize(); + wxMemoryDC memdc; + wxBitmap bmp(size.x, size.y); + memdc.SelectObject(bmp); + memdc.Blit({0, 0}, size, &dc, {0, 0}); + + { + wxGCDC dc2(memdc); + doRender(dc2); + } + + memdc.SelectObject(wxNullBitmap); + dc.DrawBitmap(bmp, 0, 0); +#else + doRender(dc); +#endif +} + +void SwitcherImage::doRender(wxDC &dc) +{ + auto size = GetSize(); + if (m_show_state){ + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush(*wxWHITE); + dc.DrawBitmap(m_switcher.bmp(), wxPoint((size.x - m_switcher.GetBmpSize().x) / 2, 0)); + } + Layout(); +} + +SwitcherImage::SwitcherImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos) +{ + wxWindow::Create(parent, id, pos, size); + SetBackgroundColour(StateColor::darkModeColorFor(*wxWHITE)); + m_show_state = true; + m_switcher = ScalableBitmap(this, file_name, 16); + m_file_name = file_name; + SetSize(size); + SetMinSize(size); + SetMaxSize(size); + + + Bind(wxEVT_PAINT, &SwitcherImage::paintEvent, this); +} + +SwitcherImage::~SwitcherImage() {} + + //DevAms Extruder AMSextruder::AMSextruder(wxWindow *parent, wxWindowID id, int nozzle_num, const wxPoint &pos, const wxSize &size) { @@ -3577,6 +3634,18 @@ void AmsItem::doRender(wxDC& dc) } } +// Orca: toggle the road segment below the item (m_panel_road). Used to drop the external-spool +// road when a Filament Track Switch is installed. No-op (returns false) when already in state. +bool AmsItem::ShowRoad(bool show) +{ + if (!m_panel_road) return false; + if (m_panel_road->IsShown() == show) return false; + m_panel_road->Show(show); + Layout(); + Refresh(); + return true; +} + void AmsItem::RenderLiteRoad(wxDC& dc, wxSize size) { auto end_top = size.x - FromDIP(3); if (m_panel_pos == AMSPanelPos::RIGHT_PANEL){ @@ -3706,4 +3775,342 @@ void AmsItem::show_sn_value(bool show) } } +DevExtruderImage::DevExtruderImage(wxWindow *parent, wxWindowID id, int extruder_num, const wxPoint &pos, const wxSize &size) : wxWindow(parent, id, pos, wxDefaultSize), m_extruder_num(extruder_num) +{ + // wxWindow::Create(parent, id, pos, wxSize(FromDIP(45), FromDIP(112))); + SetBackgroundColour(*wxWHITE); + SetSize(wxSize(FromDIP(48), FromDIP(112))); + SetMinSize(wxSize(FromDIP(48), FromDIP(112))); + SetMaxSize(wxSize(FromDIP(48), FromDIP(112))); + + + m_left_extruder_active_filled = new ScalableBitmap(this, "left_extruder_active_filled", 62); + m_left_extruder_active_empty = new ScalableBitmap(this, "left_extruder_active_empty", 62); + m_left_extruder_unactive_filled = new ScalableBitmap(this, "left_extruder_unactive_filled", 62); + m_left_extruder_unactive_empty = new ScalableBitmap(this, "left_extruder_unactive_empty", 62); + m_right_extruder_active_filled = new ScalableBitmap(this, "right_extruder_active_filled", 62); + m_right_extruder_active_empty = new ScalableBitmap(this, "right_extruder_active_empty", 62); + m_right_extruder_unactive_filled = new ScalableBitmap(this, "right_extruder_unactive_filled", 62); + m_right_extruder_unactive_empty = new ScalableBitmap(this, "right_extruder_unactive_empty", 62); + + m_extruder_single_nozzle_empty_load = new ScalableBitmap(this, "monitor_extruder_empty_load", 106); + m_extruder_single_nozzle_empty_unload = new ScalableBitmap(this, "monitor_extruder_empty_unload", 106); + m_extruder_single_nozzle_filled_load = new ScalableBitmap(this, "monitor_extruder_filled_load", 106); + m_extruder_single_nozzle_filled_unload = new ScalableBitmap(this, "monitor_extruder_filled_unload", 106); + + Bind(wxEVT_PAINT, &DevExtruderImage::paintEvent, this); +} + +void DevExtruderImage::msw_rescale() +{ + m_left_extruder_active_filled->msw_rescale(); + m_left_extruder_active_empty->msw_rescale(); + m_left_extruder_unactive_filled->msw_rescale(); + m_left_extruder_unactive_empty->msw_rescale(); + m_right_extruder_active_filled->msw_rescale(); + m_right_extruder_active_empty->msw_rescale(); + m_right_extruder_unactive_filled->msw_rescale(); + m_right_extruder_unactive_empty->msw_rescale(); + + m_extruder_single_nozzle_empty_load->msw_rescale(); + m_extruder_single_nozzle_empty_unload->msw_rescale(); + m_extruder_single_nozzle_filled_load->msw_rescale(); + m_extruder_single_nozzle_filled_unload->msw_rescale(); + Layout(); + Refresh(); +} + +void DevExtruderImage::render(wxDC &dc) +{ +#ifdef __WXMSW__ + wxSize size = GetSize(); + wxMemoryDC memdc; + wxBitmap bmp(size.x, size.y); + memdc.SelectObject(bmp); + memdc.Blit({0, 0}, size, &dc, {0, 0}); + + { + wxGCDC dc2(memdc); + doRender(dc2); + } + + memdc.SelectObject(wxNullBitmap); + dc.DrawBitmap(bmp, 0, 0); +#else + doRender(dc); +#endif +} + +void DevExtruderImage::doRender(wxDC &dc) +{ + auto size = GetSize(); + auto pot = wxPoint(size.x / 2, (size.y - m_left_extruder_active_filled->GetBmpSize().y) / 2); + + if (m_extruder_num >= 2) + { + ScalableBitmap *left_extruder_bmp{nullptr}; + ScalableBitmap *right_extruder_bmp{nullptr}; + + switch (m_right_ext_state) + { + case DevExtruderState::FILLED_LOAD: + right_extruder_bmp = current_extruder_loc == "right" ? m_right_extruder_active_filled : m_right_extruder_unactive_filled; + break; + case DevExtruderState::FILLED_UNLOAD: + right_extruder_bmp = current_extruder_loc == "right" ? m_right_extruder_active_filled : m_right_extruder_unactive_filled; + break; + case DevExtruderState::EMPTY_LOAD: + if (current_extruder_loc.empty()) + { + right_extruder_bmp = m_right_extruder_active_empty; + } + else + { + right_extruder_bmp = current_extruder_loc == "right" ? m_right_extruder_active_empty : m_right_extruder_unactive_empty; + } + break; + case DevExtruderState::EMPTY_UNLOAD: + right_extruder_bmp = current_extruder_loc == "right" ? m_right_extruder_active_empty : m_right_extruder_unactive_empty; + break; + default: break; + } + + switch (m_left_ext_state) + { + case DevExtruderState::FILLED_LOAD: + left_extruder_bmp = current_extruder_loc == "left" ? m_left_extruder_active_filled : m_left_extruder_unactive_filled; + break; + case DevExtruderState::FILLED_UNLOAD: + left_extruder_bmp = current_extruder_loc == "left" ? m_left_extruder_active_filled : m_left_extruder_unactive_filled; + break; + case DevExtruderState::EMPTY_LOAD: + if (current_extruder_loc.empty()) + { + left_extruder_bmp = m_left_extruder_active_empty; + } + else + { + left_extruder_bmp = current_extruder_loc == "left" ? m_left_extruder_active_empty : m_left_extruder_unactive_empty; + } + break; + case DevExtruderState::EMPTY_UNLOAD: + left_extruder_bmp = current_extruder_loc == "left" ? m_left_extruder_active_empty : m_left_extruder_unactive_empty; + break; + default: break; + } + + if (left_extruder_bmp) { dc.DrawBitmap(left_extruder_bmp->bmp(), pot.x - left_extruder_bmp->GetBmpWidth(), pot.y); } + if (right_extruder_bmp) { dc.DrawBitmap(right_extruder_bmp->bmp(), pot.x, pot.y); } + } + else + { + ScalableBitmap *extruder_bmp = nullptr; + switch (m_single_ext_state) + { + case DevExtruderState::FILLED_LOAD: + extruder_bmp = m_extruder_single_nozzle_filled_load; + break; + case DevExtruderState::FILLED_UNLOAD: + extruder_bmp = m_extruder_single_nozzle_filled_unload; + break; + case DevExtruderState::EMPTY_LOAD: + extruder_bmp = m_extruder_single_nozzle_empty_load; + break; + case DevExtruderState::EMPTY_UNLOAD: + extruder_bmp = m_extruder_single_nozzle_empty_unload; + break; + default: break; + } + + if (extruder_bmp) { dc.DrawBitmap(extruder_bmp->bmp(), pot.x - extruder_bmp->GetBmpWidth() / 2, (size.y - extruder_bmp->GetBmpHeight()) / 2); } + } +} + + +FeedDirectionDialog::FeedDirectionDialog(wxWindow* parent, + const int extruderNum, + const std::string& printer_type) + : wxDialog(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize), + m_extruder_num(extruderNum), + m_printer_type(printer_type) +{ + SetBackgroundColour(wxColour("#FFFFFF")); + SetMaxSize(wxSize(FromDIP(360), FromDIP(207))); + SetMinSize(wxSize(FromDIP(360), FromDIP(207))); + SetSize(wxSize(FromDIP(360), FromDIP(207))); + + wxBoxSizer* mainSizer = new wxBoxSizer(wxVERTICAL); + + wxGridSizer* topSizer = new wxGridSizer (1, 3, FromDIP(5), 0); + + m_radioHelper = new wxRadioButton(this, wxID_ANY, wxT(""), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + m_leftRadio = new wxRadioButton(this, wxID_ANY, + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); + m_rightRadio = new wxRadioButton(this, wxID_ANY, + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true))); + m_radioHelper->Show(false); + m_radioHelper->SetCanFocus(false); + + m_leftRadio->SetForegroundColour(*wxBLACK); + m_rightRadio->SetForegroundColour(*wxBLACK); + + topSizer->Add(m_leftRadio, 0, wxALIGN_CENTER | wxALL, FromDIP(20)); + m_extruderImage = new DevExtruderImage(this, wxID_ANY, m_extruder_num); + topSizer->Add(m_extruderImage, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + topSizer->Add(m_rightRadio, 0, wxALIGN_CENTER | wxALL, FromDIP(20)); + + mainSizer->AddStretchSpacer(1); + mainSizer->Add(topSizer, 1, wxEXPAND); + mainSizer->AddStretchSpacer(1); + + wxBoxSizer* bottomSizer = new wxBoxSizer(wxHORIZONTAL); + m_confirmBtn = new Button(this, _L("Confirm")); + m_confirmBtn->SetSize(wxSize(FromDIP(80), FromDIP(32))); + m_confirmBtn->Enable(false); + m_confirmBtn->SetFont(::Label::Body_14); + bottomSizer->Add(m_confirmBtn, 0, wxALIGN_RIGHT); + + mainSizer->Add(bottomSizer, 0, wxALIGN_RIGHT | wxBOTTOM | wxRIGHT, FromDIP(10)); + + SetSizer(mainSizer); + Layout(); + Centre(wxBOTH); + + m_lastChecked = m_radioHelper; + m_confirmBtn->Bind(wxEVT_BUTTON, &FeedDirectionDialog::OnConfirm, this); + m_leftRadio->Bind(wxEVT_RADIOBUTTON, &FeedDirectionDialog::OnRadioClicked, this); + m_rightRadio->Bind(wxEVT_RADIOBUTTON, &FeedDirectionDialog::OnRadioClicked, this); +} + +void FeedDirectionDialog::OnConfirm(wxCommandEvent& event) +{ + EndModal(wxID_OK); +} + +void FeedDirectionDialog::OnRadioClicked(wxCommandEvent& evt) +{ + auto clicked = static_cast<wxRadioButton*>(evt.GetEventObject()); + m_load_extruder_id = std::nullopt; + if (clicked == m_lastChecked) + { + m_radioHelper->SetValue(true); + m_lastChecked = m_radioHelper; + m_confirmBtn->Enable(false); + m_extruderImage->update(DevExtruderState::EMPTY_LOAD, DevExtruderState::EMPTY_LOAD); + m_extruderImage->setExtruderUsed(""); + + } + else + { + clicked->SetValue(true); + m_lastChecked = clicked; + m_confirmBtn->Enable(true); + + if (clicked == m_leftRadio) + { + m_extruderImage->update(DevExtruderState::FILLED_LOAD, DevExtruderState::EMPTY_LOAD); + m_extruderImage->setExtruderUsed("left"); + m_load_extruder_id = 1; + { + SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); + } + } + else if (clicked == m_rightRadio) + { + m_extruderImage->update(DevExtruderState::EMPTY_LOAD, DevExtruderState::FILLED_LOAD); + m_extruderImage->setExtruderUsed("right"); + m_load_extruder_id = 0; + { + SetTitle(wxString::Format(_L("Load %s to ") + _L(DevPrinterConfigUtil::get_toolhead_display_name(m_printer_type, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::LowerCase)), m_filament_id)); + } + } + } + m_leftRadio->Refresh(); + m_rightRadio->Refresh(); + Fit(); + Update(); +} + +std::optional<int> FeedDirectionDialog::GetExtruderID() +{ + if (m_extruderImage) + { + return m_load_extruder_id; + } + return std::nullopt; +} + +wxString FeedDirectionDialog::calcTrayName(MachineObject* obj, const std::string& amsID, const std::string& slotID) +{ + if (amsID.empty() || slotID.empty() || !obj) + return wxString(); + + auto filaSys = obj->GetFilaSystem(); + if (!filaSys) + return wxString(); + + DevAms* ams = filaSys->GetAmsById(amsID); + if (!ams) + return wxString(); + + int ams_id_int = std::stoi(amsID); + int slot_id_int = std::stoi(slotID); + int tray_id = 0; + + // Orca: DevAms::AmsType is the local enum (AMS / AMS_LITE / N3F / N3S); it has no EXT_SPOOL + // member, and external/virtual spools are not real DevAms objects (GetAmsById returns nullptr + // above), so the EXT_SPOOL branch from upstream is unnecessary here. + if (ams->GetAmsType() == DevAms::AMS || ams->GetAmsType() == DevAms::AMS_LITE || ams->GetAmsType() == DevAms::N3F) { + tray_id = ams_id_int * 4 + slot_id_int; + } else if (ams->GetAmsType() == DevAms::N3S) { + tray_id = ams_id_int + slot_id_int; + } else { + return wxString(); + } + + return wxGetApp().transition_tridid(tray_id); +} + +void FeedDirectionDialog::SetExtruderMapping(MachineObject* obj, + const std::string& currAmsId, + const std::string& currSlotId, + const std::vector<std::pair<std::string, std::string>>& extruderSlots) +{ + wxString filamentID = calcTrayName(obj, currAmsId, currSlotId); + if (filamentID.empty()) + return; + + m_filament_id = filamentID; + SetTitle(wxString::Format(_L("Load %s to "), filamentID)); + + std::vector<wxString> extruderMapping(extruderSlots.size()); + for (size_t i = 0; i < extruderSlots.size(); ++i) { + if (!extruderSlots[i].first.empty()) + extruderMapping[i] = calcTrayName(obj, extruderSlots[i].first, extruderSlots[i].second); + } + + if (extruderMapping.size() > 1 && extruderMapping[1] == filamentID) //left extruder + { + m_leftRadio->Enable(false); + m_confirmBtn->Enable(false); + m_extruderImage->update(DevExtruderState::EMPTY_LOAD, DevExtruderState::EMPTY_LOAD); + m_extruderImage->setExtruderUsed("right"); + } + else if (!extruderMapping.empty() && extruderMapping[0] == filamentID) //right extruder + { + m_rightRadio->Enable(false); + m_confirmBtn->Enable(false); + m_extruderImage->update(DevExtruderState::EMPTY_LOAD, DevExtruderState::EMPTY_LOAD); + m_extruderImage->setExtruderUsed("left"); + } + else + { + m_radioHelper->SetValue(true); + m_lastChecked = m_radioHelper; + m_confirmBtn->Enable(false); + m_extruderImage->update(DevExtruderState::EMPTY_LOAD, DevExtruderState::EMPTY_LOAD); + m_extruderImage->setExtruderUsed(""); + } +} + }} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Widgets/AMSItem.hpp b/src/slic3r/GUI/Widgets/AMSItem.hpp index 676fec6ec6..526fa82f36 100644 --- a/src/slic3r/GUI/Widgets/AMSItem.hpp +++ b/src/slic3r/GUI/Widgets/AMSItem.hpp @@ -12,6 +12,7 @@ #include <wx/hyperlink.h> #include <wx/animate.h> #include <wx/dynarray.h> +#include <optional> #define AMS_CONTROL_BRAND_COLOUR wxColour(0, 150, 136) @@ -400,6 +401,26 @@ private: }; +// Orca: routing glyph shown on the AMS control when a Filament Track Switch is installed. +class SwitcherImage: public wxWindow +{ +public: + void setShowState(bool show_state) { m_show_state = show_state; }; + // void msw_rescale(); + void paintEvent(wxPaintEvent &evt); + + void render(wxDC &dc); + bool m_show_state = {false}; + wxColour m_colour; + ScalableBitmap m_switcher; + string m_file_name; + // bool m_ams_loading{ false }; + void doRender(wxDC &dc); + SwitcherImage(wxWindow *parent, wxWindowID id, string file_name, const wxSize& size, const wxPoint &pos = wxDefaultPosition); + ~SwitcherImage(); +}; + + class AMSextruder : public wxWindow { private: @@ -771,6 +792,9 @@ public: void PlayRridLoading(wxString canid); void StopRridLoading(wxString canid); void msw_rescale(); + // Orca: hide/show the road segment below the item; used to drop the external-spool road + // when a Filament Track Switch is installed. Returns true if the visibility actually changed. + bool ShowRoad(bool show); void show_sn_value(bool show); void SetAmsStepExtra(wxString canid, AMSPassRoadType type, AMSPassRoadSTEP step); void SetAmsStep(std::string amsid, std::string canid, AMSPassRoadType type, AMSPassRoadSTEP step); @@ -849,6 +873,111 @@ wxDECLARE_EVENT(EVT_AMS_UNSELETED_AMS, wxCommandEvent); wxDECLARE_EVENT(EVT_VAMS_ON_FILAMENT_EDIT, wxCommandEvent); wxDECLARE_EVENT(EVT_AMS_SWITCH, SimpleEvent); +enum class DevExtruderState { + FILLED_LOAD, + FILLED_UNLOAD, + EMPTY_LOAD, + EMPTY_UNLOAD +}; + +class DevExtruderImage : public wxWindow +{ + ScalableBitmap *m_left_extruder_active_filled; + ScalableBitmap *m_left_extruder_active_empty; + ScalableBitmap *m_left_extruder_unactive_filled; + ScalableBitmap *m_left_extruder_unactive_empty; + ScalableBitmap *m_right_extruder_active_filled; + ScalableBitmap *m_right_extruder_active_empty; + ScalableBitmap *m_right_extruder_unactive_filled; + ScalableBitmap *m_right_extruder_unactive_empty; + + ScalableBitmap *m_extruder_single_nozzle_empty_load; + ScalableBitmap *m_extruder_single_nozzle_empty_unload; + ScalableBitmap *m_extruder_single_nozzle_filled_load; + ScalableBitmap *m_extruder_single_nozzle_filled_unload; + + DevExtruderState m_left_ext_state = {DevExtruderState::EMPTY_LOAD}; + DevExtruderState m_right_ext_state = {DevExtruderState::EMPTY_LOAD}; + DevExtruderState m_single_ext_state = {DevExtruderState::EMPTY_LOAD}; + +public: + DevExtruderImage(wxWindow *parent, wxWindowID id, + int extruder_num, + const wxPoint &pos = wxDefaultPosition, + const wxSize &size = wxDefaultSize); + ~DevExtruderImage() + { + + } + void update(DevExtruderState single_state) + { + m_single_ext_state = single_state; + } + void update(DevExtruderState left_state, DevExtruderState right_state) + { + m_left_ext_state = left_state; + m_right_ext_state = right_state; + } + + void msw_rescale(); + void setExtruderCount(int extruder_num) + { + m_extruder_num = extruder_num; + } + void setExtruderUsed(const std::string& loc) + { + if (current_extruder_loc == loc) { return; } + current_extruder_loc = loc; + Refresh(); + } +private: + void paintEvent(wxPaintEvent &evt) + { + wxPaintDC dc(this); + render(dc); + } + void render(wxDC &dc); + void doRender(wxDC &dc); + int m_extruder_num = 1; + std::string current_extruder_loc = ""; + +}; + +// Filament Track Switch: when the switch is installed and calibrated a filament can be routed to +// either extruder, so this dialog lets the user pick. GetExtruderID() returns the chosen extruder +// (1 = deputy/left, 0 = main/right) or nullopt if none was picked; that value is passed to +// MachineObject::command_ams_change_filament. Only constructed on the FTS-ready path. +class FeedDirectionDialog : public wxDialog +{ +public: + FeedDirectionDialog(wxWindow* parent, const int extruderNum, const std::string& printer_type = ""); + + std::optional<int> GetExtruderID(); + + void SetExtruderMapping(MachineObject* obj, + const std::string& currAmsId, + const std::string& currSlotId, + const std::vector<std::pair<std::string, std::string>>& extruderSlots); + +private: + static wxString calcTrayName(MachineObject* obj, const std::string& amsID, const std::string& slotID); + + int m_extruder_num{}; + std::string m_printer_type; + wxString m_filament_id{}; + wxRadioButton* m_radioHelper{nullptr}; + wxRadioButton* m_leftRadio{nullptr}; + wxRadioButton* m_rightRadio{nullptr}; + wxRadioButton* m_lastChecked{nullptr}; + DevExtruderImage* m_extruderImage{nullptr}; + Button* m_confirmBtn{nullptr}; + std::optional<int> m_load_extruder_id = std::nullopt; + + void OnConfirm(wxCommandEvent& event); + void OnRadioClicked(wxCommandEvent& evt); + +}; + }} // namespace Slic3r::GUI #endif // !slic3r_GUI_amscontrol_hpp_ diff --git a/src/slic3r/GUI/Widgets/FilamentLoad.cpp b/src/slic3r/GUI/Widgets/FilamentLoad.cpp index 502b153fef..2f2ef4dd92 100644 --- a/src/slic3r/GUI/Widgets/FilamentLoad.cpp +++ b/src/slic3r/GUI/Widgets/FilamentLoad.cpp @@ -3,6 +3,7 @@ #include "../BitmapCache.hpp" #include "../I18N.hpp" #include "../GUI_App.hpp" +#include "../DeviceCore/DevFilaSystem.h" #include <wx/simplebook.h> #include <wx/dcgraph.h> @@ -37,6 +38,28 @@ FilamentLoad::FilamentLoad(wxWindow* parent, wxWindowID id, const wxPoint& pos, //FILAMENT_CHANGE_STEP_STRING[FilamentStep::STEP_FEED_FILAMENT] = _L("Feed Filament"); FILAMENT_CHANGE_STEP_STRING[FilamentStep::STEP_CONFIRM_EXTRUDED] = _L("Confirm extruded"); FILAMENT_CHANGE_STEP_STRING[FilamentStep::STEP_CHECK_POSITION] = _L("Check filament location"); + + // Orca: labels for the device-numbered steps carried by the AMS (ams.cfs). Overlapping steps + // reuse the wording above so the current-step highlight (driven by the legacy ams_status_sub + // path) still text-matches; the switch/hotend/cooling and Filament Track Switch steps are new. + // STEP_CHECK_POSITION and STEP_CONFIRM_EXTRUDED share code 0x08, so CONFIRM is assigned first + // and CHECK_POSITION last, leaving code 0x08 mapped to "Check filament location" as on device. + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_IDLE] = _L("Idling..."); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PAUSE] = _L("Pause"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_HEAT_NOZZLE] = _L("Heat the nozzle"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_CUT_FILAMENT] = _L("Cut filament"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PULL_CURR_FILAMENT] = _L("Pull back the current filament"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PUSH_NEW_FILAMENT] = _L("Push new filament into extruder"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_GRAB_NEW_FILAMENT] = _L("Grab new filament"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PURGE_OLD_FILAMENT] = _L("Purge old filament"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_SWITCH_EXTRUDER] = _L("Switch") + " " + _L("extruder"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_SWITCH_HOTEND] = _L("Switch") + " " + _L("hotend"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_AMS_FILA_COOLING] = _L("Wait for AMS cooling"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PUSH_SWITCHER_FILA] = _L("Switch current filament at Filament Track Switch"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_PULL_SWITCHER_FILA] = _L("Pull back current filament at Filament Track Switch"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_SWITCHER_SWITCH] = _L("Switch track at Filament Track Switch"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_CONFIRM_EXTRUDED] = _L("Confirm extruded"); + DEV_FILAMENT_CHANGE_STEP_STRING[DevFilamentStep::STEP_CHECK_POSITION] = _L("Check filament location"); } void FilamentLoad::SetFilamentStep(FilamentStep item_idx, FilamentStepType f_type) @@ -124,11 +147,34 @@ void FilamentLoad::SetFilamentStep(FilamentStep item_idx, FilamentStepType f_typ step_control->SetSlotInformation(slot_info); } -void FilamentLoad::SetupSteps(bool has_fila_to_switch) { +void FilamentLoad::SetupSteps(MachineObject* obj_, bool has_fila_to_switch) { m_filament_load_steps->DeleteAllItems(); m_filament_unload_steps->DeleteAllItems(); m_filament_vt_load_steps->DeleteAllItems(); + // Orca: newer firmware sends the exact change-step sequence through the AMS (ams.cfs). When + // present, build the visible steps straight from that list and skip the hardcoded per-model + // sequences below. Inert on current firmware: the list is empty, so this branch is skipped and + // the legacy logic runs unchanged. + if (obj_ && obj_->GetFilaSystem() && !obj_->GetFilaSystem()->GetFilamentChangeSteps().empty()) { + const auto& steps = obj_->GetFilaSystem()->GetFilamentChangeSteps(); + for (auto step : steps) { + auto iter = DEV_FILAMENT_CHANGE_STEP_STRING.find(step); + if (iter == DEV_FILAMENT_CHANGE_STEP_STRING.end()) { + BOOST_LOG_TRIVIAL(error) << "Unknown filament change step: " << static_cast<int>(step); + continue; + } + + m_filament_load_steps->AppendItem(iter->second); + m_filament_unload_steps->AppendItem(iter->second); + m_filament_vt_load_steps->AppendItem(iter->second); + } + + Layout(); + Fit(); + return; + } + if (m_ams_model == AMSModel::GENERIC_AMS || m_ext_model == AMSModel::N3F_AMS || m_ext_model == AMSModel::N3S_AMS) { if (has_fila_to_switch) { m_filament_load_steps->AppendItem(FILAMENT_CHANGE_STEP_STRING[FilamentStep::STEP_HEAT_NOZZLE]); diff --git a/src/slic3r/GUI/Widgets/FilamentLoad.hpp b/src/slic3r/GUI/Widgets/FilamentLoad.hpp index c358816b77..e3cc6daf67 100644 --- a/src/slic3r/GUI/Widgets/FilamentLoad.hpp +++ b/src/slic3r/GUI/Widgets/FilamentLoad.hpp @@ -35,6 +35,10 @@ protected: public: std::map<FilamentStep, wxString> FILAMENT_CHANGE_STEP_STRING; + // Labels for the device-numbered steps reported by the AMS (ams.cfs). Keyed by the device + // enum, separate from the legacy FilamentStep map above. Only used when the AMS provides a + // step list; empty AMS list falls back to the legacy sequences below. + std::map<DevFilamentStep, wxString> DEV_FILAMENT_CHANGE_STEP_STRING; AMSModel m_ams_model{ AMSModel::GENERIC_AMS }; AMSModel m_ext_model{ AMSModel::AMS_LITE }; AMSModel m_is_none_ams_mode{ AMSModel::AMS_LITE }; @@ -44,7 +48,7 @@ public: void SetFilamentStep(FilamentStep item_idx, FilamentStepType f_type); void ShowFilamentTip(bool hasams = true); - void SetupSteps(bool is_extrusion_exist); + void SetupSteps(MachineObject* obj_, bool is_extrusion_exist); void show_nofilament_mode(bool show); void updateID(int ams_id, int slot_id) { m_ams_id = ams_id; m_slot_id = slot_id; }; diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp new file mode 100644 index 0000000000..05857c6d0d --- /dev/null +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.cpp @@ -0,0 +1,1290 @@ +#include "MultiNozzleSync.hpp" + +#include "../GUI_App.hpp" +#include "../I18N.hpp" +#include "../Plater.hpp" +#include "../DeviceManager.hpp" +#include "../DeviceCore/DevConfigUtil.h" +#include "../DeviceCore/DevNozzleSystem.h" +#include "../wxExtensions.hpp" +#include "Button.hpp" +#include "Label.hpp" +#include "StaticBox.hpp" +#include "libslic3r/PresetBundle.hpp" +#include "libslic3r/Utils.hpp" + +#include <algorithm> +#include <cmath> +#include <map> +#include <numeric> +#include <set> + +#include <wx/choice.h> +#include <wx/sizer.h> +#include <wx/stattext.h> + +namespace Slic3r { namespace GUI { + +wxDEFINE_EVENT(EVT_NOZZLE_SELECTED, wxCommandEvent); + +static const int LeftExtruderIdx = 0; +static const int RightExtruderIdx = 1; + +// ---- extruder_nozzle_stats config helpers --------------------------------------------------------------------- +// Orca: nozzle stats have no live runtime object; they are stored in the printer preset's `extruder_nozzle_stats` +// config key (ConfigOptionStrings, one encoded map per extruder) via get_extruder_nozzle_stats / +// save_extruder_nozzle_stats_to_string. These helpers read and write that config. + +int getExtruderNozzleCount(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type) +{ + if (!preset_bundle) + return 0; + auto *opt = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionStrings>("extruder_nozzle_stats"); + if (!opt) + return 0; + const auto stats = get_extruder_nozzle_stats(opt->values); + if (extruder_id < 0 || extruder_id >= (int) stats.size()) + return 0; + const auto it = stats[extruder_id].find(volume_type); + return it == stats[extruder_id].end() ? 0 : it->second; +} + +int getExtruderNozzleCountTotal(PresetBundle *preset_bundle, int extruder_id) +{ + if (!preset_bundle) + return 0; + auto *opt = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionStrings>("extruder_nozzle_stats"); + if (!opt) + return 0; + const auto stats = get_extruder_nozzle_stats(opt->values); + if (extruder_id < 0 || extruder_id >= (int) stats.size()) + return 0; + int sum = 0; + for (const auto &kv : stats[extruder_id]) + sum += kv.second; + return sum; +} + +// ---- ManualNozzleCountDialog ---------------------------------------------------------------------------------- + +ManualNozzleCountDialog::ManualNozzleCountDialog( + wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int max_nozzle_count, bool force_no_zero) + : DPIDialog(parent, wxID_ANY, _L("Set nozzle count"), wxDefaultPosition, wxDefaultSize, wxCAPTION | wxCLOSE_BOX) +{ + SetBackgroundColour(*wxWHITE); + + wxPanel *content = new wxPanel(this); + content->SetBackgroundColour(*wxWHITE); + wxBitmap nozzle_bmp = create_scaled_bitmap("hotend_thumbnail", nullptr, FromDIP(60)); + auto *nozzle_icon = new wxStaticBitmap(content, wxID_ANY, nozzle_bmp); + wxBoxSizer *content_sizer = new wxBoxSizer(wxHORIZONTAL); + content->SetSizer(content_sizer); + + wxBoxSizer *choice_sizer = new wxBoxSizer(wxVERTICAL); + choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L("Please set nozzle count")), 0, wxALL | wxALIGN_LEFT, FromDIP(10)); + + wxArrayString nozzle_choices; + for (int i = 0; i <= max_nozzle_count; ++i) + nozzle_choices.Add(wxString::Format("%d", i)); + + // A Hybrid extruder mixes Standard and High Flow nozzles, so it gets both count choices; the concrete + // types get exactly one. + if (volume_type == nvtStandard || volume_type == nvtHybrid) { + choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtStandard))), 0, wxALL | wxALIGN_LEFT, FromDIP(5)); + m_standard_choice = new wxChoice(content, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(100), -1), nozzle_choices); + m_standard_choice->SetSelection(standard_count); + choice_sizer->Add(m_standard_choice, 0, wxLEFT | wxBOTTOM | wxRIGHT, FromDIP(10)); + } + if (volume_type == nvtHighFlow || volume_type == nvtHybrid) { + choice_sizer->Add(new wxStaticText(content, wxID_ANY, _L(get_nozzle_volume_type_string(nvtHighFlow))), 0, wxALL | wxALIGN_LEFT, FromDIP(5)); + m_highflow_choice = new wxChoice(content, wxID_ANY, wxDefaultPosition, wxSize(FromDIP(100), -1), nozzle_choices); + m_highflow_choice->SetSelection(highflow_count); + choice_sizer->Add(m_highflow_choice, 0, wxLEFT | wxBOTTOM | wxRIGHT, FromDIP(10)); + } + + m_error_label = new wxStaticText(this, wxID_ANY, ""); + m_error_label->SetForegroundColour(wxColour("#E14747")); + m_error_label->Hide(); + + auto update_nozzle_error = [this, force_no_zero, content, max_nozzle_count](int standard_count, int highflow_count) { + const int total_count = standard_count + highflow_count; + if (0 < total_count && total_count <= max_nozzle_count && m_error_label->IsShown()) { + m_error_label->Hide(); + m_confirm_btn->Enable(); + Layout(); + Fit(); + } else if ((total_count == 0 && force_no_zero) || total_count > max_nozzle_count) { + const wxString error_tip = total_count == 0 ? _L("Error: Can not set both nozzle count to zero.") + : wxString::Format(_L("Error: Nozzle count can not exceed %d."), max_nozzle_count); + m_error_label->SetLabel(error_tip); + m_error_label->Wrap(content->GetSize().x); + m_error_label->Show(); + m_confirm_btn->Disable(); + Layout(); + Fit(); + } + }; + + if (m_standard_choice) + m_standard_choice->Bind(wxEVT_CHOICE, [this, update_nozzle_error](wxCommandEvent &e) { + update_nozzle_error(m_standard_choice->GetSelection(), m_highflow_choice ? m_highflow_choice->GetSelection() : 0); + e.Skip(); + }); + if (m_highflow_choice) + m_highflow_choice->Bind(wxEVT_CHOICE, [this, update_nozzle_error](wxCommandEvent &e) { + update_nozzle_error(m_standard_choice ? m_standard_choice->GetSelection() : 0, m_highflow_choice->GetSelection()); + e.Skip(); + }); + + content_sizer->Add(nozzle_icon, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(15)); + content_sizer->Add(choice_sizer, 0, wxALIGN_CENTRE_VERTICAL); + + m_confirm_btn = new Button(this, _L("Confirm")); + m_confirm_btn->SetStyle(ButtonStyle::Confirm, ButtonType::Window); + m_confirm_btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent &) { EndModal(wxID_OK); }); + + wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(content, 1, wxEXPAND); + main_sizer->Add(m_error_label, 0, wxALL, FromDIP(5)); + main_sizer->Add(m_confirm_btn, 0, wxALIGN_CENTER_HORIZONTAL | wxBOTTOM, FromDIP(20)); + + SetSizerAndFit(main_sizer); + CentreOnParent(); + wxGetApp().UpdateDlgDarkUI(this); +} + +int ManualNozzleCountDialog::GetNozzleCount(NozzleVolumeType volume_type) const +{ + if (volume_type == nvtStandard) + return m_standard_choice ? m_standard_choice->GetSelection() : 0; + if (volume_type == nvtHighFlow) + return m_highflow_choice ? m_highflow_choice->GetSelection() : 0; + if (volume_type == nvtHybrid) + return (m_standard_choice ? m_standard_choice->GetSelection() : 0) + + (m_highflow_choice ? m_highflow_choice->GetSelection() : 0); + return 0; +} + +// ---- free functions ------------------------------------------------------------------------------------------- + +// Session-scoped provenance of the current `extruder_nozzle_stats` values: device sync sets it so a manual +// flow switch keeps the machine-reported per-type breakdown; seeding clears it. The stats themselves do not +// survive a preset switch (the key is absent from saved presets, so the edited config is rebuilt without it), +// so this flag only protects the currently loaded values. +static bool s_nozzle_stats_from_machine = false; + +void setNozzleStatsFromMachine(bool from_machine) { s_nozzle_stats_from_machine = from_machine; } + +void setExtruderNozzleCount(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type, int nozzle_count, bool clear_all) +{ + if (!preset_bundle) + return; + // Hybrid is a mix marker, not a physical nozzle type — never a stats key. + if (volume_type == nvtHybrid) + return; + auto &config = preset_bundle->printers.get_edited_preset().config; + auto *opt = config.option<ConfigOptionStrings>("extruder_nozzle_stats", true); + if (!opt) + return; + + const int extruder_count = preset_bundle->get_printer_extruder_count(); + auto stats = get_extruder_nozzle_stats(opt->values); + if ((int) stats.size() < extruder_count) + stats.resize(extruder_count); + if (extruder_id < 0 || extruder_id >= (int) stats.size()) + return; + + if (clear_all) + stats[extruder_id].clear(); + stats[extruder_id][volume_type] = nozzle_count; + opt->values = save_extruder_nozzle_stats_to_string(stats); +} + +bool nozzle_diameter_supports_tpu_high_flow(double nozzle_diameter) +{ + // "Direct Drive TPU High Flow" is offered only on the H2D/H2D Pro 0.4 and 0.6 nozzles. + constexpr double kEps = 0.01; + return std::fabs(nozzle_diameter - 0.4) < kEps || std::fabs(nozzle_diameter - 0.6) < kEps; +} + +bool extruder_supports_tpu_high_flow(PresetBundle *preset_bundle, int extruder_id) +{ + if (!preset_bundle) + return false; + const auto *nozzle_diameter = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionFloats>("nozzle_diameter"); + return nozzle_diameter != nullptr && extruder_id >= 0 && extruder_id < (int) nozzle_diameter->values.size() && + nozzle_diameter_supports_tpu_high_flow(nozzle_diameter->values[extruder_id]); +} + +void updateNozzleCountDisplay(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type) +{ + auto *plater = wxGetApp().plater(); + if (!preset_bundle || !plater) + return; + + auto *max_nozzle_count = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + // Skip nil entries: a nullable-int nil is INT_MAX (> 1) and would otherwise falsely pass the gate. + const bool support_multi_nozzle = max_nozzle_count && + std::any_of(max_nozzle_count->values.begin(), max_nozzle_count->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); }); + + int display_count = -1; // hides the badge + if (support_multi_nozzle) + display_count = volume_type == nvtHybrid ? getExtruderNozzleCountTotal(preset_bundle, extruder_id) + : getExtruderNozzleCount(preset_bundle, extruder_id, volume_type); + plater->sidebar().set_extruder_nozzle_count(extruder_id, display_count); +} + +void seedExtruderNozzleStats(PresetBundle *preset_bundle) +{ + if (!preset_bundle) + return; + auto *max_nozzle_count = preset_bundle->printers.get_edited_preset().config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + auto *nozzle_volume_type = preset_bundle->project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); + + const int extruder_count = preset_bundle->get_printer_extruder_count(); + for (int eid = 0; eid < extruder_count; ++eid) { + NozzleVolumeType type = nvtStandard; + if (nozzle_volume_type && eid < (int) nozzle_volume_type->values.size()) + type = NozzleVolumeType(nozzle_volume_type->values[eid]); + // A fresh seed has no per-type breakdown to draw on, so a Hybrid extruder starts as all-Standard. + if (type == nvtHybrid) + type = nvtStandard; + int count = 1; + if (max_nozzle_count && eid < (int) max_nozzle_count->values.size() && + max_nozzle_count->values[eid] != ConfigOptionIntsNullable::nil_value()) + count = max_nozzle_count->values[eid]; + setExtruderNozzleCount(preset_bundle, eid, type, count, true); + } + s_nozzle_stats_from_machine = false; +} + +void onNozzleVolumeTypeSwitch(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType type) +{ + if (!preset_bundle) + return; + // Machine-synced stats carry the device's per-type breakdown; a flow switch must not collapse it. + if (s_nozzle_stats_from_machine) + return; + // Hybrid is a mix, not a type every nozzle shares, so there is nothing to carry over. + if (type == nvtHybrid) + return; + const int total = getExtruderNozzleCountTotal(preset_bundle, extruder_id); + setExtruderNozzleCount(preset_bundle, extruder_id, type, total, true); +} + +void manuallySetNozzleCount(int extruder_id) +{ + PresetBundle *preset_bundle = wxGetApp().preset_bundle; + if (!preset_bundle) + return; + + DynamicPrintConfig full_config = preset_bundle->full_config(); + auto *max_nozzle_count = full_config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + // Multi-nozzle gate: no-op for every single-nozzle / dual-extruder ({1,1}) printer. + // Skip nil entries: a nullable-int nil is INT_MAX (> 1) and would otherwise falsely pass the gate. + if (!max_nozzle_count || + !std::any_of(max_nozzle_count->values.begin(), max_nozzle_count->values.end(), + [](int v) { return v > 1 && v != ConfigOptionIntsNullable::nil_value(); })) + return; + + auto *nozzle_volume_type_opt = full_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); + if (!nozzle_volume_type_opt || extruder_id < 0 || extruder_id >= (int) nozzle_volume_type_opt->values.size() || + extruder_id >= (int) max_nozzle_count->values.size()) + return; + + const NozzleVolumeType volume_type = NozzleVolumeType(nozzle_volume_type_opt->values[extruder_id]); + const int standard_count = getExtruderNozzleCount(preset_bundle, extruder_id, nvtStandard); + const int highflow_count = getExtruderNozzleCount(preset_bundle, extruder_id, nvtHighFlow); + + // Require at least one nozzle for a Hybrid extruder (an empty mix is meaningless) and when the other + // extruder currently has none. + bool force_no_zero = volume_type == nvtHybrid; + if (nozzle_volume_type_opt->values.size() > 1) + force_no_zero |= getExtruderNozzleCountTotal(preset_bundle, 1 - extruder_id) == 0; + + ManualNozzleCountDialog dialog(wxGetApp().plater(), volume_type, standard_count, highflow_count, max_nozzle_count->values[extruder_id], force_no_zero); + if (dialog.ShowModal() == wxID_OK) { + if (volume_type == nvtHybrid) { + setExtruderNozzleCount(preset_bundle, extruder_id, nvtStandard, dialog.GetNozzleCount(nvtStandard), true); + setExtruderNozzleCount(preset_bundle, extruder_id, nvtHighFlow, dialog.GetNozzleCount(nvtHighFlow), false); + } else { + setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, dialog.GetNozzleCount(volume_type), true); + } + updateNozzleCountDisplay(preset_bundle, extruder_id, volume_type); + wxGetApp().plater()->update(); + } +} + +// ==== device-sync half ==== + +ExtruderBadge::ExtruderBadge(wxWindow* parent) : wxPanel(parent) +{ + wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + SetBackgroundColour("#F8F8F8"); + wxBitmap icon = create_scaled_bitmap("extruder_badge_none_selected", nullptr, FromDIP(90)); + + auto extruder_label = new Label(this, _L("Extruder")); + + badget = new wxStaticBitmap(this, wxID_ANY, icon); + + m_diameter_list = { "0.4","0.4" }; + m_volume_type_list = { NozzleVolumeType::nvtStandard,NozzleVolumeType::nvtStandard }; + + left_diameter_desp = new Label(this, _L(m_diameter_list[LeftExtruderIdx])); + right_diameter_desp = new Label(this, _L(m_diameter_list[RightExtruderIdx])); + left_flow_desp = new Label(this, _L(get_nozzle_volume_type_string(m_volume_type_list[LeftExtruderIdx]))); + right_flow_desp = new Label(this, _L(get_nozzle_volume_type_string(m_volume_type_list[RightExtruderIdx]))); + + + wxBoxSizer* top_h = new wxBoxSizer(wxVERTICAL); + top_h->Add(extruder_label, 0, wxALIGN_CENTER | wxBOTTOM, FromDIP(10)); + + main_sizer->Add(top_h, 0, wxEXPAND | wxTOP, FromDIP(5)); + main_sizer->Add(badget, 0, wxALIGN_CENTER | wxTOP, FromDIP(5)); + + wxBoxSizer* left_extruder = new wxBoxSizer(wxVERTICAL); + + left_extruder->Add(left_diameter_desp, 0, wxALIGN_CENTER | wxLEFT, FromDIP(12)); + left_extruder->Add(left_flow_desp, 0, wxALIGN_CENTER | wxLEFT, FromDIP(12)); + + wxBoxSizer* right_extruder = new wxBoxSizer(wxVERTICAL); + right_extruder->Add(right_diameter_desp, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(12)); + right_extruder->Add(right_flow_desp, 0, wxALIGN_CENTER | wxRIGHT, FromDIP(12)); + + wxBoxSizer* info_sizer = new wxBoxSizer(wxHORIZONTAL); + info_sizer->Add(left_extruder, 0); + info_sizer->AddStretchSpacer(); + info_sizer->Add(right_extruder, 0); + + main_sizer->Add(info_sizer, 0, wxEXPAND | wxTOP, FromDIP(5)); + + SetSizer(main_sizer); + Layout(); + Fit(); + wxGetApp().UpdateDarkUIWin(this); +} + +void ExtruderBadge::SetExtruderInfo(int extruder_id, const std::string& diameter, const NozzleVolumeType& volume_type) +{ + m_diameter_list[extruder_id] = diameter; + m_volume_type_list[extruder_id] = volume_type; + + if (extruder_id == LeftExtruderIdx) { + left_diameter_desp->SetLabel(diameter + " mm"); + left_flow_desp->SetLabel(_L(get_nozzle_volume_type_string(volume_type))); + } + else if (extruder_id == RightExtruderIdx) { + right_diameter_desp->SetLabel(diameter + " mm"); + right_flow_desp->SetLabel(_L(get_nozzle_volume_type_string(volume_type))); + } +} + +void ExtruderBadge::SetExtruderValid(bool right_on) +{ + if (!right_on) { + right_diameter_desp->SetLabel(""); + right_flow_desp->SetLabel(""); + } + std::string badge_name; + if (m_right_on) + badge_name = "extruder_badge_none_selected"; + else + badge_name = "extruder_badge_none_selected_single"; + wxBitmap icon = create_scaled_bitmap(badge_name, nullptr, FromDIP(90)); + badget->SetBitmap(icon); + + m_right_on = right_on; +} + +void ExtruderBadge::SetExtruderStatus(bool left_selected, bool right_selected) +{ + std::string badge_name; + if (m_right_on) { + if (left_selected && right_selected) + badge_name = "extruder_badge_both_selected"; + else if (left_selected) + badge_name = "extruder_badge_left_selected"; + else if (right_selected) + badge_name = "extruder_badge_right_selected"; + else + badge_name = "extruder_badge_none_selected"; + } + else if (left_selected) { + badge_name = "extruder_badge_left_selected_single"; + } + else { + badge_name = "extruder_badge_none_selected_single"; + } + + wxBitmap icon = create_scaled_bitmap(badge_name, nullptr, FromDIP(90)); + badget->SetBitmap(icon); + Layout(); +} + + +void ExtruderBadge::UnMarkRelatedItems(const NozzleOption& option) +{ + bool left_selected = true, right_selected = true; + + if (m_diameter_list[LeftExtruderIdx] == option.diameter && option.extruder_nozzle_stats.count(LeftExtruderIdx) + && option.extruder_nozzle_stats.at(LeftExtruderIdx).count(m_volume_type_list[LeftExtruderIdx]) + && option.extruder_nozzle_stats.at(LeftExtruderIdx).at(m_volume_type_list[LeftExtruderIdx])>0) + left_selected = false; + + if (m_diameter_list[RightExtruderIdx] == option.diameter && option.extruder_nozzle_stats.count(RightExtruderIdx) + && option.extruder_nozzle_stats.at(RightExtruderIdx).count(m_volume_type_list[RightExtruderIdx]) + && option.extruder_nozzle_stats.at(RightExtruderIdx).at(m_volume_type_list[RightExtruderIdx])>0) + right_selected = false; + + SetExtruderStatus(left_selected, right_selected); +} + +void ExtruderBadge::MarkRelatedItems(const NozzleOption& option) +{ + bool left_selected = false, right_selected = false; + + if (m_diameter_list[LeftExtruderIdx] == option.diameter && option.extruder_nozzle_stats.count(LeftExtruderIdx) + && option.extruder_nozzle_stats.at(LeftExtruderIdx).count(m_volume_type_list[LeftExtruderIdx]) + && option.extruder_nozzle_stats.at(LeftExtruderIdx).at(m_volume_type_list[LeftExtruderIdx]) > 0) + left_selected = true; + + if (m_diameter_list[RightExtruderIdx] == option.diameter && option.extruder_nozzle_stats.count(RightExtruderIdx) + && option.extruder_nozzle_stats.at(RightExtruderIdx).count(m_volume_type_list[RightExtruderIdx]) + && option.extruder_nozzle_stats.at(RightExtruderIdx).at(m_volume_type_list[RightExtruderIdx]) > 0) + right_selected = true; + + SetExtruderStatus(left_selected, right_selected); +} + +HotEndTable::HotEndTable(wxWindow* parent) : wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,wxBORDER_NONE) +{ + Bind(wxEVT_PAINT, &HotEndTable::OnPaint, this); + auto main_sizer = new wxBoxSizer(wxVERTICAL); + auto label = new Label(this, _L("Induction Hotend Rack")); + label->SetBackgroundColour("#F8F8F8"); + + m_arow_nozzle_box = CreateNozzleBox({ 0,2,4 }); + m_brow_nozzle_box = CreateNozzleBox({ 1,3,5 }); + main_sizer->Add(label, 0, wxALIGN_CENTER_HORIZONTAL | wxTOP | wxBOTTOM, FromDIP(5)); + main_sizer->Add(m_arow_nozzle_box, 0, wxLEFT | wxRIGHT, FromDIP(5)); + main_sizer->Add(m_brow_nozzle_box, 0, wxLEFT | wxRIGHT, FromDIP(5)); + SetBackgroundColour("#F8F8F8"); + + SetSizer(main_sizer); + Layout(); + Fit(); + wxGetApp().UpdateDarkUIWin(this); +} + +void HotEndTable::UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack) +{ + m_nozzle_rack = rack; + const auto& nozzle_rack = rack.lock(); + if (nozzle_rack) { + UpdateNozzleItems(m_nozzle_items, nozzle_rack); + } +} + +std::vector<int> HotEndTable::FilterHotEnds(const NozzleOption& option) +{ + auto rack = m_nozzle_rack.lock(); + if (!rack) + return {}; + + std::vector<HotEndAttr> nozzles_to_search; + + for (auto& item : option.extruder_nozzle_stats) { + for (auto& nozzle : item.second) { + HotEndAttr info; + info.diameter = option.diameter; + info.extruder_id = item.first; + info.volume_type = nozzle.first; + nozzles_to_search.emplace_back(info); + } + } + + std::vector<int> filtered_nozzles; + + for (auto& info : nozzles_to_search) { + + float diameter = atof(info.diameter.c_str()); + NozzleFlowType flow = DevNozzle::ToNozzleFlowType(info.volume_type); + int extruder_id = 1 - info.extruder_id; //physical + + auto nozzles = rack->GetNozzleSystem()->CollectNozzles(extruder_id, flow, diameter); + + for (auto& nozzle : nozzles) { + if (nozzle.IsOnRack()) + filtered_nozzles.emplace_back(nozzle.GetNozzleId()); + } + } + + return filtered_nozzles; +} + +void HotEndTable::MarkRelatedItems(const NozzleOption& option) +{ + const static StateColor bg_green( + std::pair<wxColour, int>(wxColour("#E5F0EE"), StateColor::Normal) + ); + + const static StateColor bd_green( + std::pair<wxColour, int>(wxColour("#009688"), StateColor::Normal) + ); + auto filtered_nozzles = FilterHotEnds(option); + for (auto nozzle_id : filtered_nozzles) { + auto iter = m_nozzle_items.find(nozzle_id); + if (iter == m_nozzle_items.end()) + continue; + auto& item = iter->second; + item->SetBackgroundColor(bg_green); + item->SetBorderColor(bd_green); + for (auto child : item->GetChildren()) { + child->SetBackgroundColour("#E5F0EE"); + } + } + wxGetApp().UpdateDarkUIWin(this); +} + +void HotEndTable::UnMarkRelatedItems(const NozzleOption& option) +{ + static const wxColour bg_color("#EEEEEE"); + static const wxColour bd_color("#CECECE"); + const static StateColor bg_green( + std::pair<wxColour, int>(bg_color, StateColor::Normal) + ); + + const static StateColor bd_green( + std::pair<wxColour, int>(bd_color, StateColor::Normal) + ); + auto filtered_nozzles = FilterHotEnds(option); + for (auto nozzle_id : filtered_nozzles) { + auto iter = m_nozzle_items.find(nozzle_id); + if (iter == m_nozzle_items.end()) + continue; + auto& item = iter->second; + item->SetBackgroundColor(bg_green); + item->SetBorderColor(bd_green); + for (auto child : item->GetChildren()) { + child->SetBackgroundColour(bg_color); + } + } + wxGetApp().UpdateDarkUIWin(this); +} + + + +StaticBox* HotEndTable::CreateNozzleBox(const std::vector<int>& nozzle_indices) +{ + StaticBox* nozzle_box = new StaticBox(this); + nozzle_box->SetBackgroundColour("#F8F8F8"); + nozzle_box->SetBorderColorNormal("#F8F8F8"); + nozzle_box->SetCornerRadius(0); + + wxSizer* h_sizer = new wxBoxSizer(wxHORIZONTAL); + for (auto idx : nozzle_indices) { + wgtDeviceNozzleRackNozzleItem* nozzle_item = new wgtDeviceNozzleRackNozzleItem(nozzle_box, idx); + nozzle_item->SetBackgroundColorNormal("#EEEEEE"); + for (auto& child : nozzle_item->GetChildren()) + child->SetBackgroundColour("#EEEEEE"); + m_nozzle_items[idx] = nozzle_item; + h_sizer->Add(nozzle_item, 0, wxALL, FromDIP(8)); + } + + nozzle_box->SetSizer(h_sizer); + + return nozzle_box; +} + +void HotEndTable::UpdateNozzleItems(const std::unordered_map<int, wgtDeviceNozzleRackNozzleItem*>& nozzle_items, std::shared_ptr<DevNozzleRack> nozzle_rack) +{ + for (auto& item : nozzle_items) + item.second->Update(nozzle_rack); +} + +void HotEndTable::OnPaint(wxPaintEvent& evt) +{ + wxPaintDC dc(this); + wxSize size = GetClientSize(); + + dc.SetPen(wxPen(wxColour("#EEEEEE"), 2)); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + dc.DrawRoundedRectangle(0, 0, size.GetWidth()-2, size.GetHeight()-2, 5); +} + +NozzleListTable::NozzleListTable(wxWindow* parent) : wxPanel(parent,wxID_ANY,wxDefaultPosition,wxDefaultSize ,wxNO_BORDER) +{ + m_web_view = wxWebView::New(this, wxID_ANY, wxEmptyString, wxDefaultPosition,wxDefaultSize,wxString::FromAscii(wxWebViewBackendDefault),wxNO_BORDER); + m_web_view->AddScriptMessageHandler("nozzleListTable"); + m_web_view->EnableContextMenu(false); + fs::path filepath = fs::path(resources_dir()) / "web/flush/NozzleListTable.html"; + wxFileName fn(wxString::FromUTF8(filepath.string())); + wxString url = wxFileSystem::FileNameToURL(fn); + m_web_view->LoadURL(url); + + auto sizer = new wxBoxSizer(wxVERTICAL); + sizer->AddStretchSpacer(0); + sizer->Add(m_web_view, 1, wxEXPAND); + sizer->AddStretchSpacer(0); + SetSizer(sizer); + Layout(); + + m_web_view->Bind(wxEVT_WEBVIEW_SCRIPT_MESSAGE_RECEIVED, [this,sizer](wxWebViewEvent& evt) { + std::string message = evt.GetString().ToStdString(); + BOOST_LOG_TRIVIAL(debug) << __FUNCTION__ << "Received message: " << message; + try { + json j = json::parse(message); + if (j["msg"].get<std::string>() == "init") { + auto table_obj_str = BuildTableObjStr(); + auto text_obj_str = BuildTextObjStr(); + CallAfter([table_obj_str, text_obj_str, this] { + wxString script1 = wxString::Format("initText(%s)", text_obj_str); + m_web_view->RunScript(script1); + wxString script2 = wxString::Format("initTable(%s)", table_obj_str); + m_web_view->RunScript(script2); + }); + } + else if (j["msg"].get<std::string>() == "updateList") { + auto table_obj_str = BuildTableObjStr(); + + CallAfter([table_obj_str, this] { + wxString script1 = wxString::Format("updateTable(%s)", table_obj_str); + m_web_view->RunScript(script1); + }); + + } + else if (j["msg"].get<std::string>() == "onSelect") { + int idx = j["index"].get<int>(); + m_selected_idx = idx; + SendSelectionChangedEvent(); + } + else if (j["msg"].get<std::string>() == "layout") { + int height = j["height"].get<int>(); + int width = j["width"].get<int>(); + wxSize table_size = wxSize(-1, FromDIP(height)); + m_web_view->SetSize(table_size); + m_web_view->SetMaxSize(table_size); + m_web_view->SetMinSize(table_size); + this->Layout(); + this->GetParent()->Layout(); + this->GetParent()->Fit(); + } + } + catch (...) { + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << "Failed to parse json message: " << message; + } + }); + + wxGetApp().UpdateDarkUIWin(this); +} + +wxString NozzleListTable::BuildTableObjStr() +{ + json obj; + obj["darkmode"] = wxGetApp().dark_mode(); + obj["data"] = json::array(); + for(size_t idx = 0; idx < m_nozzle_options.size(); ++idx){ + const auto& option = m_nozzle_options[idx]; + json json_opt; + json_opt["diameter"] = option.diameter; + json_opt["is_selected"] = idx == m_selected_idx; + json_opt["darkmode"] = wxGetApp().dark_mode(); + + json extruders = json::object(); + for (const auto& [extruderId, nozzleInfo] : option.extruder_nozzle_stats) { + nlohmann::json nozzleData; + nozzleData["type"] = ""; + nozzleData["count"] = std::accumulate(nozzleInfo.begin(), nozzleInfo.end(), 0, [](int val, auto elem) {return val + elem.second; }); + extruders[std::to_string(extruderId)] = nozzleData; + } + json_opt["extruders"] = extruders; + obj["data"].push_back(json_opt); + } + return wxString::FromUTF8(obj.dump().c_str()); +} + +void NozzleListTable::SendSelectionChangedEvent() +{ + wxCommandEvent event(EVT_NOZZLE_SELECTED, GetId()); + event.SetInt(m_selected_idx); + event.SetEventObject(this); + ProcessWindowEvent(event); +} +wxString NozzleListTable::BuildTextObjStr() +{ + wxString nozzle_selection = _L("Nozzle Selection"); + wxString nozzle_list = _L("Available Nozzles"); + std::string pt = wxGetApp().preset_bundle->printers.get_edited_preset().get_printer_type(wxGetApp().preset_bundle); + wxString Left = _L(DevPrinterConfigUtil::get_toolhead_display_name(pt, DEPUTY_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true)); + wxString Right = _L(DevPrinterConfigUtil::get_toolhead_display_name(pt, MAIN_EXTRUDER_ID, ToolHeadComponent::Extruder, ToolHeadNameCase::TitleCase, true)); + wxString highflow = _L(get_nozzle_volume_type_string(nvtHighFlow)); + wxString standard = _L(get_nozzle_volume_type_string(nvtStandard)); + + wxString text_obj = "{"; + text_obj += wxString::Format("\"nozzle_selection_label\":\"%s\",", nozzle_selection); + text_obj += wxString::Format("\"nozzle_list_label\":\"%s\",", nozzle_list); + text_obj += wxString::Format("\"left_label\":\"%s\",", Left); + text_obj += wxString::Format("\"right_label\":\"%s\",", Right); + text_obj += wxString::Format("\"highflow_label\":\"%s\",", highflow); + text_obj += wxString::Format("\"standard_label\":\"%s\",", standard); + text_obj += wxString::Format("\"language\":\"%s\"", wxGetApp().app_config->get_language_code()); + text_obj += "}"; + + return text_obj; +} + +void NozzleListTable::SetOptions(const std::vector<NozzleOption>& options,int default_select) +{ + m_nozzle_options = options; + m_selected_idx = default_select; + auto table_obj_str = BuildTableObjStr(); + wxString script1 = wxString::Format("updateTable(%s)", table_obj_str); + BOOST_LOG_TRIVIAL(info) << __FUNCTION__ << "update table " << script1; + +#if 1 + m_web_view->RunScript(script1); +#else + CallAfter([script1, this]() { + m_web_view->RunScript(script1); + }); +#endif +} + +MultiNozzleStatusTable::MultiNozzleStatusTable(wxWindow* parent): wxPanel(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxBORDER_NONE) +{ + m_badge = new ExtruderBadge(this); + + SetBackgroundColour(wxColour("#F8F8F8")); + + auto main_sizer = new wxBoxSizer(wxVERTICAL); + + auto title_panel = new wxPanel(this); + title_panel->SetBackgroundColour(0xEEEEEE); + auto title_sizer = new wxBoxSizer(wxHORIZONTAL); + title_panel->SetSizer(title_sizer); + + Label* static_text = new Label(this, _L("Nozzle Info")); + static_text->SetFont(Label::Head_13); + static_text->SetBackgroundColour(0xEEEEEE); + + title_sizer->Add(static_text, 0, wxALIGN_CENTER | wxALL, FromDIP(5)); + + main_sizer->Add(title_panel, 0, wxEXPAND); + main_sizer->AddSpacer(10); + + wxSizer* nozzle_area_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_table = new HotEndTable(this); + + nozzle_area_sizer->Add(m_badge, 0, wxLEFT | wxRIGHT, FromDIP(20)); + nozzle_area_sizer->Add(m_table, 0, wxRIGHT, FromDIP(10)); + + main_sizer->Add(nozzle_area_sizer); + main_sizer->AddSpacer(FromDIP(5)); + + SetSizer(main_sizer); + Layout(); + Fit(); + wxGetApp().UpdateDarkUIWin(this); +} + +void MultiNozzleStatusTable::MarkRelatedItems(const NozzleOption& option) +{ + m_table->MarkRelatedItems(option); + + m_badge->MarkRelatedItems(option); +} + +void MultiNozzleStatusTable::UnMarkRelatedItems(const NozzleOption& option) +{ + m_table->UnMarkRelatedItems(option); + + m_badge->UnMarkRelatedItems(option); +} + +void MultiNozzleStatusTable::UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack) +{ + if (m_table) + m_table->UpdateRackInfo(rack); + if (m_badge) { + auto nozzle_rack = rack.lock(); + if (!nozzle_rack) + return; + auto nozzles_in_extruder = nozzle_rack->GetNozzleSystem()->GetExtNozzles(); + bool has_right = false; + for (auto& elem : nozzles_in_extruder) { + auto& nozzle = elem.second; + int extruder_id = nozzle.AtLeftExtruder() ? 0 : 1; + if (nozzle.AtRightExtruder()) + has_right = true; + + NozzleVolumeType volume_type = DevNozzle::ToNozzleVolumeType(nozzle.m_nozzle_flow); + + m_badge->SetExtruderInfo(extruder_id, format_diameter_to_str(nozzle.GetNozzleDiameter()), volume_type); + } + m_badge->SetExtruderValid(has_right); + } +} + + +Slic3r::GUI::MultiNozzleSyncDialog::MultiNozzleSyncDialog(wxWindow* parent,std::weak_ptr<DevNozzleRack> rack) : DPIDialog(parent, wxID_ANY, _L("Sync Nozzle status"),wxDefaultPosition, wxDefaultSize,wxDEFAULT_DIALOG_STYLE) +{ + m_nozzle_rack = rack; + wxSizer* main_sizer = new wxBoxSizer(wxVERTICAL); + SetBackgroundColour(*wxWHITE); + + m_tips = new Label(this, ""); + wxBoxSizer* label_sizer = new wxBoxSizer(wxHORIZONTAL); + label_sizer->Add(m_tips, 0, wxLEFT | wxRIGHT, FromDIP(25)); + main_sizer->Add(label_sizer, 0, wxTOP | wxBOTTOM, FromDIP(15)); + + m_list_table = new NozzleListTable(this); + + m_list_table->Bind(EVT_NOZZLE_SELECTED, [this](wxCommandEvent& evt) { + int idx = evt.GetInt(); + this->OnSelectRadio(idx); + }); + + main_sizer->Add(m_list_table, 0, wxEXPAND | wxLEFT | wxRIGHT, FromDIP(25)); + + m_nozzle_table = new MultiNozzleStatusTable(this); + wxBoxSizer* table_sizer = new wxBoxSizer(wxHORIZONTAL); + table_sizer->Add(m_nozzle_table, 0, wxLEFT | wxRIGHT, FromDIP(25)); + main_sizer->Add(table_sizer, 0, wxTOP | wxBOTTOM, FromDIP(15)); + + wxBoxSizer* button_sizer = new wxBoxSizer(wxHORIZONTAL); + + m_cancel_btn = new Button(this, _L("Cancel"), "", 0, 0, wxID_OK); + m_confirm_btn = new Button(this, _L("Confirm"), "", 0, 0, wxID_CANCEL); + + m_caution = new Label(this, _L("Caution: Mixing nozzle diameters in one print is not supported. If the selected size is only on one extruder, single-extruder printing will be enforced.")); + m_caution->SetForegroundColour("#909090"); + main_sizer->Add(m_caution, 0, wxLEFT | wxRIGHT, FromDIP(25)); + + StateColor btn_bg_green( + std::pair<wxColour, int>(wxColour(144, 144, 144), StateColor::Disabled), + std::pair<wxColour, int>(wxColour(0, 137, 123), StateColor::Pressed), + std::pair<wxColour, int>(wxColour(38, 166, 154), StateColor::Hovered), + std::pair<wxColour, int>(wxColour(0, 150, 136), StateColor::Normal) + ); + + StateColor btn_text_green( + std::pair<wxColour, int>(wxColour(255, 255, 254), StateColor::Normal) + ); + + + m_confirm_btn->SetBackgroundColor(btn_bg_green); + m_confirm_btn->SetMinSize(wxSize(FromDIP(55), FromDIP(24))); + m_confirm_btn->SetCornerRadius(FromDIP(12)); + m_confirm_btn->SetBackgroundColor(btn_bg_green); + m_confirm_btn->SetTextColor(btn_text_green); + m_confirm_btn->SetFocus(); + + m_cancel_btn->SetMinSize(wxSize(FromDIP(55), FromDIP(24))); + m_cancel_btn->SetCornerRadius(FromDIP(12)); + + button_sizer->AddStretchSpacer(); + button_sizer->Add(m_cancel_btn, 0, wxALL, FromDIP(10)); + button_sizer->Add(m_confirm_btn, 0, wxALL, FromDIP(10)); + + main_sizer->Add(button_sizer, 0, wxEXPAND | wxALL, FromDIP(10)); + + SetSizer(main_sizer); + + //main_sizer->SetSizeHints(this); + main_sizer->Fit(this); + + int table_width = m_nozzle_table->GetBestSize().GetWidth(); + m_tips->Wrap(table_width); + m_tips->SetMaxSize(wxSize(table_width, -1)); + + m_caution->Wrap(table_width); + m_caution->SetMaxSize(wxSize(table_width, -1)); + + Layout(); + + m_refresh_timer = new wxTimer(this); + Bind(wxEVT_TIMER, &MultiNozzleSyncDialog::OnRefreshTimer, this); + CenterOnParent(); + wxGetApp().UpdateDlgDarkUI(this); +} + + +void MultiNozzleSyncDialog::OnRackStatusReadingFinished(wxEvent& evt) { + if (!IsShown()) return; + + m_refreshing = false; + if (m_refresh_timer) + m_refresh_timer->Stop(); +#if 1 + if (!UpdateUi(m_nozzle_rack)) + EndModal(wxID_OK); +#else + if(!UpdateUoi(m_nozzle_rack)){ + CallAfter([this]() { + EndModal(wxID_OK); + }); + } +#endif +} + +void MultiNozzleSyncDialog::OnRefreshTimer(wxTimerEvent& evt){ + if(!m_refreshing) + return; + auto nozzle_rack = m_nozzle_rack.lock(); + if(!nozzle_rack) + return; + + int reading_count = nozzle_rack->GetReadingCount(); + int reading_idx = nozzle_rack->GetReadingIdx(); + + wxString tip = wxString::Format(_L("Refresh %d/%d..."), reading_idx, reading_count); + m_confirm_btn->SetLabel(tip); + m_confirm_btn->Fit(); + if (m_confirm_btn->GetParent()) + m_confirm_btn->GetParent()->Layout(); + + m_confirm_btn->Disable(); + m_cancel_btn->Disable(); +} + +void MultiNozzleSyncDialog::UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack) +{ + m_nozzle_rack = rack; + UpdateUi(rack); +} + +void MultiNozzleSyncDialog::OnSelectRadio(int select_idx) +{ + if (m_nozzle_option_idx != -1) + m_nozzle_table->UnMarkRelatedItems(m_nozzle_option_values[m_nozzle_option_idx]); + m_nozzle_option_idx = select_idx; + m_nozzle_table->MarkRelatedItems(m_nozzle_option_values[m_nozzle_option_idx]); +} + +bool MultiNozzleSyncDialog::hasMultiDiameters(const std::vector<MultiNozzleUtils::NozzleGroupInfo>& group_infos) +{ + if (group_infos.empty()) + return false; + return !std::all_of(group_infos.begin(), group_infos.end(), [val = group_infos.front()](auto& elem) {return val.diameter == elem.diameter; }); +} + + +std::vector<NozzleOption> MultiNozzleSyncDialog::GetNozzleOptions(const std::vector<MultiNozzleUtils::NozzleGroupInfo>& nozzle_groups) +{ + std::vector<NozzleOption> options; + + std::set<std::string> diameters; + std::multimap<std::string, MultiNozzleUtils::NozzleGroupInfo> groups_mapped_for_diameter; + for (auto& nozzle_group : nozzle_groups) { + groups_mapped_for_diameter.insert({ nozzle_group.diameter,nozzle_group }); + } + +#if ENABLE_MIX_FLOW_PRINT + for (auto it = groups_mapped_for_diameter.begin(); it != groups_mapped_for_diameter.end(); ) { + NozzleOption option; + const auto& diameter = it->first; + auto range = groups_mapped_for_diameter.equal_range(diameter); + + option.diameter = diameter; + for (auto val_it = range.first; val_it != range.second; ++val_it) { + const auto& elem = val_it->second; + option.extruder_nozzle_stats[elem.extruder_id][elem.volume_type] += elem.nozzle_count; + } + options.emplace_back(std::move(option)); + it = range.second; + } +#else + for (auto it = groups_mapped_for_diameter.begin(); it != groups_mapped_for_diameter.end(); ) { + const auto& diameter = it->first; + auto range = groups_mapped_for_diameter.equal_range(diameter); + + std::vector<std::pair<NozzleVolumeType, int>> left_nozzles; + std::vector<std::pair<NozzleVolumeType, int>> right_nozzles; + + for (auto val_it = range.first; val_it != range.second; ++val_it) { + const auto& elem = val_it->second; + if (elem.extruder_id == 0) + left_nozzles.emplace_back(elem.volume_type, elem.nozzle_count); + else + right_nozzles.emplace_back(elem.volume_type, elem.nozzle_count); + } + + for (const auto& left_nozzle : left_nozzles.empty() ? std::vector<std::pair<NozzleVolumeType, int>>{{}} : left_nozzles) { + for (const auto& right_nozzle : right_nozzles.empty() ? std::vector<std::pair<NozzleVolumeType, int>>{{}} : right_nozzles) { + NozzleOption option; + option.diameter = diameter; + + if (!left_nozzles.empty()) { + option.extruder_nozzle_stats[0] = { left_nozzle.first, left_nozzle.second }; + } + + if (!right_nozzles.empty()) { + option.extruder_nozzle_stats[1] = { right_nozzle.first, right_nozzle.second }; + } + + options.emplace_back(std::move(option)); + } + } + + it = range.second; + } +#endif + return options; +} + +bool MultiNozzleSyncDialog::UpdateOptionList(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable) +{ + const auto& nozzle_rack = rack.lock(); + if (!nozzle_rack) + return true; + bool has_unknown = nozzle_rack->HasUnknownNozzles() && !ignore_unknown; + bool has_unreliable = nozzle_rack->HasUnreliableNozzles() && !ignore_unreliable; + + if (has_unknown || has_unreliable) { + m_list_table->Hide(); + return true; + } + + m_list_table->Show(); + + m_nozzle_option_values.clear(); + + auto options = GetNozzleOptions(nozzle_rack->GetNozzleSystem()->GetNozzleGroups()); + + int recommend_idx = std::max_element(options.begin(), options.end(), [](const NozzleOption& opt1, const NozzleOption& opt2) { + int count1 = 0, count2 = 0; + for (auto elem : opt1.extruder_nozzle_stats) { + for (auto& stats : elem.second) + count1 += stats.second; + } + for (auto elem : opt2.extruder_nozzle_stats) { + for (auto& stats : elem.second) + count2 += stats.second; + } + return count1 < count2; + }) - options.begin(); + + m_nozzle_option_values = options; + OnSelectRadio(recommend_idx); + m_list_table->SetOptions(options,recommend_idx); + + if (!has_unknown && !has_unreliable && options.size() == 1) { + return false; + } + return true; +} + +void MultiNozzleSyncDialog::UpdateTip(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable) +{ + const auto& nozzle_rack = rack.lock(); + if (!nozzle_rack) + return; + + bool has_unknown = nozzle_rack->HasUnknownNozzles() && !ignore_unknown; + bool has_unreliable = nozzle_rack->HasUnreliableNozzles() && !ignore_unreliable; + + if (has_unknown && has_unreliable) { + m_tips->SetLabel(_L("Unknown nozzle detected. Refresh to update info (unrefreshed nozzles will be excluded during slicing). Verify nozzle diameter & flow rate against displayed values.")); + m_caution->Hide(); + } + else if (has_unknown) { + m_tips->SetLabel(_L("Unknown nozzle detected. Refresh to update (unrefreshed nozzles will be skipped in slicing).")); + m_caution->Hide(); + } + else if (has_unreliable) { + m_tips->SetLabel(_L("Please confirm whether the required nozzle diameter and flow rate match the currently displayed values.")); + m_caution->Hide(); + } + else { + m_tips->SetLabel(_L("Your printer has different nozzles installed. Please select a nozzle for this print.")); + m_caution->Show(); + } +} + +int MultiNozzleSyncDialog::ShowModal() +{ + bool res = UpdateUi(m_nozzle_rack); + if (!res) + return wxID_OK; + + return DPIDialog::ShowModal(); + +} + +MultiNozzleSyncDialog::~MultiNozzleSyncDialog() +{ + if (auto rack = m_nozzle_rack.lock()) { + rack->Unbind(DEV_RACK_EVENT_READING_FINISHED, &MultiNozzleSyncDialog::OnRackStatusReadingFinished, this); + } + if (m_refresh_timer) + m_refresh_timer->Stop(); +} + +void MultiNozzleSyncDialog::UpdateButton(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable) +{ + const auto& nozzle_rack = rack.lock(); + if (!nozzle_rack) + return; + + if (m_refreshing) + return; + + bool has_unknown = nozzle_rack->HasUnknownNozzles() && !ignore_unknown; + bool has_unreliable = nozzle_rack->HasUnreliableNozzles() && !ignore_unreliable; + + auto refresh_cmd = [rack, this]() { + auto nozzle_rack = m_nozzle_rack.lock(); + if (!nozzle_rack) + return; + nozzle_rack->CtrlRackReadAll(); + m_refreshing = true; + if (m_refresh_timer) + m_refresh_timer->Start(500); + nozzle_rack->Bind(DEV_RACK_EVENT_READING_FINISHED, &MultiNozzleSyncDialog::OnRackStatusReadingFinished, this); + }; + + auto trust_cmd = [rack, this]() { + auto nozzle_rack = rack.lock(); + if (!nozzle_rack) + return; + nozzle_rack->CtrlRackConfirmAll(); + UpdateUi(rack, true, false); + }; + + auto ignore_opt = [rack,this]() { + if (!UpdateUi(rack, true, true)) + EndModal(wxID_OK); + }; + + m_cancel_btn->Enable(); + m_confirm_btn->Enable(); + + if (has_unknown && has_unreliable) { + m_cancel_btn->Show(); + m_confirm_btn->Show(); + + m_cancel_btn->SetLabel(_L("Ignore")); + m_confirm_btn->SetLabel(_L("Refresh")); + + m_cancel_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, ignore_opt](auto& e) {ignore_opt(); }); + m_confirm_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, refresh_cmd](auto& e) {refresh_cmd(); }); + } + else if (has_unknown) { + m_cancel_btn->Show(); + m_confirm_btn->Show(); + + m_cancel_btn->SetLabel(_L("Ignore")); + m_confirm_btn->SetLabel(_L("Refresh")); + + m_cancel_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, ignore_opt](auto& e) {ignore_opt(); }); + m_confirm_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, refresh_cmd](auto& e) {refresh_cmd(); }); + } + else if (has_unreliable) { + m_cancel_btn->Show(); + m_confirm_btn->Show(); + + m_cancel_btn->SetLabel(_L("Refresh")); + m_confirm_btn->SetLabel(_L("Confirm")); + + m_cancel_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, refresh_cmd](auto& e) {refresh_cmd(); }); + m_confirm_btn->Bind(wxEVT_LEFT_DOWN, [this, rack, trust_cmd](auto& e) {trust_cmd(); }); + + } + else { + m_cancel_btn->Hide(); + m_confirm_btn->Show(); + m_confirm_btn->SetLabel(_L("OK")); + m_confirm_btn->Bind(wxEVT_LEFT_DOWN, [this](auto& e) {EndModal(wxID_OK); }); + } + +} + +bool MultiNozzleSyncDialog::UpdateUi(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable) +{ + m_nozzle_table->UpdateRackInfo(rack); + bool res = UpdateOptionList(rack, ignore_unknown, ignore_unreliable); + if (!res) + return false; + + UpdateTip(rack, ignore_unknown, ignore_unreliable); + UpdateButton(rack, ignore_unknown, ignore_unreliable); + + Layout(); + + int table_width = m_nozzle_table->GetBestSize().GetWidth(); + m_tips->Wrap(table_width); + m_tips->SetMaxSize(wxSize(table_width, -1)); + m_caution->Wrap(table_width); + m_caution->SetMaxSize(wxSize(table_width, -1)); + Fit(); + return true; +} + + +std::optional<NozzleOption> tryPopUpMultiNozzleDialog(MachineObject* obj) +{ + if (!obj) + return std::nullopt; + auto rack = obj->GetNozzleSystem()->GetNozzleRack(); + if (!rack || !rack->IsSupported()) + return std::nullopt; + MultiNozzleSyncDialog dialog(wxGetApp().plater_,rack); + + bool has_unreliable = rack->HasUnreliableNozzles(); + bool has_unknown = rack->HasUnknownNozzles(); + + auto config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + + if (dialog.ShowModal() == wxID_OK) { + auto selected_option = dialog.GetSelectedOption(); + if (!selected_option) + return std::nullopt; + auto& preset_bundle = GUI::wxGetApp().preset_bundle; + auto& project_config = preset_bundle->project_config; + + ConfigOptionEnumsGeneric* nozzle_volume_type_opt = project_config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type"); + + // write to preset bundle config + for (int extruder_id = 0; extruder_id < 2; ++extruder_id) { + NozzleVolumeType volume_type; + int nozzle_count; + bool clear_all = true; + if (!selected_option->extruder_nozzle_stats.count(extruder_id)) { + nozzle_count = 0; + // Reset the concrete volume types (Standard/High Flow); Hybrid is a mix marker, never a stats key. + // TPU High Flow is a concrete variant that exists only on 0.4/0.6 nozzles, so reset it too, but + // only there (same guard that skips High Flow on 0.2). + std::vector<NozzleVolumeType> reset_types{nvtStandard, nvtHighFlow}; + if (extruder_supports_tpu_high_flow(preset_bundle, extruder_id)) + reset_types.push_back(nvtTPUHighFlow); + for (NozzleVolumeType vt : reset_types) { + volume_type = vt; + setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, nozzle_count, clear_all); + clear_all = false; + } + } + else { + for (auto& stat : selected_option->extruder_nozzle_stats[extruder_id]) { + volume_type = stat.first; + nozzle_count = stat.second; + setExtruderNozzleCount(preset_bundle, extruder_id, volume_type, nozzle_count, clear_all); + clear_all = false; + } + } + } + // The stats now hold the device's per-type breakdown: protect it from being collapsed by a manual + // flow switch, and refresh the sidebar badges. + setNozzleStatsFromMachine(true); + if (nozzle_volume_type_opt) { + for (int extruder_id = 0; extruder_id < 2 && extruder_id < (int) nozzle_volume_type_opt->values.size(); ++extruder_id) + updateNozzleCountDisplay(preset_bundle, extruder_id, NozzleVolumeType(nozzle_volume_type_opt->values[extruder_id])); + } + return selected_option; + } + + return std::nullopt; +} + +}} // namespace Slic3r::GUI diff --git a/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp new file mode 100644 index 0000000000..18a5ecbd95 --- /dev/null +++ b/src/slic3r/GUI/Widgets/MultiNozzleSync.hpp @@ -0,0 +1,258 @@ +#ifndef slic3r_GUI_MultiNozzleSync_hpp_ +#define slic3r_GUI_MultiNozzleSync_hpp_ + +// Multi-nozzle GUI. +// +// Two surfaces live here: +// - The DEVICE-INDEPENDENT "manual nozzle count" surface (ManualNozzleCountDialog + helpers): lets the +// user declare, per extruder, how many physical nozzles of each volume type a multi-nozzle (H2C) +// extruder carries. Persisted into the printer preset's `extruder_nozzle_stats` config key, which the +// multi-nozzle slicer already consumes (ToolOrdering::build_multi_nozzle_group_result). +// - The DEVICE-SYNC surface (MultiNozzleSyncDialog / HotEndTable / NozzleListTable / +// tryPopUpMultiNozzleDialog): reads the live nozzle rack from the connected machine via +// DevNozzleRack / wgtDeviceNozzleRackNozzleItem and lets the user pick a nozzle option to slice with. +// Popped from the sidebar "sync machine" button when the selected printer is an H2C. +// +// Everything here is inert for existing printers: the manual entry points are gated on the printer having +// any extruder with `extruder_max_nozzle_count > 1` (no shipping single-nozzle/dual-extruder profile sets +// it), and the device-sync path only runs for a connected machine whose rack reports as supported. + +#include "../GUI_Utils.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" +#include "slic3r/GUI/DeviceCore/DevNozzleRack.h" +#include "slic3r/GUI/DeviceTab/wgtDeviceNozzleRackNozzleItem.h" + +#include <wx/panel.h> +#include <wx/webview.h> + +#include <memory> +#include <optional> +#include <unordered_map> +#include <vector> + +class wxChoice; +class wxStaticText; +class wxStaticBitmap; +class Button; // global widget (src/slic3r/GUI/Widgets/Button.hpp), not in the Slic3r::GUI namespace +class Label; // global widget (src/slic3r/GUI/Widgets/Label.hpp) +class StaticBox; + +namespace Slic3r { +class PresetBundle; +class MachineObject; + +namespace GUI { + +#define ENABLE_MIX_FLOW_PRINT 1 + +#if ENABLE_MIX_FLOW_PRINT +struct NozzleOption +{ + std::string diameter; + std::unordered_map<int, std::unordered_map<NozzleVolumeType, int>> extruder_nozzle_stats; +}; +#else +struct NozzleOption +{ + std::string diameter; + std::unordered_map<int, std::pair<NozzleVolumeType, int>> extruder_nozzle_stats; +}; +#endif + +// Dialog to manually set the per-volume-type physical nozzle count of one multi-nozzle extruder. +class ManualNozzleCountDialog : public DPIDialog +{ +public: + ManualNozzleCountDialog(wxWindow *parent, NozzleVolumeType volume_type, int standard_count, int highflow_count, int max_nozzle_count, bool force_no_zero); + ~ManualNozzleCountDialog() override = default; + void on_dpi_changed(const wxRect &suggested_rect) override {} + int GetNozzleCount(NozzleVolumeType volume_type) const; + +private: + wxChoice *m_standard_choice{nullptr}; + wxChoice *m_highflow_choice{nullptr}; + Button *m_confirm_btn{nullptr}; + wxStaticText *m_error_label{nullptr}; +}; + +class ExtruderBadge : public wxPanel +{ +public: + ExtruderBadge(wxWindow* parent); + void SetExtruderInfo(int extruder_id, const std::string& label, const NozzleVolumeType& flow); + void UnMarkRelatedItems(const NozzleOption& option); + void MarkRelatedItems(const NozzleOption& option); + void SetExtruderValid(bool right_on); +private: + void SetExtruderStatus(bool left_selected, bool right_selected); + + bool m_right_on{ true }; + wxStaticBitmap* badget; + Label* left; + Label* right; + Label* left_diameter_desp; + Label* right_diameter_desp; + Label* left_flow_desp; + Label* right_flow_desp; + + std::vector<std::string> m_diameter_list; + std::vector<NozzleVolumeType> m_volume_type_list; +}; + +class HotEndTable : public wxPanel +{ +public: + HotEndTable(wxWindow* parent); + void UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack); + void MarkRelatedItems(const NozzleOption& option); + void UnMarkRelatedItems(const NozzleOption& option); +private: + StaticBox* CreateNozzleBox(const std::vector<int>& nozzle_indices); + void UpdateNozzleItems(const std::unordered_map<int, wgtDeviceNozzleRackNozzleItem*>& nozzle_items, + std::shared_ptr<DevNozzleRack> nozzle_rack); + +private: + struct HotEndAttr { + std::string diameter; + int extruder_id; + NozzleVolumeType volume_type; + }; + + std::vector<int> FilterHotEnds(const NozzleOption& option); + +private: + StaticBox* m_arow_nozzle_box{ nullptr }; + StaticBox* m_brow_nozzle_box{ nullptr }; + std::unordered_map<int, wgtDeviceNozzleRackNozzleItem*> m_nozzle_items; + std::weak_ptr<DevNozzleRack> m_nozzle_rack; + void OnPaint(wxPaintEvent& event); +}; + + +wxDECLARE_EVENT(EVT_NOZZLE_SELECTED, wxCommandEvent); + +class NozzleListTable : public wxPanel +{ +public: + NozzleListTable(wxWindow* parent); + int GetSelectIdx(); + void SetOptions(const std::vector<NozzleOption>& options,int default_select); +private: + wxString BuildTableObjStr(); + wxString BuildTextObjStr(); + std::vector<NozzleOption> m_nozzle_options; + + void SendSelectionChangedEvent(); + + wxWebView* m_web_view; + + int m_selected_idx; +}; + +class MultiNozzleStatusTable : public wxPanel +{ +public: + MultiNozzleStatusTable(wxWindow* parent); + void UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack); + void MarkRelatedItems(const NozzleOption& option); + void UnMarkRelatedItems(const NozzleOption& option); +private: + ExtruderBadge* m_badge; + HotEndTable* m_table; +}; + + +class MultiNozzleSyncDialog : public DPIDialog +{ +public: + MultiNozzleSyncDialog(wxWindow* parent, std::weak_ptr<DevNozzleRack> rack); + virtual void on_dpi_changed(const wxRect& suggested_rect) {}; + std::vector<NozzleOption> GetNozzleOptions(const std::vector<MultiNozzleUtils::NozzleGroupInfo>& group_infos); + + std::optional<NozzleOption> GetSelectedOption() { + if (m_nozzle_option_idx < 0 || m_nozzle_option_idx >= m_nozzle_option_values.size()) + return std::nullopt; + return m_nozzle_option_values[m_nozzle_option_idx]; + } + + int ShowModal() override; + ~MultiNozzleSyncDialog() override; +private: + void UpdateRackInfo(std::weak_ptr<DevNozzleRack> rack); + + bool hasMultiDiameters(const std::vector<MultiNozzleUtils::NozzleGroupInfo>& group_infos); + void OnSelectRadio(int select_idx); + + bool UpdateUi(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown=false, bool ignore_unreliable=false); + + bool UpdateOptionList(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable); + void UpdateTip(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable); + void UpdateButton(std::weak_ptr<DevNozzleRack> rack, bool ignore_unknown, bool ignore_unreliable); + void OnRackStatusReadingFinished(wxEvent& evt); + void OnRefreshTimer(wxTimerEvent& event); + +private: + MultiNozzleStatusTable* m_nozzle_table; + NozzleListTable* m_list_table; + std::vector<NozzleOption> m_nozzle_option_values; + int m_nozzle_option_idx{ -1 }; + bool m_refreshing{ false }; + + std::weak_ptr<DevNozzleRack> m_nozzle_rack; + Label* m_tips; + Label* m_caution; + + wxTimer* m_refresh_timer {nullptr}; + size_t m_rack_event_token; + Button* m_cancel_btn; + Button* m_confirm_btn; +}; + + +// Entry point for the sidebar "sync machine" button: pops MultiNozzleSyncDialog for a connected H2C and +// returns the chosen nozzle option (nullopt if the machine has no supported rack or the user cancels). +std::optional<NozzleOption> tryPopUpMultiNozzleDialog(MachineObject* obj); + +// Persist one extruder's per-volume-type nozzle count into the edited printer preset's `extruder_nozzle_stats` +// config key (the value the multi-nozzle slicer reads). When clear_all is true, the extruder's other volume-type +// counts are reset first. +void setExtruderNozzleCount(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType type, int nozzle_count, bool clear_all); + +// Read one extruder's nozzle count for a volume type (or its total) from the edited printer preset's +// `extruder_nozzle_stats` config key. Returns 0 when the stats are absent or the extruder is unknown. +int getExtruderNozzleCount(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type); +int getExtruderNozzleCountTotal(PresetBundle *preset_bundle, int extruder_id); + +// Refresh the sidebar nozzle-count badge for one extruder: shows the extruder's physical nozzle count on +// multi-nozzle printers, hides it (count -1) everywhere else. +void updateNozzleCountDisplay(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType volume_type); + +// Reset `extruder_nozzle_stats` to its baseline for the selected printer: each extruder gets +// extruder_max_nozzle_count nozzles of its currently selected volume type. Called whenever the stats are +// absent (the key is session-only — preset switches rebuild the edited config without it). Clears the +// machine-provenance flag. +void seedExtruderNozzleStats(PresetBundle *preset_bundle); + +// React to the user switching one extruder's nozzle volume type: carry the extruder's total nozzle count +// over to the new type. No-op for Hybrid (which is a mix, not a type all nozzles share) and for +// machine-synced stats (the device-reported per-type breakdown must survive a flow switch). +void onNozzleVolumeTypeSwitch(PresetBundle *preset_bundle, int extruder_id, NozzleVolumeType type); + +// Mark the current `extruder_nozzle_stats` values as machine-reported (device sync) or manual/seeded. +void setNozzleStatsFromMachine(bool from_machine); + +// True when a nozzle of this diameter can carry the "Direct Drive TPU High Flow" variant. That variant +// exists on the 0.4 and 0.6 nozzle H2D/H2D Pro leaves (not 0.2/0.8), so this is the single source of truth +// for the diameter set — the counterpart of the High-Flow-skip-for-0.2 guard. +bool nozzle_diameter_supports_tpu_high_flow(double nozzle_diameter); +// Same predicate resolved from the edited printer preset's nozzle_diameter for one extruder. False when unknown. +bool extruder_supports_tpu_high_flow(PresetBundle *preset_bundle, int extruder_id); + +// Entry point: pop the ManualNozzleCountDialog for one extruder of a multi-nozzle printer and persist the result. +// No-op unless the selected printer has an extruder with extruder_max_nozzle_count > 1. +void manuallySetNozzleCount(int extruder_id); + +}} // namespace Slic3r::GUI + +#endif // slic3r_GUI_MultiNozzleSync_hpp_ diff --git a/src/slic3r/GUI/Widgets/ProgressDialog.cpp b/src/slic3r/GUI/Widgets/ProgressDialog.cpp index 0ace737d8d..0575e584f4 100644 --- a/src/slic3r/GUI/Widgets/ProgressDialog.cpp +++ b/src/slic3r/GUI/Widgets/ProgressDialog.cpp @@ -556,7 +556,7 @@ bool ProgressDialog::Update(int value, const wxString &newmsg, bool *skip) if (newmsg.empty()) { // also provide the finishing message if the application didn't - m_msg->SetLabel(wxGetTranslation("Done.")); + m_msg->SetLabel(_L("Done.")); } // allow the window to repaint: diff --git a/src/slic3r/GUI/calib_dlg.cpp b/src/slic3r/GUI/calib_dlg.cpp index 8cf33c3851..0a18e2d448 100644 --- a/src/slic3r/GUI/calib_dlg.cpp +++ b/src/slic3r/GUI/calib_dlg.cpp @@ -1471,12 +1471,24 @@ FlowRateCalibrationDialog::FlowRateCalibrationDialog(wxWindow* parent, wxWindowI type_box->Add(m_rbType, 0, wxALL | wxEXPAND, FromDIP(4)); v_sizer->Add(type_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); - // Pattern selection - auto labeled_box_pattern = new LabeledStaticBox(this, _L("Top Surface Pattern")); - auto pattern_box = new wxStaticBoxSizer(labeled_box_pattern, wxVERTICAL); + // Settings + auto stb = new LabeledStaticBox(this, _L("Settings")); + auto settings_sizer = new wxStaticBoxSizer(stb, wxVERTICAL); + + wxString pattern_str = _L("Top Surface Pattern"); + int text_max = GetTextMax(this, std::vector<wxString>{pattern_str}); + + settings_sizer->AddSpacer(FromDIP(5)); + + auto st_size = wxSize(text_max, -1); + auto ti_size = FromDIP(wxSize(120, -1)); + + // Top surface pattern + auto pattern_sizer = new wxBoxSizer(wxHORIZONTAL); + auto pattern_text = new wxStaticText(this, wxID_ANY, pattern_str, wxDefaultPosition, st_size, wxALIGN_LEFT); // ORCA: Use ComboBox with icons instead of RadioGroup - m_rbPattern = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, nullptr, wxCB_READONLY); + m_rbPattern = new ComboBox(this, wxID_ANY, wxEmptyString, wxDefaultPosition, ti_size, 0, nullptr, wxCB_READONLY); boost::filesystem::path image_path(Slic3r::resources_dir()); image_path /= "images"; @@ -1497,9 +1509,13 @@ FlowRateCalibrationDialog::FlowRateCalibrationDialog(wxWindow* parent, wxWindowI m_rbPattern->SetSelection(0); // Default to Archimedean Chords // ORCA: explicit set value to ensure display on Windows m_rbPattern->SetValue(m_rbPattern->GetString(0)); + m_rbPattern->GetDropDown().SetUseContentWidth(true); - pattern_box->Add(m_rbPattern, 0, wxALL | wxEXPAND, FromDIP(4)); - v_sizer->Add(pattern_box, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); + pattern_sizer->Add(pattern_text, 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + pattern_sizer->Add(m_rbPattern , 0, wxALL | wxALIGN_CENTER_VERTICAL, FromDIP(2)); + settings_sizer->Add(pattern_sizer, 0, wxLEFT, FromDIP(3)); + + v_sizer->Add(settings_sizer, 0, wxTOP | wxRIGHT | wxLEFT | wxEXPAND, FromDIP(10)); v_sizer->AddSpacer(FromDIP(5)); diff --git a/src/slic3r/Utils/CalibUtils.cpp b/src/slic3r/Utils/CalibUtils.cpp index 29d302c776..e7d16ffef9 100644 --- a/src/slic3r/Utils/CalibUtils.cpp +++ b/src/slic3r/Utils/CalibUtils.cpp @@ -7,6 +7,7 @@ #include "../GUI/PartPlate.hpp" #include "libslic3r/CutUtils.hpp" #include "libslic3r/ClipperUtils.hpp" +#include "libslic3r/Utils.hpp" #include "libslic3r/Model.hpp" #include "slic3r/GUI/Jobs/BoostThreadWorker.hpp" @@ -27,11 +28,19 @@ const double MIN_PA_K_VALUE = 0.0; const double MAX_PA_K_VALUE = 2.0; std::unique_ptr<Worker> CalibUtils::print_worker; -wxString wxstr_temp_dir = fs::path(fs::temp_directory_path() / "calib").wstring(); -static const std::string temp_dir = wxstr_temp_dir.utf8_string(); -static const std::string temp_gcode_path = temp_dir + "/temp.gcode"; -static const std::string path = temp_dir + "/test.3mf"; -static const std::string config_3mf_path = temp_dir + "/test_config.3mf"; + +// Built lazily so temporary_dir() is read on first use, after set_temporary_dir() +// has run at startup (it isolates the temp root per user to avoid cross-user collisions). +static const std::string& calib_temp_dir() +{ + static const std::string dir = temporary_dir() + "/calib"; + return dir; +} +static std::string calib_temp_file(const std::string& name) { return calib_temp_dir() + "/" + name; } + +static const std::string gcode_filename = "temp.gcode"; +static const std::string model_filename = "test.3mf"; +static const std::string config_filename = "test_config.3mf"; static std::string MachineBedTypeString[7] = { "auto", @@ -85,6 +94,10 @@ wxString get_nozzle_volume_type_name(NozzleVolumeType type) return _L("Standard"); } else if (NozzleVolumeType::nvtHighFlow == type) { return _L("High Flow"); + } else if (NozzleVolumeType::nvtHybrid == type) { + return _L("Hybrid"); + } else if (NozzleVolumeType::nvtTPUHighFlow == type) { + return _L("TPU High Flow"); } return wxString(); } @@ -1599,7 +1612,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f part_plate->update_slice_result_valid_state(true); gcode_result->reset(); - fff_print->export_gcode(temp_gcode_path, gcode_result, nullptr); + fff_print->export_gcode(calib_temp_file(gcode_filename), gcode_result, nullptr); std::vector<ThumbnailData*> thumbnails; PlateDataPtrs plate_data_list; @@ -1618,7 +1631,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f } for (auto plate_data : plate_data_list) { - plate_data->gcode_file = temp_gcode_path; + plate_data->gcode_file = calib_temp_file(gcode_filename); plate_data->is_sliced_valid = true; plate_data->printer_model_id = obj_->printer_type; FilamentInfo& filament_info = plate_data->slice_filaments_info.front(); @@ -1681,7 +1694,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f } StoreParams store_params; - store_params.path = path.c_str(); + store_params.path = calib_temp_file(model_filename); store_params.model = model; store_params.plate_data_list = plate_data_list; store_params.config = &new_print_config; @@ -1695,7 +1708,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f bool success = Slic3r::store_bbs_3mf(store_params); store_params.strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithSliceInfo | SaveStrategy::SkipAuxiliary; - store_params.path = config_3mf_path.c_str(); + store_params.path = calib_temp_file(config_filename); success = Slic3r::store_bbs_3mf(store_params); release_PlateData_list(plate_data_list); @@ -1784,9 +1797,9 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess PrintPrepareData job_data; job_data.is_from_plater = false; job_data.plate_idx = 0; - job_data._3mf_config_path = config_3mf_path; - job_data._3mf_path = path; - job_data._temp_path = temp_dir; + job_data._3mf_config_path = calib_temp_file(config_filename); + job_data._3mf_path = calib_temp_file(model_filename); + job_data._temp_path = calib_temp_dir(); PlateListData plate_data; plate_data.is_valid = true; @@ -1889,9 +1902,9 @@ void CalibUtils::send_to_print(const std::vector<CalibInfo> &calib_infos, wxStri PrintPrepareData job_data; job_data.is_from_plater = false; job_data.plate_idx = 0; - job_data._3mf_config_path = config_3mf_path; - job_data._3mf_path = path; - job_data._temp_path = temp_dir; + job_data._3mf_config_path = calib_temp_file(config_filename); + job_data._3mf_path = calib_temp_file(model_filename); + job_data._temp_path = calib_temp_dir(); PlateListData plate_data; plate_data.is_valid = true; diff --git a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp index f1d892134b..b0ea653dd3 100644 --- a/src/slic3r/Utils/MoonrakerPrinterAgent.cpp +++ b/src/slic3r/Utils/MoonrakerPrinterAgent.cpp @@ -536,7 +536,7 @@ void MoonrakerPrinterAgent::build_ams_payload(int ams_count, int max_lane_index, print_json["ams"] = ams_json; // Call the parser to populate DevFilaSystem - DevFilaSystemParser::ParseV1_0(print_json, obj, obj->GetFilaSystem(), false); + DevFilaSystemParser::ParseV1_0(print_json, obj, obj->GetFilaSystem().get(), false); BOOST_LOG_TRIVIAL(info) << "MoonrakerPrinterAgent::build_ams_payload: Parsed " << trays.size() << " trays"; // Set printer_type so update_sync_status() can match it against the preset's printer type. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1108fe9350..3cbdc25f5f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,13 +13,17 @@ endif() set(TEST_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data) file(TO_NATIVE_PATH "${TEST_DATA_DIR}" TEST_DATA_DIR) +# Shipped vendor profiles, so tests can exercise the real machine/filament gcode. +set(PROFILES_DIR ${CMAKE_SOURCE_DIR}/resources/profiles) +file(TO_NATIVE_PATH "${PROFILES_DIR}" PROFILES_DIR) + include(CTest) include(Catch) set(CATCH_EXTRA_ARGS "" CACHE STRING "Extra arguments for catch2 test suites.") # Unknown if this still works and/or should be replaced with something else. add_library(test_common INTERFACE) -target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" CATCH_CONFIG_FAST_COMPILE) +target_compile_definitions(test_common INTERFACE TEST_DATA_DIR=R"\(${TEST_DATA_DIR}\)" PROFILES_DIR=R"\(${PROFILES_DIR}\)" CATCH_CONFIG_FAST_COMPILE) target_include_directories(test_common INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) if (APPLE) @@ -57,5 +61,6 @@ add_subdirectory(libslic3r) add_subdirectory(slic3rutils) add_subdirectory(fff_print) add_subdirectory(sla_print) +add_subdirectory(filament_group) diff --git a/tests/fff_print/test_gcode_timing.cpp b/tests/fff_print/test_gcode_timing.cpp index 646ab1bbbe..4570f253bb 100644 --- a/tests/fff_print/test_gcode_timing.cpp +++ b/tests/fff_print/test_gcode_timing.cpp @@ -2,12 +2,14 @@ #include "libslic3r/libslic3r.h" #include "libslic3r/GCode/GCodeProcessor.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" #include "libslic3r/PrintConfig.hpp" #include "test_utils.hpp" #include <fstream> #include <map> +#include <memory> using namespace Slic3r; using Catch::Matchers::WithinAbs; @@ -323,3 +325,96 @@ TEST_CASE("Carried-forward tool-change delay reaches the total without polluting REQUIRE_THAT(rd.at(role), WithinAbs(zero_time, 1e-2)); } } + +TEST_CASE("Per-slot machine limits follow the active nozzle", "[GCodeTiming][MultiNozzle]") +{ + // Single physical extruder carrying two nozzle variants: machine slot 0 (Standard) caps X/Y + // speed at 200 mm/s, slot 1 (High Flow) at 50 mm/s. The estimator must clamp each move by the + // slot of the nozzle the active filament occupies -- resolved from the grouping context handed + // over before the replay plus the occupancy recorder, i.e. the exact in-slicer streaming path. + FullPrintConfig config = make_config(0.0, 0.0, 0.0); + config.extruder_type.values = {static_cast<int>(etDirectDrive)}; + config.printer_extruder_id.values = {1, 1}; + config.printer_extruder_variant.values = {"Direct Drive Standard", "Direct Drive High Flow"}; + // Slot-major layout: [slot0-Normal, slot0-Stealth, slot1-Normal, slot1-Stealth]. + config.machine_max_speed_x.values = {200., 200., 50., 50.}; + config.machine_max_speed_y.values = {200., 200., 50., 50.}; + config.machine_max_speed_z.values = {200., 200., 50., 50.}; + config.machine_max_speed_e.values = {200., 200., 50., 50.}; + // Keep acceleration and jerk far from limiting so move times are speed-dominated. + for (auto *accel : {&config.machine_max_acceleration_x, &config.machine_max_acceleration_y, + &config.machine_max_acceleration_z, &config.machine_max_acceleration_e}) + accel->values = {100000., 100000., 100000., 100000.}; + config.machine_max_acceleration_travel.values = {100000., 100000.}; + config.machine_max_acceleration_extruding.values = {100000., 100000.}; + config.machine_max_jerk_x.values = {10000., 10000.}; + config.machine_max_jerk_y.values = {10000., 10000.}; + config.machine_max_jerk_z.values = {10000., 10000.}; + config.machine_max_jerk_e.values = {10000., 10000.}; + + // Grouping stub: filament 0 lives on the Standard nozzle (slot 0), filament 1 on the + // High Flow nozzle (slot 1), both mounted on extruder 0. + std::vector<MultiNozzleUtils::NozzleInfo> nozzles; + { + MultiNozzleUtils::NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; n.extruder_id = 0; n.group_id = 0; nozzles.push_back(n); + n.volume_type = nvtHighFlow; n.extruder_id = 0; n.group_id = 1; nozzles.push_back(n); + } + std::vector<int> filament_nozzle_map = {0, 1}; + std::vector<unsigned int> used_filaments = {0, 1}; + auto group = MultiNozzleUtils::LayeredNozzleGroupResult::create(filament_nozzle_map, nozzles, used_filaments); + REQUIRE(group.has_value()); + auto context = std::make_shared<MultiNozzleUtils::LayeredNozzleGroupResult>(*group); + + // Two identical 100 mm X travels, one per filament; T..H.. carries the target nozzle id. + // The trailing 1 mm move keeps two blocks queued at finalize, so the measured move's time is + // flushed (a lone final block is never attributed); it adds 1 mm to the second bucket. + const char* gcode = + "M83\n" + "T0 H0\n" + "G1 X100 F30000\n" + "T1 H1\n" + "G1 X0 F30000\n" + "G1 X1 F30000\n"; + + // Travel time accumulated after each tool-change move (bucket 0 = before any T). + auto travel_times_by_tool = [](const GCodeProcessorResult& r) { + std::vector<double> out(1, 0.0); + for (const auto& mv : r.moves) { + if (mv.type == EMoveType::Tool_change) + out.push_back(0.0); + else if (mv.type == EMoveType::Travel) + out.back() += mv.time[NORMAL]; + } + return out; + }; + + SECTION("the move on the High Flow nozzle is clamped by its own slot") { + GCodeProcessor proc; + proc.initialize_from_context(context); + run_processor(proc, config, gcode); + auto times = travel_times_by_tool(proc.get_result()); + REQUIRE(times.size() == 3); + REQUIRE_THAT(times[1], Catch::Matchers::WithinRel(100.0 / 200.0, 0.10)); + REQUIRE_THAT(times[2], Catch::Matchers::WithinRel(101.0 / 50.0, 0.10)); + } + SECTION("an emitted envelope line reaches every slot") { + const std::string enveloped = std::string("M201 X20000\nM203 X80\n") + gcode; + GCodeProcessor proc; + proc.initialize_from_context(context); + run_processor(proc, config, enveloped.c_str()); + auto times = travel_times_by_tool(proc.get_result()); + REQUIRE(times.size() == 3); + REQUIRE_THAT(times[1], Catch::Matchers::WithinRel(100.0 / 80.0, 0.10)); + REQUIRE_THAT(times[2], Catch::Matchers::WithinRel(101.0 / 80.0, 0.10)); + } + SECTION("no grouping context degrades to slot 0") { + GCodeProcessor proc; + run_processor(proc, config, gcode); + auto times = travel_times_by_tool(proc.get_result()); + REQUIRE(times.size() == 3); + REQUIRE_THAT(times[1], Catch::Matchers::WithinRel(100.0 / 200.0, 0.10)); + REQUIRE_THAT(times[2], Catch::Matchers::WithinRel(101.0 / 200.0, 0.10)); + } +} diff --git a/tests/fff_print/test_gcodewriter.cpp b/tests/fff_print/test_gcodewriter.cpp index adb104a25b..022b7841fc 100644 --- a/tests/fff_print/test_gcodewriter.cpp +++ b/tests/fff_print/test_gcodewriter.cpp @@ -1,6 +1,10 @@ #include <catch2/catch_all.hpp> +#include <cstdlib> #include <memory> +#include <sstream> +#include <string> +#include <vector> #include "libslic3r/GCodeWriter.hpp" #include "libslic3r/GCode.hpp" @@ -8,11 +12,23 @@ #include "libslic3r/Print.hpp" #include "libslic3r/ModelArrange.hpp" +#include <boost/filesystem.hpp> + #include "test_helpers.hpp" using namespace Slic3r; using namespace Slic3r::Test; +// Arrange on a finite bed, not an unbounded InfiniteBed: the latter places items +// near INT64_MIN/4 (~2.3e18), which reaches ClipperLib's coordinate limit and throws +// "Coordinate outside allowed range" on Windows/arm64. A 500x500 bed keeps coordinates +// small while still covering large printers. +static void arrange_objects_on_test_bed(Model &model, const DynamicPrintConfig &config) +{ + const BoundingBox bed{Point::new_scale(0., 0.), Point::new_scale(500., 500.)}; + arrange_objects(model, bed, ArrangeParams{scaled(min_object_distance(config))}); +} + SCENARIO("set_speed emits values with fixed-point output.", "[GCodeWriter]") { GIVEN("GCodeWriter instance") { @@ -241,8 +257,7 @@ TEST_CASE("Machine envelope emits max limit among used extruders", "[GCodeWriter obj2->config.set_key_value("extruder", new ConfigOptionInt(2)); // 0-based index 1 Print print; - arrange_objects(model, InfiniteBed{}, - ArrangeParams{scaled(min_object_distance(config))}); + arrange_objects_on_test_bed(model, config); for (auto* mo : model.objects) { mo->ensure_on_bed(); print.auto_assign_extruders(mo); @@ -354,7 +369,7 @@ TEST_CASE("EXTRUDER_LIMIT per-extruder clamping and max fallback", "[GCodeWriter obj2->config.set_key_value("extruder", new ConfigOptionInt(2)); // 0-based index 1 Print print; - arrange_objects(model, InfiniteBed{}, ArrangeParams{scaled(min_object_distance(config))}); + arrange_objects_on_test_bed(model, config); for (auto* mo : model.objects) { mo->ensure_on_bed(); print.auto_assign_extruders(mo); @@ -404,3 +419,404 @@ TEST_CASE("EXTRUDER_LIMIT per-extruder clamping and max fallback", "[GCodeWriter } } } + +SCENARIO("Extruder reads the injected config column", "[GCodeWriter][H2C]") { + GIVEN("A writer whose per-variant arrays hold three columns for two filaments") { + GCodeWriter writer; + // Column layout after a migrating regroup: filament 0 -> column 0, filament 1 -> + // columns 1 (its first variant) and 2 (its second variant). + writer.config.retraction_length.values = {0.8, 0.5, 1.2}; + writer.config.z_hop.values = {0.4, 0.6, 0.9}; + writer.config.retraction_speed.values = {30., 40., 50.}; + writer.config.filament_flow_ratio.values = {0.98, 1.0, 1.02}; + // Filament-indexed arrays keep one entry per filament. + writer.config.filament_diameter.values = {1.75, 1.75}; + writer.set_extruders({0, 1}); + writer.toolchange(1, 1); + Extruder *fil = writer.filament(); + REQUIRE(fil != nullptr); + REQUIRE(fil->id() == 1); + const double crossection = 1.75 * 1.75 * 0.25 * PI; + + WHEN("no column has been injected") { + THEN("the getters read the filament id's column") { + REQUIRE(fil->config_index() == 1); + REQUIRE_THAT(fil->retraction_length(), Catch::Matchers::WithinAbs(0.5, 1e-9)); + REQUIRE_THAT(fil->retract_lift(), Catch::Matchers::WithinAbs(0.6, 1e-9)); + REQUIRE(fil->retract_speed() == 40); + REQUIRE_THAT(fil->e_per_mm3(), Catch::Matchers::WithinRel(1.0 / crossection, 1e-9)); + } + } + WHEN("the second variant column is injected") { + fil->set_config_index(2); + THEN("the getters follow the column and the flow cache is rescaled") { + REQUIRE(fil->config_index() == 2); + REQUIRE_THAT(fil->retraction_length(), Catch::Matchers::WithinAbs(1.2, 1e-9)); + REQUIRE_THAT(fil->retract_lift(), Catch::Matchers::WithinAbs(0.9, 1e-9)); + REQUIRE(fil->retract_speed() == 50); + REQUIRE_THAT(fil->e_per_mm3(), Catch::Matchers::WithinRel(1.02 / crossection, 1e-9)); + } + THEN("filament-indexed reads keep using the filament id") { + REQUIRE_THAT(fil->filament_diameter(), Catch::Matchers::WithinAbs(1.75, 1e-9)); + } + } + WHEN("a negative index is injected") { + fil->set_config_index(2); + fil->set_config_index(-1); + THEN("resolution resets to the filament id") { + REQUIRE(fil->config_index() == 1); + REQUIRE_THAT(fil->retraction_length(), Catch::Matchers::WithinAbs(0.5, 1e-9)); + REQUIRE_THAT(fil->e_per_mm3(), Catch::Matchers::WithinRel(1.0 / crossection, 1e-9)); + } + } + } +} + +// Numeric argument of every line starting with `prefix`, in file order. +static std::vector<int> collect_line_args(const std::string &gcode, const std::string &prefix) +{ + std::vector<int> values; + std::istringstream stream(gcode); + std::string line; + while (std::getline(stream, line)) + if (line.compare(0, prefix.size(), prefix) == 0) + values.push_back(std::atoi(line.c_str() + int(prefix.size()))); + return values; +} + +static int count_lines_with_prefix(const std::string &gcode, const std::string &prefix) +{ + return (int) collect_line_args(gcode, prefix).size(); +} + +// A toolchange ordinal sequence is healthy when it advances by exactly one per +// change block; a change-less prime-tower visit must not consume an ordinal. +static bool ordinals_consecutive(const std::vector<int> &values) +{ + for (size_t i = 1; i < values.size(); ++i) + if (values[i] != values[i - 1] + 1) + return false; + return true; +} + +SCENARIO("Toolchange emission and prefix per printer kind", "[GCodeWriter][H2C]") { + GIVEN("A dual-extruder writer with two filaments") { + GCodeWriter writer; + writer.config.filament_diameter.values = {1.75, 1.75}; + writer.set_extruders({0, 1}); + + WHEN("the printer is a BBL machine") { + writer.set_is_bbl_machine(true); + THEN("the toolchange prefix is the plain T command") { + REQUIRE_THAT(writer.toolchange_prefix(), Catch::Matchers::Equals("T")); + } + THEN("toolchange emits a single M1020 with the nozzle id") { + const std::string gcode = writer.toolchange(1, 0); + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring("M1020 S1 H0")); + REQUIRE_THAT(gcode, !Catch::Matchers::StartsWith("T1")); + } + THEN("the other filament and nozzle emit their own ids") { + REQUIRE_THAT(writer.toolchange(0, 1), Catch::Matchers::ContainsSubstring("M1020 S0 H1")); + } + THEN("an unresolved nozzle keeps the literal -1 convention") { + REQUIRE_THAT(writer.toolchange(1, -1), Catch::Matchers::ContainsSubstring("M1020 S1 H-1")); + } + } + WHEN("the printer is a BBL machine with manual filament change") { + writer.set_is_bbl_machine(true); + writer.config.manual_filament_change.value = true; + THEN("the manual tag wins over the M1020 form") { + REQUIRE_THAT(writer.toolchange_prefix(), Catch::Matchers::StartsWith(";")); + const std::string gcode = writer.toolchange(1, 0); + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring(writer.toolchange_prefix() + "1")); + REQUIRE_THAT(gcode, !Catch::Matchers::ContainsSubstring("M1020")); + } + } + WHEN("the printer is not a BBL machine") { + THEN("toolchange keeps the plain T command") { + REQUIRE_THAT(writer.toolchange_prefix(), Catch::Matchers::Equals("T")); + const std::string gcode = writer.toolchange(1, 0); + REQUIRE_THAT(gcode, Catch::Matchers::StartsWith("T1")); + REQUIRE_THAT(gcode, !Catch::Matchers::ContainsSubstring("M1020")); + } + } + } +} + +// Shared dual-extruder printer config for the toolchange-count scenarios below. +static DynamicPrintConfig dual_extruder_toolchange_config() +{ + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_key_value("gcode_flavor", new ConfigOptionEnum<GCodeFlavor>(gcfMarlinFirmware)); + config.set_key_value("emit_machine_limits_to_gcode", new ConfigOptionBool(false)); + config.set_key_value("machine_start_gcode", new ConfigOptionString("")); + config.set_key_value("layer_height", new ConfigOptionFloat(0.2)); + config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(0.2)); + config.set_key_value("initial_layer_line_width", new ConfigOptionFloatOrPercent(0, false)); + config.set_key_value("z_hop", new ConfigOptionFloats({0., 0.})); + // The change block carries both a real toolchange command and the ordinal + // placeholder the stock profiles feed to the firmware. + config.set_key_value("change_filament_gcode", + new ConfigOptionString("T[next_filament_id]\nM620 O{toolchange_count + 1}\n")); + + // 2 extruders, one filament each (manual map so nothing regroups them). + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({0.4, 0.4})); + config.set_key_value("printer_extruder_id", new ConfigOptionInts({1, 2})); + config.set_key_value("printer_extruder_variant", new ConfigOptionStrings({"Direct Drive Standard", "Direct Drive Standard"})); + config.set_key_value("filament_diameter", new ConfigOptionFloats({1.75, 1.75})); + config.set_key_value("filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00"})); + config.set_key_value("default_filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00"})); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PLA"})); + config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode", true)->value = fmmManual; + config.set_key_value("filament_map", new ConfigOptionInts({1, 2})); + config.set_key_value("nozzle_temperature", new ConfigOptionInts({210, 210})); + config.set_key_value("nozzle_temperature_range_low", new ConfigOptionInts({190, 190})); + config.set_key_value("nozzle_temperature_range_high", new ConfigOptionInts({240, 240})); + config.set_key_value("flush_multiplier", new ConfigOptionFloats({1})); + config.set_key_value("flush_volumes_matrix", new ConfigOptionFloats({0, 140, 140, 0})); + return config; +} + +SCENARIO("Change blocks carry consecutive toolchange ordinals without a duplicate command", "[GCodeWriter][H2C]") { + GIVEN("Two sequentially printed objects on different extruders of a BBL machine") { + DynamicPrintConfig config = dual_extruder_toolchange_config(); + config.set_key_value("print_sequence", new ConfigOptionEnum<PrintSequence>(PrintSequence::ByObject)); + + Model model; + auto *obj1 = model.add_object(); + obj1->add_volume(cube(20)); + obj1->add_instance(); + auto *obj2 = model.add_object(); + obj2->add_volume(cube(20)); + obj2->add_instance(); + obj2->config.set_key_value("extruder", new ConfigOptionInt(2)); + + auto slice_to_gcode = [&]() { + Print print; + print.is_BBL_printer() = true; + arrange_objects_on_test_bed(model, config); + for (auto *mo : model.objects) { + mo->ensure_on_bed(); + print.auto_assign_extruders(mo); + } + print.apply(model, config); + print.validate(); + print.set_status_silent(); + print.process(); + return Slic3r::Test::gcode(print); + }; + + WHEN("the change block already changes the tool") { + const std::string gcode = slice_to_gcode(); + const std::vector<int> ordinals = collect_line_args(gcode, "M620 O"); + THEN("each change block advances the ordinal by exactly one, without inflation") { + REQUIRE(!ordinals.empty()); + REQUIRE(ordinals_consecutive(ordinals)); + REQUIRE(ordinals.front() <= 3); + } + THEN("the writer's own command is suppressed as a duplicate") { + REQUIRE(count_lines_with_prefix(gcode, "M1020") == 0); + REQUIRE(count_lines_with_prefix(gcode, "T1") >= 1); + } + } + WHEN("the change block does not change the tool itself") { + config.set_key_value("change_filament_gcode", + new ConfigOptionString("M620 O{toolchange_count + 1}\n")); + const std::string gcode = slice_to_gcode(); + const std::vector<int> ordinals = collect_line_args(gcode, "M620 O"); + THEN("the writer's toolchange survives and carries a nozzle id") { + REQUIRE(count_lines_with_prefix(gcode, "M1020 S1 H") >= 1); + } + THEN("the ordinal sequence stays consecutive") { + REQUIRE(!ordinals.empty()); + REQUIRE(ordinals_consecutive(ordinals)); + REQUIRE(ordinals.front() <= 3); + } + } + } +} + +SCENARIO("Prime-tower visits without a filament change do not advance the toolchange ordinal", "[GCodeWriter][H2C]") { + GIVEN("A print whose only filament change happens far above the bed") { + DynamicPrintConfig config = dual_extruder_toolchange_config(); + config.set_key_value("enable_prime_tower", new ConfigOptionBool(true)); + + // Filament 2 is used only above z=6, so every tower layer below it is a + // change-less visit — the exact geometry that used to inflate the ordinal. + Model model; + auto *obj = model.add_object(); + obj->add_volume(cube(10)); + obj->add_instance(); + DynamicPrintConfig range_config; + range_config.set_key_value("extruder", new ConfigOptionInt(2)); + // Every layer range must carry a layer_height (see layer_height_profile_from_ranges). + range_config.set_key_value("layer_height", new ConfigOptionFloat(0.2)); + obj->layer_config_ranges[{6.0, 10.0}].assign_config(std::move(range_config)); + + Print print; + print.is_BBL_printer() = true; + arrange_objects_on_test_bed(model, config); + for (auto *mo : model.objects) { + mo->ensure_on_bed(); + print.auto_assign_extruders(mo); + } + print.apply(model, config); + print.validate(); + print.set_status_silent(); + print.process(); + const std::string gcode = Slic3r::Test::gcode(print); + + WHEN("the print is exported") { + const std::vector<int> ordinals = collect_line_args(gcode, "M620 O"); + THEN("the prime-tower toolchange path was exercised") { + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring("CP TOOLCHANGE START")); + } + THEN("dozens of change-less tower layers consume no ordinal") { + REQUIRE(!ordinals.empty()); + REQUIRE(ordinals_consecutive(ordinals)); + REQUIRE(ordinals.front() <= 3); + } + THEN("no duplicate toolchange command follows the change block") { + REQUIRE(count_lines_with_prefix(gcode, "M1020") == 0); + } + } + } +} + +// --------------------------------------------------------------------------- +// Real-profile toolchange coverage, targeted. The all-vendors sweep in test_profile_slicing.cpp now +// slices a two-colour cube per printer, so it already expands every shipped change_filament_gcode with +// each printer's DEFAULT extruder variants (both the single-nozzle append_tcr and dual-nozzle set_extruder +// paths). What that sweep can't reach is a variant-conditional branch the defaults never select — H2D's +// change gcode has an `== "Direct Drive TPU High Flow"` block. This scenario forces that branch by handing +// the extruders distinct kits, so an unregistered placeholder inside it still throws "Variable does not +// exist" here instead of only in the field. +// --------------------------------------------------------------------------- + +// Two 20mm cubes on separate extruders of a BBL machine, printed by object so exactly +// one real toolchange fires and drives the change_filament_gcode. Returns the g-code. +static std::string slice_two_object_bbl(DynamicPrintConfig &config) +{ + config.set_key_value("print_sequence", new ConfigOptionEnum<PrintSequence>(PrintSequence::ByObject)); + + Model model; + auto *obj1 = model.add_object(); + obj1->add_volume(cube(20)); + obj1->add_instance(); + auto *obj2 = model.add_object(); + obj2->add_volume(cube(20)); + obj2->add_instance(); + obj2->config.set_key_value("extruder", new ConfigOptionInt(2)); + + Print print; + print.is_BBL_printer() = true; + arrange_objects_on_test_bed(model, config); + for (auto *mo : model.objects) { + mo->ensure_on_bed(); + print.auto_assign_extruders(mo); + } + print.apply(model, config); + print.validate(); + print.set_status_silent(); + print.process(); + return Slic3r::Test::gcode(print); +} + +// The real change_filament_gcode of a shipped "<printer> 0.4 nozzle" machine profile. +static std::string shipped_change_filament_gcode(const std::string &printer) +{ + const std::string path = std::string(PROFILES_DIR) + "/BBL/machine/Bambu Lab " + printer + " 0.4 nozzle.json"; + // PROFILES_DIR is an absolute path baked in at build time; a sparse test checkout + // without resources/ leaves it missing. Skip rather than dereference a config that + // never loaded - this is the only fff_print test that reads a shipped profile. + if (!boost::filesystem::exists(path)) + SKIP("shipped profile not present in this checkout: " << path); + DynamicPrintConfig config; + std::map<std::string, std::string> key_values; + std::string reason; + config.load_from_json(path, ForwardCompatibilitySubstitutionRule::Enable, key_values, reason); + // Fail loudly on a malformed/renamed profile instead of null-dereferencing in opt_string. + INFO("profile: " << path << (reason.empty() ? "" : (" load reason: " + reason))); + REQUIRE(config.has("change_filament_gcode")); + return config.opt_string("change_filament_gcode"); +} + +SCENARIO("Toolchange gcode resolves old/new_extruder_variant from printer_extruder_variant", "[GCodeWriter][H2C]") +{ + GIVEN("a BBL dual-extruder print whose change gcode reads the extruder-variant placeholders") { + DynamicPrintConfig config = dual_extruder_toolchange_config(); + // A distinctive variant that can only reach the g-code through printer_extruder_variant. + // Both entries carry it so the assertion is independent of which physical extruder the + // emitted change routes through. + config.set_key_value("printer_extruder_variant", + new ConfigOptionStrings({"Direct Drive TPU High Flow", "Direct Drive TPU High Flow"})); + config.set_key_value("change_filament_gcode", new ConfigOptionString( + "; VARIANT old={old_extruder_variant} new={new_extruder_variant}\nT[next_filament_id]\n")); + + WHEN("the print is sliced") { + const std::string gcode = slice_two_object_bbl(config); + THEN("both placeholders resolve to the printer_extruder_variant value") { + // The resolved line is the proof: an unresolved token or a parser throw would + // prevent this exact line from being emitted. (A negative "{token}" check is + // unreliable — the g-code's trailing config dump echoes the raw template.) + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring( + "; VARIANT old=Direct Drive TPU High Flow new=Direct Drive TPU High Flow")); + } + } + } +} + +SCENARIO("Global current-tool placeholders resolve in a context with no local injection", "[GCodeWriter][H2C]") +{ + GIVEN("a BBL dual-extruder print whose before_layer_change_gcode reads the current-tool placeholders") { + DynamicPrintConfig config = dual_extruder_toolchange_config(); + // before_layer_change is one of the contexts that inject NO current_* into their local config + // (unlike change_filament / machine_end / layer_change), so these placeholders can only resolve + // through the GLOBAL parser vars published at each toolchange (and at the initial set_extruder). + // Pre-fix current_filament_id / current_extruder_id / current_nozzle_id were undefined here and the + // whole slice threw a PlaceholderParserError — the same failure mode X2D's layer_change hit. + config.set_key_value("before_layer_change_gcode", new ConfigOptionString( + "; GVAR fid={current_filament_id} eid={current_extruder_id} nid={current_nozzle_id}\n")); + + WHEN("the print is sliced (obj1 on filament 0, obj2 on filament 1)") { + std::string gcode; + REQUIRE_NOTHROW(gcode = slice_two_object_bbl(config)); + THEN("all three globals resolve to the CORRECT active-tool values on both sides of the change") { + // Assert the FULL resolved marker, not just no-throw: obj1 prints on filament 0 (extruder 0, + // nozzle 0) and obj2 on filament 1 (extruder 1, nozzle 1). Locking every field means a + // stale or wrong global (e.g. obj2 still reading fid=0, or a mismatched extruder/nozzle id) + // fails here — this is the value guard that replaces the old "throws on undefined" canary. + // Only the emitted before_layer_change lines carry resolved values; the trailing config dump + // keeps the raw "{current_filament_id}" template, so these are unambiguous. + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring("; GVAR fid=0 eid=0 nid=0")); + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring("; GVAR fid=1 eid=1 nid=1")); + } + } + } +} + +SCENARIO("Shipped dual-nozzle change_filament_gcode resolves during a real slice", "[GCodeWriter][H2C][Profiles]") +{ + const std::string printer = GENERATE(std::string("H2C"), std::string("H2D"), std::string("H2D Pro"), std::string("X2D")); + + GIVEN("the real " + printer + " change_filament_gcode driving a BBL dual-extruder slice") { + DynamicPrintConfig config = dual_extruder_toolchange_config(); + config.set_key_value("change_filament_gcode", new ConfigOptionString(shipped_change_filament_gcode(printer))); + // H2D's gcode branches on the extruder variant; give the extruders distinct kits so the + // "Direct Drive TPU High Flow" branch is reachable. + config.set_key_value("printer_extruder_variant", + new ConfigOptionStrings({"Direct Drive Standard", "Direct Drive TPU High Flow"})); + // Extruder-indexed machine rates the stock gcode divides by (default size 1); size to 2 extruders. + config.set_key_value("hotend_cooling_rate", new ConfigOptionFloatsNullable({2.0, 2.0})); + config.set_key_value("hotend_heating_rate", new ConfigOptionFloatsNullable({2.0, 2.0})); + + THEN("every placeholder resolves (no undefined-variable throw) and the change block runs") { + std::string gcode; + REQUIRE_NOTHROW(gcode = slice_two_object_bbl(config)); + // A resolved marker only the emitted change block produces (the trailing config + // dump keeps the raw "{filament_type[...]}" template), so this confirms the real + // change_filament_gcode was expanded, not merely echoed. + REQUIRE_THAT(gcode, Catch::Matchers::ContainsSubstring("set_filament_type:PLA")); + } + } +} diff --git a/tests/fff_print/test_multifilament.cpp b/tests/fff_print/test_multifilament.cpp index 12c1cae766..f33a8e1e61 100644 --- a/tests/fff_print/test_multifilament.cpp +++ b/tests/fff_print/test_multifilament.cpp @@ -85,3 +85,22 @@ TEST_CASE("Per-object wall filament override is honored", "[MultiFilament]") CHECK(tools_for_role(gcode, "perimeter") == std::set<int>{ 0, 1 }); CHECK(tools_for_role(gcode, "infill") == std::set<int>{ 0 }); // infill not overridden: stays on F1 } + +// max_layer_height can be shorter than the extruder count (normalization sizes it to the +// filament count under single_extruder_multi_material). calc_max_layer_height() in ToolOrdering +// indexed it per-nozzle and read past the end. Shortened directly here to isolate that read; +// the other per-extruder keys stay extruder-length so slicing reaches the code under test. +TEST_CASE("Multi-extruder slice stays in bounds with a short max_layer_height", "[MultiFilament]") +{ + DynamicPrintConfig config = multifilament_config(2); + config.set_deserialize_strict({ + { "nozzle_diameter", "0.4,0.4" }, + { "printer_extruder_id", "1,2" }, + { "printer_extruder_variant", "Direct Drive Standard,Direct Drive Standard" }, + { "extruder_printable_height", "0,0" }, + { "max_layer_height", "0.3" }, // deliberately one entry short + }); + Print print; + init_and_process_print({ cube(20) }, print, config); + REQUIRE_FALSE(print.objects().front()->layers().empty()); +} diff --git a/tests/fff_print/test_print.cpp b/tests/fff_print/test_print.cpp index 8ba10a6ec9..9cb085f78b 100644 --- a/tests/fff_print/test_print.cpp +++ b/tests/fff_print/test_print.cpp @@ -418,3 +418,25 @@ TEST_CASE("Sequential printing follows model order", "[Print]") REQUIRE_THAT(first_object_peak_z, Catch::Matchers::WithinAbs(20.0, 0.3)); } + +// A sequential (by-object) print must publish the print-level nozzle group result just +// like a by-layer print, so custom g-code can index the per-nozzle placeholder tables +// (e.g. nozzle_diameter_at_nozzle_id[]) instead of failing on an empty vector. +TEST_CASE("Sequential printing publishes the nozzle group result", "[Print][MultiNozzle]") +{ + SECTION("process() publishes the result") { + Print print; + Model model; + place_two_cubes_apart(60.0, { { "print_sequence", "by object" } }, print, model); + print.process(); + REQUIRE(print.get_layered_nozzle_group_result() != nullptr); + } + + SECTION("start g-code can index the per-nozzle diameter table") { + const std::string gcode = slice_two_cubes_arranged({ + { "print_sequence", "by object" }, + { "machine_start_gcode", "{if nozzle_diameter_at_nozzle_id[0] > 0}; SEQ-ND-OK\n{endif}" }, + }); + CHECK(gcode.find("; SEQ-ND-OK") != std::string::npos); + } +} diff --git a/tests/fff_print/test_support_material.cpp b/tests/fff_print/test_support_material.cpp index 24c0e9cdc5..f854939c8c 100644 --- a/tests/fff_print/test_support_material.cpp +++ b/tests/fff_print/test_support_material.cpp @@ -93,3 +93,14 @@ SCENARIO("Support layer Z honors contact distance", "[SupportMaterial]") } } } + +// extrude_support once held a `static` lambda capturing `this`, so a second export in the +// same process dereferenced a returned stack frame (ASan: stack-use-after-return). +TEST_CASE("Support G-code emission survives a second slice in the same process", "[SupportMaterial][Regression]") +{ + const std::string first = slice({ TestMesh::overhang }, { { "enable_support", 1 } }); + REQUIRE(! layers_with_role(first, "support").empty()); + + const std::string second = slice({ TestMesh::overhang }, { { "enable_support", 1 } }); + REQUIRE(! layers_with_role(second, "support").empty()); +} diff --git a/tests/filament_group/CMakeLists.txt b/tests/filament_group/CMakeLists.txt new file mode 100644 index 0000000000..b56134f56b --- /dev/null +++ b/tests/filament_group/CMakeLists.txt @@ -0,0 +1,23 @@ +get_filename_component(_TEST_NAME ${CMAKE_CURRENT_LIST_DIR} NAME) + +set(FG_GOLDEN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/golden) +file(TO_NATIVE_PATH "${FG_GOLDEN_DIR}" FG_GOLDEN_DIR) + +add_executable(${_TEST_NAME}_tests + filament_group_regression_main.cpp + ) + +target_link_libraries(${_TEST_NAME}_tests test_common libslic3r nlohmann_json Catch2::Catch2WithMain) +# ${CMAKE_SOURCE_DIR}/deps_src puts <nlohmann/json.hpp> on the include path the same way the +# libslic3r translation units resolve it (via the admesh/.. system include); nlohmann_json's own +# interface dir only exposes <json.hpp>, so the source-tree include is required for the <nlohmann/…> +# spelling the serializers use. +target_include_directories(${_TEST_NAME}_tests PRIVATE ${CMAKE_SOURCE_DIR}/src ${CMAKE_SOURCE_DIR}/deps_src) +target_compile_definitions(${_TEST_NAME}_tests PRIVATE + FG_TEST_GOLDEN_DIR=R"\(${FG_GOLDEN_DIR}\)" + ) +set_property(TARGET ${_TEST_NAME}_tests PROPERTY FOLDER "tests") + +orcaslicer_copy_test_dlls() + +orcaslicer_discover_tests(${_TEST_NAME}_tests) diff --git a/tests/filament_group/fg_test_evaluator.hpp b/tests/filament_group/fg_test_evaluator.hpp new file mode 100644 index 0000000000..00a2e1a6f5 --- /dev/null +++ b/tests/filament_group/fg_test_evaluator.hpp @@ -0,0 +1,237 @@ +#ifndef FG_TEST_EVALUATOR_HPP +#define FG_TEST_EVALUATOR_HPP + +#include "fg_test_serialization.hpp" +#include <libslic3r/FilamentGroup.hpp> +#include <libslic3r/GCode/ToolOrderUtils.hpp> +#include <libslic3r/MultiNozzleUtils.hpp> + +#include <chrono> +#include <sstream> +#include <unordered_set> + +namespace Slic3r { +namespace FGTest { + +inline bool check_constraints(const FilamentGroupContext& ctx, + const std::vector<int>& filament_map, + std::vector<std::string>& violations) { + violations.clear(); + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + + // 1. unprintable_filaments check + for (size_t ext = 0; ext < ctx.model_info.unprintable_filaments.size(); ++ext) { + for (int fil : ctx.model_info.unprintable_filaments[ext]) { + if (fil < 0 || fil >= (int)filament_map.size()) + continue; + int assigned_nozzle = filament_map[fil]; + if (assigned_nozzle < 0 || assigned_nozzle >= (int)ctx.nozzle_info.nozzle_list.size()) + continue; + if (ctx.nozzle_info.nozzle_list[assigned_nozzle].extruder_id == (int)ext) { + std::ostringstream ss; + ss << "filament " << fil << " assigned to nozzle " << assigned_nozzle + << " (extruder " << ext << ") but is unprintable there"; + violations.push_back(ss.str()); + } + } + } + + // 2. unprintable_volumes check + for (auto& [fil, volume_types] : ctx.model_info.unprintable_volumes) { + if (fil < 0 || fil >= (int)filament_map.size()) + continue; + int assigned_nozzle = filament_map[fil]; + if (assigned_nozzle < 0 || assigned_nozzle >= (int)ctx.nozzle_info.nozzle_list.size()) + continue; + if (volume_types.count(ctx.nozzle_info.nozzle_list[assigned_nozzle].volume_type)) { + std::ostringstream ss; + ss << "filament " << fil << " assigned to nozzle " << assigned_nozzle + << " with volume_type " << (int)ctx.nozzle_info.nozzle_list[assigned_nozzle].volume_type + << " but that type is unprintable for this filament"; + violations.push_back(ss.str()); + } + } + + // 3. max_group_size per extruder. This cap is an invariant of the flush-partition + // modes only: those solvers partition the filaments across extruders subject to + // each extruder's capacity. MatchMode instead maps every filament to the extruder + // holding the nearest-color loaded AMS filament and does not partition by capacity + // (its solver capacity is the filament count, not max_group_size), so a legitimate + // match may place more than max_group_size filaments on one extruder. Enforce the + // cap only for the partition modes, and only when the instance is feasible. + int total_capacity = 0; + for (auto sz : ctx.machine_info.max_group_size) + total_capacity += sz; + + if (ctx.group_info.mode != FGMode::MatchMode && + total_capacity >= (int)used_filaments.size()) { + std::map<int, int> extruder_count; + for (auto fil : used_filaments) { + if (fil >= filament_map.size()) continue; + int nozzle_id = filament_map[fil]; + if (nozzle_id < 0 || nozzle_id >= (int)ctx.nozzle_info.nozzle_list.size()) + continue; + extruder_count[ctx.nozzle_info.nozzle_list[nozzle_id].extruder_id]++; + } + for (auto& [ext, count] : extruder_count) { + if (ext >= 0 && ext < (int)ctx.machine_info.max_group_size.size()) { + if (count > ctx.machine_info.max_group_size[ext]) { + std::ostringstream ss; + ss << "extruder " << ext << " has " << count << " filaments but max is " + << ctx.machine_info.max_group_size[ext]; + violations.push_back(ss.str()); + } + } + } + } + + return violations.empty(); +} + +inline int compute_flush_cost(const FilamentGroupContext& ctx, + const std::vector<int>& filament_map) { + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + if (used_filaments.empty()) + return 0; + + auto nozzle_group_result = MultiNozzleUtils::LayeredNozzleGroupResult::create( + filament_map, ctx.nozzle_info.nozzle_list, used_filaments); + + if (!nozzle_group_result) + return -1; + + std::vector<std::vector<unsigned int>> filament_sequences; + auto get_custom_seq_null = [](int, std::vector<int>&) -> bool { return false; }; + + int cost = reorder_filaments_for_multi_nozzle_extruder( + used_filaments, + *nozzle_group_result, + ctx.model_info.layer_filaments, + ctx.model_info.flush_matrix, + get_custom_seq_null, + &filament_sequences, + MultiNozzleUtils::NozzleStatusRecorder{}); + + return cost; +} + +struct FullEvalResult { + int flush_cost = 0; + double change_time = 0.0; + double full_score = 0.0; + bool constraints_ok = true; + std::vector<std::string> violations; +}; + +inline double evaluate_score(double flush, double time) { + double approx_density = 1.26; + double approx_flush_speed = 180; + double correction_factor = 2; + double flush_score = flush * approx_density * approx_flush_speed * correction_factor / 1000; + return flush_score + time; +} + +inline double calc_change_time_for_group_eval( + const std::vector<int>& filament_change_seq, + const std::vector<int>& nozzle_change_seq, + const std::vector<int>& logical_filaments, + const std::vector<MultiNozzleUtils::NozzleInfo>& nozzle_list, + const MultiNozzleUtils::FilamentChangeTimeParams& time_params, + const std::vector<bool>& ams_preload_enabled, + const std::vector<int>& group_of_filament) +{ + auto r = MultiNozzleUtils::simulate_filament_change_time( + logical_filaments, nozzle_list, filament_change_seq, + nozzle_change_seq, group_of_filament, time_params, + ams_preload_enabled); + return r.actual_time; +} + +inline FullEvalResult full_evaluate_map(const FilamentGroupContext& ctx, + const std::vector<int>& filament_map) { + FullEvalResult result; + auto used_filaments = collect_sorted_used_filaments(ctx.model_info.layer_filaments); + if (used_filaments.empty()) return result; + + auto nozzle_group_result = MultiNozzleUtils::LayeredNozzleGroupResult::create( + filament_map, ctx.nozzle_info.nozzle_list, used_filaments); + if (!nozzle_group_result) return result; + + MultiNozzleUtils::NozzleStatusRecorder initial_status; + for (auto& [nozzle_id, filament_id] : ctx.nozzle_info.nozzle_status) { + if (filament_id >= 0) { + int extruder_id = 0; + for (const auto& nozzle : ctx.nozzle_info.nozzle_list) { + if (nozzle.group_id == nozzle_id) { extruder_id = nozzle.extruder_id; break; } + } + initial_status.set_nozzle_status(nozzle_id, filament_id, extruder_id); + } + } + + std::vector<std::vector<unsigned int>> filament_sequences; + auto get_custom_seq_null = [](int, std::vector<int>&) -> bool { return false; }; + + result.flush_cost = reorder_filaments_for_multi_nozzle_extruder( + used_filaments, *nozzle_group_result, ctx.model_info.layer_filaments, + ctx.model_info.flush_matrix, get_custom_seq_null, &filament_sequences, initial_status); + + if (!filament_sequences.empty()) { + std::vector<int> filament_change_seq; + std::vector<int> nozzle_change_seq; + int prev_fil = -1, prev_nozzle = -1; + for (const auto& layer_seq : filament_sequences) { + for (unsigned int fil : layer_seq) { + auto nozzle_info = nozzle_group_result->get_first_nozzle_for_filament(fil); + if (!nozzle_info) continue; + int nid = nozzle_info->group_id; + if ((int)fil == prev_fil && nid == prev_nozzle) continue; + filament_change_seq.push_back((int)fil); + nozzle_change_seq.push_back(nid); + prev_fil = (int)fil; + prev_nozzle = nid; + } + } + + std::vector<int> logical_filaments(used_filaments.begin(), used_filaments.end()); + std::vector<int> group_of_filament(used_filaments.size(), 0); + for (size_t fi = 0; fi < used_filaments.size(); ++fi) { + int nid = filament_map[used_filaments[fi]]; + if (nid >= 0 && nid < (int)ctx.nozzle_info.nozzle_list.size()) + group_of_filament[fi] = ctx.nozzle_info.nozzle_list[nid].extruder_id; + } + result.change_time = calc_change_time_for_group_eval( + filament_change_seq, nozzle_change_seq, logical_filaments, + ctx.nozzle_info.nozzle_list, ctx.speed_info.change_time_params, + ctx.speed_info.ams_preload_enabled, group_of_filament); + } + + result.full_score = evaluate_score(result.flush_cost, result.change_time); + result.constraints_ok = check_constraints(ctx, filament_map, result.violations); + return result; +} + +inline TestResult run_and_evaluate(const FilamentGroupContext& ctx, + const ClusteringBudget& budget = {}) { + TestResult result; + + auto start = std::chrono::high_resolution_clock::now(); + int algo_cost = 0; + + FilamentGroup fg(ctx); + fg.set_clustering_budget(budget); + result.filament_map = fg.calc_filament_group(&algo_cost); + + auto end = std::chrono::high_resolution_clock::now(); + result.elapsed_ms = std::chrono::duration<double, std::milli>(end - start).count(); + + result.flush_cost = compute_flush_cost(ctx, result.filament_map); + + result.constraints_ok = check_constraints(ctx, result.filament_map, result.violations); + + return result; +} + +} // namespace FGTest +} // namespace Slic3r + +#endif // FG_TEST_EVALUATOR_HPP diff --git a/tests/filament_group/fg_test_serialization.hpp b/tests/filament_group/fg_test_serialization.hpp new file mode 100644 index 0000000000..5f59da619c --- /dev/null +++ b/tests/filament_group/fg_test_serialization.hpp @@ -0,0 +1,447 @@ +#ifndef FG_TEST_SERIALIZATION_HPP +#define FG_TEST_SERIALIZATION_HPP + +#include <nlohmann/json.hpp> +#include <libslic3r/FilamentGroup.hpp> +#include <libslic3r/FilamentGroupUtils.hpp> +#include <libslic3r/MultiNozzleUtils.hpp> +#include <libslic3r/PrintConfig.hpp> + +#include <fstream> +#include <optional> +#include <string> +#include <vector> +#include <set> +#include <map> +#include <unordered_map> + +using json = nlohmann::json; + +// Put serializers in correct ADL namespaces for each type + +namespace Slic3r { +namespace FilamentGroupUtils { + +inline void to_json(json& j, const Color& c) { + char buf[10]; + snprintf(buf, sizeof(buf), "#%02X%02X%02X%02X", c.r, c.g, c.b, c.a); + j = std::string(buf); +} + +inline void from_json(const json& j, Color& c) { + std::string s = j.get<std::string>(); + if (s.size() >= 7 && s[0] == '#') { + c.r = (unsigned char)std::stoi(s.substr(1, 2), nullptr, 16); + c.g = (unsigned char)std::stoi(s.substr(3, 2), nullptr, 16); + c.b = (unsigned char)std::stoi(s.substr(5, 2), nullptr, 16); + c.a = (s.size() >= 9) ? (unsigned char)std::stoi(s.substr(7, 2), nullptr, 16) : 255; + } +} + +inline void to_json(json& j, const FilamentInfo& fi) { + j = json{ + {"color", fi.color}, + {"type", fi.type}, + {"is_support", fi.is_support}, + {"usage_type", (int)fi.usage_type} + }; +} + +inline void from_json(const json& j, FilamentInfo& fi) { + fi.color = j.at("color").get<Color>(); + j.at("type").get_to(fi.type); + j.at("is_support").get_to(fi.is_support); + fi.usage_type = (FilamentUsageType)j.at("usage_type").get<int>(); +} + +inline void to_json(json& j, const MachineFilamentInfo& mfi) { + j = json{ + {"color", mfi.color}, + {"type", mfi.type}, + {"is_support", mfi.is_support}, + {"usage_type", (int)mfi.usage_type}, + {"extruder_id", mfi.extruder_id}, + {"is_extended", mfi.is_extended} + }; +} + +inline void from_json(const json& j, MachineFilamentInfo& mfi) { + mfi.color = j.at("color").get<Color>(); + j.at("type").get_to(mfi.type); + j.at("is_support").get_to(mfi.is_support); + mfi.usage_type = (FilamentUsageType)j.at("usage_type").get<int>(); + j.at("extruder_id").get_to(mfi.extruder_id); + j.at("is_extended").get_to(mfi.is_extended); +} + +} // namespace FilamentGroupUtils + +namespace MultiNozzleUtils { + +inline void to_json(json& j, const NozzleInfo& ni) { + j = json{ + {"diameter", ni.diameter}, + {"volume_type", (int)ni.volume_type}, + {"extruder_id", ni.extruder_id}, + {"group_id", ni.group_id} + }; +} + +inline void from_json(const json& j, NozzleInfo& ni) { + j.at("diameter").get_to(ni.diameter); + ni.volume_type = (NozzleVolumeType)j.at("volume_type").get<int>(); + j.at("extruder_id").get_to(ni.extruder_id); + j.at("group_id").get_to(ni.group_id); +} + +inline void to_json(json& j, const FilamentChangeTimeParams& p) { + j = json{ + {"selector_load_time", p.selector_load_time}, + {"selector_unload_time", p.selector_unload_time}, + {"standard_load_time", p.standard_load_time}, + {"standard_unload_time", p.standard_unload_time} + }; +} + +inline void from_json(const json& j, FilamentChangeTimeParams& p) { + j.at("selector_load_time").get_to(p.selector_load_time); + j.at("selector_unload_time").get_to(p.selector_unload_time); + j.at("standard_load_time").get_to(p.standard_load_time); + j.at("standard_unload_time").get_to(p.standard_unload_time); +} + +} // namespace MultiNozzleUtils + +// ============ Helper: set<int> as JSON array ============ +namespace FGTestDetail { +inline json set_to_json(const std::set<int>& s) { + return json(std::vector<int>(s.begin(), s.end())); +} + +inline std::set<int> json_to_set(const json& j) { + auto v = j.get<std::vector<int>>(); + return std::set<int>(v.begin(), v.end()); +} + +inline json nvt_set_to_json(const std::set<NozzleVolumeType>& s) { + std::vector<int> v; + for (auto t : s) v.push_back((int)t); + return json(v); +} + +inline std::set<NozzleVolumeType> json_to_nvt_set(const json& j) { + std::set<NozzleVolumeType> s; + for (auto& item : j) s.insert((NozzleVolumeType)item.get<int>()); + return s; +} +} // namespace FGTestDetail + +// ============ FilamentGroupContext::ModelInfo ============ +inline void to_json(json& j, const FilamentGroupContext::ModelInfo& mi) { + using namespace FGTestDetail; + j["flush_matrix"] = mi.flush_matrix; + j["layer_filaments"] = mi.layer_filaments; + + j["filament_info"] = json::array(); + for (auto& fi : mi.filament_info) + j["filament_info"].push_back(fi); + + j["filament_ids"] = mi.filament_ids; + + j["unprintable_filaments"] = json::array(); + for (auto& s : mi.unprintable_filaments) + j["unprintable_filaments"].push_back(set_to_json(s)); + + json uv = json::object(); + for (auto& [fil, types] : mi.unprintable_volumes) + uv[std::to_string(fil)] = nvt_set_to_json(types); + j["unprintable_volumes"] = uv; +} + +inline void from_json(const json& j, FilamentGroupContext::ModelInfo& mi) { + using namespace FGTestDetail; + j.at("flush_matrix").get_to(mi.flush_matrix); + j.at("layer_filaments").get_to(mi.layer_filaments); + + mi.filament_info.clear(); + for (auto& item : j.at("filament_info")) + mi.filament_info.push_back(item.get<FilamentGroupUtils::FilamentInfo>()); + + j.at("filament_ids").get_to(mi.filament_ids); + + mi.unprintable_filaments.clear(); + for (auto& item : j.at("unprintable_filaments")) + mi.unprintable_filaments.push_back(json_to_set(item)); + + mi.unprintable_volumes.clear(); + if (j.contains("unprintable_volumes")) { + for (auto& [k, v] : j.at("unprintable_volumes").items()) + mi.unprintable_volumes[std::stoi(k)] = json_to_nvt_set(v); + } +} + +// ============ FilamentGroupContext::GroupInfo ============ +inline void to_json(json& j, const FilamentGroupContext::GroupInfo& gi) { + j = json{ + {"total_filament_num", gi.total_filament_num}, + {"max_gap_threshold", gi.max_gap_threshold}, + {"mode", (int)gi.mode}, + {"strategy", (int)gi.strategy}, + {"ignore_ext_filament", gi.ignore_ext_filament}, + {"has_filament_switcher", gi.has_filament_switcher}, + {"filament_volume_map", gi.filament_volume_map} + }; +} + +inline void from_json(const json& j, FilamentGroupContext::GroupInfo& gi) { + j.at("total_filament_num").get_to(gi.total_filament_num); + j.at("max_gap_threshold").get_to(gi.max_gap_threshold); + gi.mode = (FGMode)j.at("mode").get<int>(); + gi.strategy = (FGStrategy)j.at("strategy").get<int>(); + j.at("ignore_ext_filament").get_to(gi.ignore_ext_filament); + j.at("has_filament_switcher").get_to(gi.has_filament_switcher); + j.at("filament_volume_map").get_to(gi.filament_volume_map); +} + +// ============ FilamentGroupContext::MachineInfo ============ +inline void to_json(json& j, const FilamentGroupContext::MachineInfo& mi) { + j["max_group_size"] = mi.max_group_size; + + j["machine_filament_info"] = json::array(); + for (auto& vec : mi.machine_filament_info) { + json arr = json::array(); + for (auto& mfi : vec) arr.push_back(mfi); + j["machine_filament_info"].push_back(arr); + } + + j["prefer_non_model_filament"] = mi.prefer_non_model_filament; + j["master_extruder_id"] = mi.master_extruder_id; +} + +inline void from_json(const json& j, FilamentGroupContext::MachineInfo& mi) { + j.at("max_group_size").get_to(mi.max_group_size); + + mi.machine_filament_info.clear(); + for (auto& arr : j.at("machine_filament_info")) { + std::vector<FilamentGroupUtils::MachineFilamentInfo> vec; + for (auto& item : arr) + vec.push_back(item.get<FilamentGroupUtils::MachineFilamentInfo>()); + mi.machine_filament_info.push_back(std::move(vec)); + } + + j.at("prefer_non_model_filament").get_to(mi.prefer_non_model_filament); + j.at("master_extruder_id").get_to(mi.master_extruder_id); +} + +// ============ FilamentGroupContext::SpeedInfo ============ +inline void to_json(json& j, const FilamentGroupContext::SpeedInfo& si) { + json fpt = json::object(); + for (auto& [fil, inner] : si.filament_print_time) { + json inner_j = json::object(); + for (auto& [layer, time] : inner) + inner_j[std::to_string(layer)] = time; + fpt[std::to_string(fil)] = inner_j; + } + j["filament_print_time"] = fpt; + j["extruder_change_time"] = si.extruder_change_time; + j["filament_change_time"] = si.filament_change_time; + j["group_with_time"] = si.group_with_time; + j["change_time_params"] = si.change_time_params; + j["ams_preload_enabled"] = si.ams_preload_enabled; +} + +inline void from_json(const json& j, FilamentGroupContext::SpeedInfo& si) { + si.filament_print_time.clear(); + if (j.contains("filament_print_time")) { + for (auto& [k, v] : j.at("filament_print_time").items()) { + int fil = std::stoi(k); + for (auto& [k2, v2] : v.items()) + si.filament_print_time[fil][std::stoi(k2)] = v2.get<double>(); + } + } + j.at("extruder_change_time").get_to(si.extruder_change_time); + j.at("filament_change_time").get_to(si.filament_change_time); + j.at("group_with_time").get_to(si.group_with_time); + si.change_time_params = j.at("change_time_params").get<MultiNozzleUtils::FilamentChangeTimeParams>(); + j.at("ams_preload_enabled").get_to(si.ams_preload_enabled); +} + +// ============ FilamentGroupContext::NozzleInfo ============ +inline void to_json(json& j, const FilamentGroupContext::NozzleInfo& ni) { + json enl = json::object(); + for (auto& [ext, nozzles] : ni.extruder_nozzle_list) + enl[std::to_string(ext)] = nozzles; + j["extruder_nozzle_list"] = enl; + + j["nozzle_list"] = json::array(); + for (auto& n : ni.nozzle_list) + j["nozzle_list"].push_back(n); + + json ns = json::object(); + for (auto& [noz, fil] : ni.nozzle_status) + ns[std::to_string(noz)] = fil; + j["nozzle_status"] = ns; +} + +inline void from_json(const json& j, FilamentGroupContext::NozzleInfo& ni) { + ni.extruder_nozzle_list.clear(); + for (auto& [k, v] : j.at("extruder_nozzle_list").items()) + ni.extruder_nozzle_list[std::stoi(k)] = v.get<std::vector<int>>(); + + ni.nozzle_list.clear(); + for (auto& item : j.at("nozzle_list")) + ni.nozzle_list.push_back(item.get<MultiNozzleUtils::NozzleInfo>()); + + ni.nozzle_status.clear(); + if (j.contains("nozzle_status")) { + for (auto& [k, v] : j.at("nozzle_status").items()) + ni.nozzle_status[std::stoi(k)] = v.get<int>(); + } +} + +// ============ Full FilamentGroupContext ============ +inline void to_json(json& j, const FilamentGroupContext& ctx) { + json mi, gi, mai, si, ni; + to_json(mi, ctx.model_info); + to_json(gi, ctx.group_info); + to_json(mai, ctx.machine_info); + to_json(si, ctx.speed_info); + to_json(ni, ctx.nozzle_info); + j["model_info"] = mi; + j["group_info"] = gi; + j["machine_info"] = mai; + j["speed_info"] = si; + j["nozzle_info"] = ni; +} + +inline void from_json(const json& j, FilamentGroupContext& ctx) { + from_json(j.at("model_info"), ctx.model_info); + from_json(j.at("group_info"), ctx.group_info); + from_json(j.at("machine_info"), ctx.machine_info); + from_json(j.at("speed_info"), ctx.speed_info); + from_json(j.at("nozzle_info"), ctx.nozzle_info); +} + +} // namespace Slic3r + +// ============ Test-specific types in FGTest namespace ============ +namespace Slic3r { +namespace FGTest { + +struct TestMetadata { + std::string id; + std::string config_type; + int seed = 0; +}; + +inline void to_json(json& j, const TestMetadata& m) { + j = json{{"id", m.id}, {"config_type", m.config_type}, {"seed", m.seed}}; +} + +inline void from_json(const json& j, TestMetadata& m) { + j.at("id").get_to(m.id); + j.at("config_type").get_to(m.config_type); + j.at("seed").get_to(m.seed); +} + +struct TestResult { + std::vector<int> filament_map; + int flush_cost = 0; + double elapsed_ms = 0; + bool constraints_ok = true; + std::vector<std::string> violations; +}; + +inline void to_json(json& j, const TestResult& r) { + j = json{ + {"filament_map", r.filament_map}, + {"flush_cost", r.flush_cost}, + {"elapsed_ms", r.elapsed_ms}, + {"constraints_ok", r.constraints_ok}, + {"violations", r.violations} + }; +} + +inline void from_json(const json& j, TestResult& r) { + j.at("filament_map").get_to(r.filament_map); + j.at("flush_cost").get_to(r.flush_cost); + j.at("elapsed_ms").get_to(r.elapsed_ms); + j.at("constraints_ok").get_to(r.constraints_ok); + if (j.contains("violations")) + j.at("violations").get_to(r.violations); +} + +// ============ Base Result (golden baseline stored in input file) ============ +struct BaseResult { + double full_score = 0; + int flush_cost = 0; + bool constraints_ok = true; +}; + +inline void to_json(json& j, const BaseResult& g) { + j = json{ + {"full_score", g.full_score}, + {"flush_cost", g.flush_cost}, + {"constraints_ok", g.constraints_ok} + }; +} + +inline void from_json(const json& j, BaseResult& g) { + j.at("full_score").get_to(g.full_score); + j.at("flush_cost").get_to(g.flush_cost); + j.at("constraints_ok").get_to(g.constraints_ok); +} + +// ============ File I/O ============ +struct TestCase { + TestMetadata metadata; + FilamentGroupContext context; + std::optional<BaseResult> base_result; +}; + +inline TestCase load_test_case(const std::string& path) { + std::ifstream f(path); + json j = json::parse(f); + TestCase tc; + tc.metadata = j.at("metadata").get<TestMetadata>(); + Slic3r::from_json(j.at("context"), tc.context); + if (j.contains("base_result")) + tc.base_result = j.at("base_result").get<BaseResult>(); + return tc; +} + +inline void save_test_case(const std::string& path, const TestCase& tc) { + json j; + j["metadata"] = tc.metadata; + json ctx_j; + Slic3r::to_json(ctx_j, tc.context); + j["context"] = ctx_j; + if (tc.base_result) + j["base_result"] = *tc.base_result; + std::ofstream f(path); + f << j.dump(-1); +} + +inline void save_result(const std::string& case_path, const TestResult& result) { + std::string result_path = case_path; + auto pos = result_path.rfind(".json"); + if (pos != std::string::npos) + result_path = result_path.substr(0, pos) + ".result.json"; + else + result_path += ".result.json"; + + json j = result; + std::ofstream f(result_path); + f << j.dump(2); +} + +inline TestResult load_result(const std::string& result_path) { + std::ifstream f(result_path); + json j = json::parse(f); + return j.get<TestResult>(); +} + +} // namespace FGTest +} // namespace Slic3r + +#endif // FG_TEST_SERIALIZATION_HPP diff --git a/tests/filament_group/fg_test_utils.hpp b/tests/filament_group/fg_test_utils.hpp new file mode 100644 index 0000000000..2d2864bf10 --- /dev/null +++ b/tests/filament_group/fg_test_utils.hpp @@ -0,0 +1,406 @@ +#ifndef FG_TEST_UTILS_HPP +#define FG_TEST_UTILS_HPP + +#include "fg_test_serialization.hpp" +#include <random> +#include <algorithm> +#include <cassert> + +namespace Slic3r { +namespace FGTest { + +class TestRng { +public: + explicit TestRng(int seed) : m_gen(seed) {} + + int rand_int(int lo, int hi) { + std::uniform_int_distribution<int> dist(lo, hi); + return dist(m_gen); + } + + float rand_float(float lo, float hi) { + std::uniform_real_distribution<float> dist(lo, hi); + return dist(m_gen); + } + + double rand_double(double lo, double hi) { + std::uniform_real_distribution<double> dist(lo, hi); + return dist(m_gen); + } + + bool rand_bool(double prob = 0.5) { + return rand_double(0, 1) < prob; + } + + template<typename T> + void shuffle(std::vector<T>& v) { + std::shuffle(v.begin(), v.end(), m_gen); + } + +private: + std::mt19937 m_gen; +}; + +// Generate a flush matrix for one extruder: [filament_count x filament_count] +inline std::vector<std::vector<float>> generate_flush_matrix(int filament_count, TestRng& rng) { + std::vector<std::vector<float>> matrix(filament_count, std::vector<float>(filament_count, 0.0f)); + for (int i = 0; i < filament_count; ++i) { + for (int j = 0; j < filament_count; ++j) { + if (i == j) + matrix[i][j] = 0.0f; + else + matrix[i][j] = rng.rand_float(10.0f, 600.0f); + } + } + return matrix; +} + +// Generate layer_filaments with interval characteristics +inline std::vector<std::vector<unsigned int>> generate_layer_filaments_interval( + int num_layers, int total_filaments, const std::vector<unsigned int>& used_filaments, TestRng& rng) +{ + std::vector<std::vector<unsigned int>> layers; + layers.reserve(num_layers); + + int n_used = (int)used_filaments.size(); + int fils_per_layer_min = std::min(2, n_used); + int fils_per_layer_max = std::min(n_used, std::max(2, n_used / 2 + 1)); + + // First layer: random subset + int first_count = rng.rand_int(fils_per_layer_min, fils_per_layer_max); + std::vector<unsigned int> pool = used_filaments; + rng.shuffle(pool); + std::vector<unsigned int> current(pool.begin(), pool.begin() + first_count); + std::sort(current.begin(), current.end()); + layers.push_back(current); + + for (int layer = 1; layer < num_layers; ++layer) { + // 10% chance: completely random new set (object boundary) + if (rng.rand_bool(0.10)) { + int count = rng.rand_int(fils_per_layer_min, fils_per_layer_max); + pool = used_filaments; + rng.shuffle(pool); + current.assign(pool.begin(), pool.begin() + count); + } else { + // Markov: keep each filament with 70% prob, maybe add new ones + std::vector<unsigned int> next; + for (auto f : current) { + if (rng.rand_bool(0.70)) + next.push_back(f); + } + // Maybe add a filament not in current + if (rng.rand_bool(0.30) || next.empty()) { + std::vector<unsigned int> candidates; + std::set<unsigned int> cur_set(next.begin(), next.end()); + for (auto f : used_filaments) { + if (!cur_set.count(f)) + candidates.push_back(f); + } + if (!candidates.empty()) { + next.push_back(candidates[rng.rand_int(0, (int)candidates.size() - 1)]); + } + } + if (next.empty()) + next.push_back(used_filaments[rng.rand_int(0, n_used - 1)]); + current = next; + } + std::sort(current.begin(), current.end()); + current.erase(std::unique(current.begin(), current.end()), current.end()); + layers.push_back(current); + } + + return layers; +} + +// Generate layer_filaments where every layer is different (stress/edge) +inline std::vector<std::vector<unsigned int>> generate_layer_filaments_chaotic( + int num_layers, int total_filaments, const std::vector<unsigned int>& used_filaments, TestRng& rng) +{ + std::vector<std::vector<unsigned int>> layers; + int n_used = (int)used_filaments.size(); + int fils_per_layer_min = std::min(2, n_used); + int fils_per_layer_max = n_used; + + for (int layer = 0; layer < num_layers; ++layer) { + int count = rng.rand_int(fils_per_layer_min, fils_per_layer_max); + std::vector<unsigned int> pool = used_filaments; + rng.shuffle(pool); + std::vector<unsigned int> current(pool.begin(), pool.begin() + count); + std::sort(current.begin(), current.end()); + layers.push_back(current); + } + return layers; +} + +// Generate layer_filaments where all layers are the same (edge) +inline std::vector<std::vector<unsigned int>> generate_layer_filaments_uniform( + int num_layers, const std::vector<unsigned int>& used_filaments) +{ + return std::vector<std::vector<unsigned int>>(num_layers, used_filaments); +} + +// Generate filament info +inline std::vector<FilamentGroupUtils::FilamentInfo> generate_filament_info(int count, TestRng& rng) { + static const char* types[] = {"PLA", "ABS", "PETG", "TPU", "PA", "PLA-S"}; + std::vector<FilamentGroupUtils::FilamentInfo> infos; + for (int i = 0; i < count; ++i) { + FilamentGroupUtils::FilamentInfo fi; + fi.color = FilamentGroupUtils::Color( + (unsigned char)rng.rand_int(0, 255), + (unsigned char)rng.rand_int(0, 255), + (unsigned char)rng.rand_int(0, 255)); + fi.type = types[rng.rand_int(0, 5)]; + fi.is_support = (fi.type == "PLA-S"); + fi.usage_type = fi.is_support ? FilamentUsageType::SupportOnly : FilamentUsageType::ModelOnly; + infos.push_back(fi); + } + return infos; +} + +// Generate machine filament info (per extruder) +inline std::vector<std::vector<FilamentGroupUtils::MachineFilamentInfo>> generate_machine_filament_info( + int num_extruders, int filaments_per_extruder, TestRng& rng) +{ + std::vector<std::vector<FilamentGroupUtils::MachineFilamentInfo>> result; + for (int ext = 0; ext < num_extruders; ++ext) { + std::vector<FilamentGroupUtils::MachineFilamentInfo> vec; + for (int i = 0; i < filaments_per_extruder; ++i) { + FilamentGroupUtils::MachineFilamentInfo mfi; + mfi.color = FilamentGroupUtils::Color( + (unsigned char)rng.rand_int(0, 255), + (unsigned char)rng.rand_int(0, 255), + (unsigned char)rng.rand_int(0, 255)); + mfi.type = "PLA"; + mfi.is_support = false; + mfi.usage_type = FilamentUsageType::ModelOnly; + mfi.extruder_id = ext; + mfi.is_extended = (i >= 4); + vec.push_back(mfi); + } + result.push_back(vec); + } + return result; +} + +// ============ Machine Config Builders ============ + +// Config A: 2 extruders, 1 nozzle each +inline void build_config_a(FilamentGroupContext& ctx, int num_filaments, TestRng& rng) { + auto& ni = ctx.nozzle_info; + ni.nozzle_list.clear(); + ni.nozzle_list.push_back({"0.4", NozzleVolumeType::nvtStandard, 0, 0}); + ni.nozzle_list.push_back({"0.4", NozzleVolumeType::nvtStandard, 1, 1}); + ni.extruder_nozzle_list = {{0, {0}}, {1, {1}}}; + + ctx.machine_info.max_group_size = {num_filaments / 2 + 1, num_filaments / 2 + 1}; + ctx.machine_info.prefer_non_model_filament = {false, true}; + ctx.machine_info.master_extruder_id = 0; + ctx.machine_info.machine_filament_info = generate_machine_filament_info(2, 4, rng); + + ctx.group_info.filament_volume_map.assign(num_filaments, (int)NozzleVolumeType::nvtHybrid); + + ctx.model_info.unprintable_filaments.resize(2); + ctx.model_info.flush_matrix.resize(2); + for (int ext = 0; ext < 2; ++ext) + ctx.model_info.flush_matrix[ext] = generate_flush_matrix(num_filaments, rng); +} + +// Config B: 2 extruders, ext0 has 1 nozzle, ext1 has K nozzles (K in [2,6]) +inline void build_config_b(FilamentGroupContext& ctx, int num_filaments, int k_nozzles, TestRng& rng) { + auto& ni = ctx.nozzle_info; + ni.nozzle_list.clear(); + ni.nozzle_list.push_back({"0.4", NozzleVolumeType::nvtStandard, 0, 0}); + + static const NozzleVolumeType vol_types[] = { + NozzleVolumeType::nvtStandard, NozzleVolumeType::nvtHighFlow, NozzleVolumeType::nvtTPUHighFlow}; + + std::vector<int> ext1_nozzles; + for (int i = 0; i < k_nozzles; ++i) { + int group_id = i + 1; + NozzleVolumeType vt = vol_types[rng.rand_int(0, 2)]; + ni.nozzle_list.push_back({"0.4", vt, 1, group_id}); + ext1_nozzles.push_back(group_id); + } + ni.extruder_nozzle_list = {{0, {0}}, {1, ext1_nozzles}}; + + int ext0_max = std::max(4, num_filaments / 2 + 1); + int ext1_max = std::max(k_nozzles * 2, num_filaments - ext0_max + 1); + ctx.machine_info.max_group_size = {ext0_max, ext1_max}; + ctx.machine_info.prefer_non_model_filament = {false, false}; + ctx.machine_info.master_extruder_id = 0; + ctx.machine_info.machine_filament_info = generate_machine_filament_info(2, 4, rng); + + ctx.group_info.filament_volume_map.assign(num_filaments, (int)NozzleVolumeType::nvtHybrid); + + ctx.model_info.unprintable_filaments.resize(2); + ctx.model_info.flush_matrix.resize(2); + for (int ext = 0; ext < 2; ++ext) + ctx.model_info.flush_matrix[ext] = generate_flush_matrix(num_filaments, rng); +} + +// Config C: 1 extruder, K nozzles (K in [3,9]) +inline void build_config_c(FilamentGroupContext& ctx, int num_filaments, int k_nozzles, TestRng& rng) { + auto& ni = ctx.nozzle_info; + ni.nozzle_list.clear(); + + static const NozzleVolumeType vol_types[] = { + NozzleVolumeType::nvtStandard, NozzleVolumeType::nvtHighFlow, + NozzleVolumeType::nvtHybrid, NozzleVolumeType::nvtTPUHighFlow}; + + std::vector<int> nozzle_ids; + for (int i = 0; i < k_nozzles; ++i) { + NozzleVolumeType vt = vol_types[i % 4]; + ni.nozzle_list.push_back({"0.4", vt, 0, i}); + nozzle_ids.push_back(i); + } + ni.extruder_nozzle_list = {{0, nozzle_ids}}; + + ctx.machine_info.max_group_size = {num_filaments}; + ctx.machine_info.prefer_non_model_filament = {false}; + ctx.machine_info.master_extruder_id = 0; + ctx.machine_info.machine_filament_info = generate_machine_filament_info(1, 4, rng); + + ctx.group_info.filament_volume_map.assign(num_filaments, (int)NozzleVolumeType::nvtHybrid); + + ctx.model_info.unprintable_filaments.resize(1); + ctx.model_info.flush_matrix.resize(1); + ctx.model_info.flush_matrix[0] = generate_flush_matrix(num_filaments, rng); +} + +// ============ Constraint Injection ============ + +// Add unprintable_filaments constraints (some filaments forbidden on some extruders) +inline void inject_unprintable_constraints(FilamentGroupContext& ctx, + const std::vector<unsigned int>& used_filaments, + TestRng& rng, int num_constraints) { + int num_ext = (int)ctx.model_info.unprintable_filaments.size(); + for (int i = 0; i < num_constraints && !used_filaments.empty(); ++i) { + int fil = used_filaments[rng.rand_int(0, (int)used_filaments.size() - 1)]; + int ext = rng.rand_int(0, num_ext - 1); + ctx.model_info.unprintable_filaments[ext].insert(fil); + } + // Ensure no filament is banned from ALL extruders + for (auto fil : used_filaments) { + bool can_print_somewhere = false; + for (int ext = 0; ext < num_ext; ++ext) { + if (!ctx.model_info.unprintable_filaments[ext].count(fil)) { + can_print_somewhere = true; + break; + } + } + if (!can_print_somewhere) { + int ext_to_allow = rng.rand_int(0, num_ext - 1); + ctx.model_info.unprintable_filaments[ext_to_allow].erase(fil); + } + } +} + +// Add unprintable_volumes constraints +inline void inject_volume_constraints(FilamentGroupContext& ctx, + const std::vector<unsigned int>& used_filaments, + TestRng& rng, int num_constraints) { + static const NozzleVolumeType vols[] = { + NozzleVolumeType::nvtStandard, NozzleVolumeType::nvtHighFlow, + NozzleVolumeType::nvtTPUHighFlow}; + + for (int i = 0; i < num_constraints && !used_filaments.empty(); ++i) { + int fil = used_filaments[rng.rand_int(0, (int)used_filaments.size() - 1)]; + NozzleVolumeType vt = vols[rng.rand_int(0, 2)]; + ctx.model_info.unprintable_volumes[fil].insert(vt); + } + // Ensure no filament is banned from ALL nozzle volume types present + for (auto fil : used_filaments) { + if (!ctx.model_info.unprintable_volumes.count(fil)) + continue; + auto& banned = ctx.model_info.unprintable_volumes[fil]; + bool can_go_somewhere = false; + for (auto& noz : ctx.nozzle_info.nozzle_list) { + if (!banned.count(noz.volume_type)) { + can_go_somewhere = true; + break; + } + } + if (!can_go_somewhere && !banned.empty()) { + // Remove one random ban + auto it = banned.begin(); + std::advance(it, rng.rand_int(0, (int)banned.size() - 1)); + banned.erase(it); + } + } +} + +// ============ Full Case Builder ============ + +inline TestCase build_test_case(const std::string& id, const std::string& config_type, + int seed, int num_filaments, int num_layers, + bool chaotic_layers, bool with_constraints, + FGMode mode, FGStrategy strategy, bool group_with_time) { + TestRng rng(seed); + TestCase tc; + tc.metadata.id = id; + tc.metadata.config_type = config_type; + tc.metadata.seed = seed; + + auto& ctx = tc.context; + + // Used filaments: 0-based indices + std::vector<unsigned int> used_filaments; + for (int i = 0; i < num_filaments; ++i) + used_filaments.push_back((unsigned int)i); + + // Build machine config + if (config_type == "A") { + build_config_a(ctx, num_filaments, rng); + } else if (config_type == "B") { + int k = rng.rand_int(2, 6); + build_config_b(ctx, num_filaments, k, rng); + } else { + int k = rng.rand_int(3, 9); + build_config_c(ctx, num_filaments, k, rng); + } + + // Layer filaments + if (chaotic_layers) + ctx.model_info.layer_filaments = generate_layer_filaments_chaotic(num_layers, num_filaments, used_filaments, rng); + else + ctx.model_info.layer_filaments = generate_layer_filaments_interval(num_layers, num_filaments, used_filaments, rng); + + // Filament info + ctx.model_info.filament_info = generate_filament_info(num_filaments, rng); + ctx.model_info.filament_ids.resize(num_filaments); + for (int i = 0; i < num_filaments; ++i) + ctx.model_info.filament_ids[i] = "GFL_" + std::to_string(i); + + // Group info + ctx.group_info.total_filament_num = num_filaments; + ctx.group_info.max_gap_threshold = 0.01; + ctx.group_info.mode = mode; + ctx.group_info.strategy = strategy; + ctx.group_info.ignore_ext_filament = false; + ctx.group_info.has_filament_switcher = false; + + // Speed info + ctx.speed_info.extruder_change_time = 5.0; + ctx.speed_info.filament_change_time = 2.0; + ctx.speed_info.group_with_time = group_with_time; + ctx.speed_info.change_time_params = {1.0f, 1.0f, 3.0f, 2.0f}; + int num_ext = (config_type == "C") ? 1 : 2; + ctx.speed_info.ams_preload_enabled.assign(num_ext, true); + + // Constraints + if (with_constraints) { + inject_unprintable_constraints(ctx, used_filaments, rng, rng.rand_int(1, num_filaments / 2)); + if (config_type != "A") + inject_volume_constraints(ctx, used_filaments, rng, rng.rand_int(1, 3)); + } + + // Nozzle status (initially empty) + ctx.nozzle_info.nozzle_status.clear(); + + return tc; +} + +} // namespace FGTest +} // namespace Slic3r + +#endif // FG_TEST_UTILS_HPP diff --git a/tests/filament_group/filament_group_regression_main.cpp b/tests/filament_group/filament_group_regression_main.cpp new file mode 100644 index 0000000000..b2cc4bd178 --- /dev/null +++ b/tests/filament_group/filament_group_regression_main.cpp @@ -0,0 +1,330 @@ +// H2C/A2L FilamentGroup golden regression harness. +// +// Notes: +// * Orca: links Catch2::Catch2WithMain and uses the v3 convenience include <catch2/catch_all.hpp>. +// * All three golden families (config_a one-nozzle-per-extruder, config_b/config_c nozzle-centric) +// are evaluated against the goldens. The nozzle-centric FilamentGroup engine and solver layer run +// the same algorithm the goldens were generated with, scored via the nozzle-aware reorder +// (fg_test_evaluator.hpp) at a 3% one-directional tolerance. +// * The hidden [update-golden] utility is intentionally omitted: the goldens are the reference +// and must not be rewritten from Orca output. + +#include <catch2/catch_all.hpp> + +#include "fg_test_serialization.hpp" +#include "fg_test_evaluator.hpp" +#include "fg_test_utils.hpp" + +#include <filesystem> +#include <iostream> +#include <fstream> +#include <string> +#include <vector> +#include <algorithm> +#include <numeric> + +namespace fs = std::filesystem; +using namespace Slic3r; +using namespace Slic3r::FGTest; + +// ============ Helpers ============ + +static std::vector<std::string> collect_test_files(const std::string& dir) { + std::vector<std::string> files; + if (!fs::exists(dir)) return files; + for (auto& entry : fs::recursive_directory_iterator(dir)) { + if (entry.path().extension() == ".json" && + entry.path().string().find(".result.") == std::string::npos) { + files.push_back(entry.path().string()); + } + } + std::sort(files.begin(), files.end()); + return files; +} + +static std::vector<std::string> get_golden_files() { + static std::vector<std::string> files = collect_test_files(FG_TEST_GOLDEN_DIR); + return files; +} + +static bool is_constraint_feasible(const FilamentGroupContext& ctx, + const std::vector<unsigned int>& used_filaments) { + int total_capacity = 0; + for (auto sz : ctx.machine_info.max_group_size) + total_capacity += sz; + if (total_capacity < (int)used_filaments.size()) + return false; + + // Check that every filament has at least one valid nozzle + for (auto fil : used_filaments) { + bool has_valid_nozzle = false; + for (size_t nid = 0; nid < ctx.nozzle_info.nozzle_list.size(); ++nid) { + auto& nozzle = ctx.nozzle_info.nozzle_list[nid]; + // Check unprintable_filaments + if (nozzle.extruder_id >= 0 && nozzle.extruder_id < (int)ctx.model_info.unprintable_filaments.size()) { + if (ctx.model_info.unprintable_filaments[nozzle.extruder_id].count(fil)) + continue; + } + // Check unprintable_volumes + if (ctx.model_info.unprintable_volumes.count(fil)) { + if (ctx.model_info.unprintable_volumes.at(fil).count(nozzle.volume_type)) + continue; + } + has_valid_nozzle = true; + break; + } + if (!has_valid_nozzle) + return false; + } + return true; +} + +// ============ Property Check Specs ============ + +struct PropertySpec { + std::string id; + std::string config; + int seed; + int num_filaments; + int num_layers; + bool chaotic; + bool with_constraints; + FGMode mode; + FGStrategy strategy; + bool group_with_time; +}; + +static std::vector<PropertySpec> build_property_specs() { + std::vector<PropertySpec> specs; + + // Config A: 20 cases + for (int i = 0; i < 6; ++i) { + int seed = 90000 + i; + TestRng rng(seed); + specs.push_back({"prop_a_basic_" + std::to_string(i), "A", seed, + rng.rand_int(2, 6), rng.rand_int(100, 400), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 4; ++i) { + int seed = 90100 + i; + TestRng rng(seed); + specs.push_back({"prop_a_stress_" + std::to_string(i), "A", seed, + rng.rand_int(7, 10), rng.rand_int(500, 1000), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 4; ++i) { + int seed = 90200 + i; + TestRng rng(seed); + specs.push_back({"prop_a_constraint_" + std::to_string(i), "A", seed, + rng.rand_int(3, 8), rng.rand_int(100, 400), + false, true, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 3; ++i) { + int seed = 90300 + i; + TestRng rng(seed); + specs.push_back({"prop_a_edge_" + std::to_string(i), "A", seed, + rng.rand_int(2, 3), rng.rand_int(10, 50), + true, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + specs.push_back({"prop_a_mode_match", "A", 90400, + 5, 200, false, false, FGMode::MatchMode, FGStrategy::BestCost, false}); + specs.push_back({"prop_a_mode_bestfit", "A", 90401, + 5, 200, false, false, FGMode::FlushMode, FGStrategy::BestFit, false}); + specs.push_back({"prop_a_mode_time", "A", 90402, + 5, 200, false, false, FGMode::FlushMode, FGStrategy::BestCost, true}); + + // Config B: 25 cases + for (int i = 0; i < 6; ++i) { + int seed = 91000 + i; + TestRng rng(seed); + specs.push_back({"prop_b_basic_" + std::to_string(i), "B", seed, + rng.rand_int(3, 8), rng.rand_int(100, 400), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 6; ++i) { + int seed = 91100 + i; + TestRng rng(seed); + specs.push_back({"prop_b_stress_" + std::to_string(i), "B", seed, + rng.rand_int(9, 12), rng.rand_int(500, 1000), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 7; ++i) { + int seed = 91200 + i; + TestRng rng(seed); + specs.push_back({"prop_b_constraint_" + std::to_string(i), "B", seed, + rng.rand_int(4, 10), rng.rand_int(100, 400), + false, true, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 3; ++i) { + int seed = 91300 + i; + TestRng rng(seed); + specs.push_back({"prop_b_edge_" + std::to_string(i), "B", seed, + rng.rand_int(2, 4), rng.rand_int(10, 50), + true, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + specs.push_back({"prop_b_mode_match", "B", 91400, + 6, 200, false, false, FGMode::MatchMode, FGStrategy::BestCost, false}); + specs.push_back({"prop_b_mode_bestfit", "B", 91401, + 6, 200, false, false, FGMode::FlushMode, FGStrategy::BestFit, false}); + specs.push_back({"prop_b_mode_time", "B", 91402, + 6, 200, false, false, FGMode::FlushMode, FGStrategy::BestCost, true}); + + // Config C: 15 cases + for (int i = 0; i < 5; ++i) { + int seed = 92000 + i; + TestRng rng(seed); + specs.push_back({"prop_c_basic_" + std::to_string(i), "C", seed, + rng.rand_int(3, 9), rng.rand_int(100, 400), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 3; ++i) { + int seed = 92100 + i; + TestRng rng(seed); + specs.push_back({"prop_c_stress_" + std::to_string(i), "C", seed, + rng.rand_int(10, 15), rng.rand_int(500, 1000), + false, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 3; ++i) { + int seed = 92200 + i; + TestRng rng(seed); + specs.push_back({"prop_c_constraint_" + std::to_string(i), "C", seed, + rng.rand_int(4, 9), rng.rand_int(100, 400), + false, true, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + for (int i = 0; i < 2; ++i) { + int seed = 92300 + i; + TestRng rng(seed); + specs.push_back({"prop_c_edge_" + std::to_string(i), "C", seed, + rng.rand_int(2, 4), rng.rand_int(10, 50), + true, false, FGMode::FlushMode, FGStrategy::BestCost, false}); + } + specs.push_back({"prop_c_mode_match", "C", 92400, + 6, 200, false, false, FGMode::MatchMode, FGStrategy::BestCost, false}); + specs.push_back({"prop_c_mode_bestfit", "C", 92401, + 6, 200, false, false, FGMode::FlushMode, FGStrategy::BestFit, false}); + + return specs; +} + +static std::vector<PropertySpec>& get_property_specs() { + static std::vector<PropertySpec> specs = build_property_specs(); + return specs; +} + +// Under the default wall clock the result depends on how fast the machine is (see ClusteringBudget), +// so the goldens are graded under a fixed budget instead. Two restarts is the fewest that reaches +// parity with the reference on every golden, stress_79 being the last to get there. Four leaves +// margin, since the search follows a different path on each standard library (see below). +static constexpr ClusteringBudget FIXED_SEARCH_BUDGET{ + /*timeout_ms*/ 0, // no wall clock + /*max_restarts*/ 4}; + +// ============ Layer 1: Golden Regression (all configs) ============ + +// Graded against the BambuStudio golden the harness was ported from, one-directional at 3%. +// +// The tolerance is a parity allowance, and it also covers a small spread across standard libraries. +// The k-medoids search seeds each restart with std::shuffle, whose algorithm the C++ standard leaves +// unspecified, so libstdc++, libc++ and the MSVC STL permute the same seed differently, start from +// different medoids, and settle on slightly different groupings, about 3e-4 apart on either side of +// the reference, and only on the goldens heavy enough to reach the k-medoids search. +TEST_CASE("FilamentGroup golden regression", "[filament_group][golden]") { + auto files = get_golden_files(); + if (files.empty()) { + WARN("No golden files found in " FG_TEST_GOLDEN_DIR); + REQUIRE(!files.empty()); + return; + } + + auto file_path = GENERATE_REF(from_range(files)); + + DYNAMIC_SECTION("Golden: " << fs::path(file_path).stem().string()) { + auto tc = load_test_case(file_path); + REQUIRE(tc.base_result.has_value()); + + auto result = run_and_evaluate(tc.context, FIXED_SEARCH_BUDGET); + auto eval = full_evaluate_map(tc.context, result.filament_map); + + auto& base = *tc.base_result; + + INFO("Case: " << tc.metadata.id); + INFO("Golden score: " << base.full_score); + INFO("Actual score: " << eval.full_score); + INFO("Flush cost: " << eval.flush_cost << " (golden " << base.flush_cost << ")"); + INFO("Elapsed: " << result.elapsed_ms << " ms"); + + int tolerance = std::max(50, (int)(base.full_score * 0.03)); + + REQUIRE(result.constraints_ok); + REQUIRE(eval.full_score <= base.full_score + tolerance); + + // A slower search still scores the same above, since it searches just as far, but in slicing + // it would mean fewer restarts fit in the wall clock and so worse groupings. Loose on + // purpose, so it never becomes a proxy for how loaded the runner is. + const double throughput_ceiling_ms = 10.0 * ClusteringBudget{}.timeout_ms; + REQUIRE(result.elapsed_ms < throughput_ceiling_ms); + } +} + +// Covers the path real slicing takes, under the default wall clock. The score there depends on the +// runner rather than on the code (see FIXED_SEARCH_BUDGET), so the only things worth asserting are +// that the grouping comes back valid and that the search terminates. +TEST_CASE("FilamentGroup returns a valid grouping under the default budget", "[filament_group][budget]") { + auto files = get_golden_files(); + REQUIRE(!files.empty()); + + auto file_path = GENERATE_REF(from_range(files)); + + DYNAMIC_SECTION("Golden: " << fs::path(file_path).stem().string()) { + auto tc = load_test_case(file_path); + + auto result = run_and_evaluate(tc.context); // the default budget, as real slicing runs it + + INFO("Case: " << tc.metadata.id); + INFO("Elapsed: " << result.elapsed_ms << " ms"); + + REQUIRE(result.constraints_ok); + // A hang guard. The clock is only checked between swaps, so a sweep can overshoot. + REQUIRE(result.elapsed_ms < 40000.0); + } +} + +// ============ Layer 2: Property Checks (all configs) ============ + +TEST_CASE("FilamentGroup property checks", "[filament_group][property]") { + auto& specs = get_property_specs(); + auto spec = GENERATE_REF(from_range(specs)); + + DYNAMIC_SECTION("Property: " << spec.id) { + auto tc = build_test_case(spec.id, spec.config, spec.seed, + spec.num_filaments, spec.num_layers, + spec.chaotic, spec.with_constraints, + spec.mode, spec.strategy, spec.group_with_time); + + auto result = run_and_evaluate(tc.context); + + INFO("Case: " << spec.id); + INFO("Config: " << spec.config); + INFO("Flush cost: " << result.flush_cost); + INFO("Elapsed: " << result.elapsed_ms << " ms"); + + // RelWithDebInfo runaway guard; the Release-calibrated 10 s limit is raised for the slower + // build (config_b/config_c cases evaluate the full per-layer nozzle-aware reorder for every + // candidate grouping; this is a guard against hangs, not a micro-perf gate). + REQUIRE(result.elapsed_ms < 40000.0); + REQUIRE(result.flush_cost >= 0); + + auto used_filaments = collect_sorted_used_filaments(tc.context.model_info.layer_filaments); + if (is_constraint_feasible(tc.context, used_filaments)) { + if (!result.constraints_ok) { + for (auto& v : result.violations) + WARN("Violation: " << v); + } + REQUIRE(result.constraints_ok); + } else { + if (!result.constraints_ok) { + WARN("Constraint violation (infeasible case, soft): " << spec.id); + } + } + } +} diff --git a/tests/filament_group/golden/config_a/basic_17.json b/tests/filament_group/golden/config_a/basic_17.json new file mode 100644 index 0000000000..2f0edd901b --- /dev/null +++ b/tests/filament_group/golden/config_a/basic_17.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":4.0},"context":{"group_info":{"filament_volume_map":[2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":2},"machine_info":{"machine_filament_info":[[{"color":"#850C02FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F10331FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#429A7CFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#8D67FEFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#2677E2FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3A3922FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#DB8EB9FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#53A5A6FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[2,2],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1"],"filament_info":[{"color":"#E8650CFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#0A9E99FF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,18.864795684814453],[512.7918701171875,0.0]],[[0.0,332.1666259765625],[58.37631607055664,0.0]]],"layer_filaments":[[0,1],[0,1],[0,1],[1],[0,1],[0,1],[0,1],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[1],[1],[0],[0],[0],[0],[0],[0],[0],[0],[1],[1],[1],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[1],[0],[0,1],[0],[0],[0],[0,1],[0,1],[0,1],[0],[0],[1],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0],[0],[0,1],[0,1],[1],[1],[1],[1],[1],[0],[0],[0,1],[1],[0],[0,1],[1],[0],[0],[0,1],[0],[0],[0],[0,1],[0,1],[1],[0,1],[0],[0],[0],[0,1],[1],[1],[1],[1],[0,1],[0,1],[1],[0,1],[0,1],[0],[0],[0],[0],[0],[0,1],[1]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_basic_17","seed":10017}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/basic_39.json b/tests/filament_group/golden/config_a/basic_39.json new file mode 100644 index 0000000000..c834cacd5b --- /dev/null +++ b/tests/filament_group/golden/config_a/basic_39.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":4.0},"context":{"group_info":{"filament_volume_map":[2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":2},"machine_info":{"machine_filament_info":[[{"color":"#3C6B30FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FE9954FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FBBAB3FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A1A591FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#55EE36FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A8F42BFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#930D0FFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#55C501FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[2,2],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1"],"filament_info":[{"color":"#C613F1FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#0C0CBAFF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,463.53955078125],[50.04071044921875,0.0]],[[0.0,54.75393295288086],[566.574951171875,0.0]]],"layer_filaments":[[0,1],[0],[0],[0,1],[0,1],[0,1],[0],[0],[0,1],[1],[1],[1],[1],[0,1],[0,1],[0],[0],[0],[0],[0],[1],[1],[0,1],[0,1],[1],[0,1],[0],[0],[0],[0],[0,1],[1],[0],[0],[0],[0,1],[0,1],[0,1],[1],[1],[1],[1],[1],[0,1],[0],[0,1],[0,1],[0,1],[1],[1],[1],[0,1],[0,1],[1],[0],[0,1],[1],[0],[0],[1],[0,1],[1],[1],[1],[0,1],[0,1],[0],[0],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0,1],[1],[0,1],[1],[0],[0],[1],[0,1],[0,1],[1],[0,1],[0,1],[1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[1],[1],[0,1],[0,1],[0,1],[0],[0],[0,1],[1],[1],[1],[0,1],[1],[0,1],[0,1],[1],[1],[1],[0],[0],[0],[1],[1],[0,1],[1],[1],[0,1],[0],[0],[1],[0,1],[1],[0,1],[1],[1],[0],[0,1],[0,1],[0,1],[1],[1],[0,1],[0,1],[0,1],[1],[0,1],[0],[0,1],[0,1],[0],[0],[1],[1],[0,1],[0,1],[0,1],[0,1],[1],[1],[1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0,1],[1],[0],[0],[1],[1],[0],[0],[0,1],[0],[0],[0],[0,1],[0],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[1],[0],[0,1],[0],[0,1],[0,1],[0,1],[0,1],[1],[0,1],[0,1],[0,1],[0,1],[1],[1],[1],[0,1],[1],[0,1],[0,1],[0,1],[0,1],[0],[0],[1],[0,1],[0,1],[1],[1],[1],[1],[0],[0],[0],[0],[0],[0],[0],[0],[0],[0,1],[1],[1],[1],[1],[0],[0],[0],[0,1],[0,1],[0],[0,1],[0,1],[0,1]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_basic_39","seed":10039}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/basic_9.json b/tests/filament_group/golden/config_a/basic_9.json new file mode 100644 index 0000000000..33661b6cbb --- /dev/null +++ b/tests/filament_group/golden/config_a/basic_9.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":4.0},"context":{"group_info":{"filament_volume_map":[2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":2},"machine_info":{"machine_filament_info":[[{"color":"#835F29FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#ACB239FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#5EF84BFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FE36A8FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#7B6ABDFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#4FFBDDFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#E06DDEFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#751104FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[2,2],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1"],"filament_info":[{"color":"#48BC3DFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#1DEED1FF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,523.2988891601563],[480.04058837890625,0.0]],[[0.0,18.886493682861328],[47.65232467651367,0.0]]],"layer_filaments":[[0,1],[0],[0,1],[1],[0],[0],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[1],[0,1],[0],[0],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[1],[1],[0],[0],[1],[1],[1],[0],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[0,1],[0,1],[0,1],[0],[1],[0],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[1],[0],[0],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[0],[0],[0],[0],[0],[0],[0,1],[0,1],[0],[0],[1],[0,1],[0],[0],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0],[0],[1],[1],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[1],[1],[0],[0],[0],[0],[0],[0,1],[0],[0,1],[0,1],[0],[0],[0],[0],[0],[1],[1],[0,1],[0,1],[0,1],[1],[1],[1],[1],[1],[1],[0,1],[0,1],[0,1],[1],[1],[0,1],[0,1],[1],[1],[1],[0,1],[0,1],[0,1],[0,1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0,1],[0,1],[0],[1],[1],[1],[1],[1],[1],[0,1],[0,1],[0,1],[1],[1],[0,1],[1],[0,1],[0,1],[0],[0,1],[0,1],[0,1],[0],[1],[0,1],[0,1],[1],[1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[1],[0,1],[1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0,1],[0],[0,1],[1],[0,1],[0,1],[1],[1],[0,1],[0,1],[0,1],[0,1],[0],[0,1],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0,1],[0,1],[0,1]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_basic_9","seed":10009}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/constraint_117.json b/tests/filament_group/golden/config_a/constraint_117.json new file mode 100644 index 0000000000..ae6e39e299 --- /dev/null +++ b/tests/filament_group/golden/config_a/constraint_117.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":9996,"full_score":4878.185600000001},"context":{"group_info":{"filament_volume_map":[2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":3},"machine_info":{"machine_filament_info":[[{"color":"#862B28FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#5DE136FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#B737ACFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#AB25E0FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#03D322FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FEF6E8FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#6ACCEDFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#5F679DFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[2,2],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2"],"filament_info":[{"color":"#D4E014FF","is_support":false,"type":"PA","usage_type":1},{"color":"#D01CEEFF","is_support":false,"type":"PA","usage_type":1},{"color":"#E433C7FF","is_support":false,"type":"TPU","usage_type":1}],"flush_matrix":[[[0.0,345.6607360839844,334.3067626953125],[167.5570526123047,0.0,469.119140625],[205.99964904785156,536.2994384765625,0.0]],[[0.0,16.684810638427734,322.7650146484375],[260.761962890625,0.0,230.73336791992188],[267.0419616699219,64.71019744873047,0.0]]],"layer_filaments":[[0,2],[0,1],[0],[1],[1],[1],[1],[1],[1],[1],[1,2],[0,1,2],[0],[2],[1],[1],[1],[1],[1,2],[1,2],[1],[0,1],[0,1],[1,2],[1,2],[1,2],[1,2],[1,2],[2],[0],[1,2],[1,2],[1],[0,2],[0,1,2],[0,1,2],[1],[1,2],[1,2],[1,2],[1,2],[0,1,2],[2],[1],[0,1],[0,1,2],[0,1,2],[0,1,2],[0,2],[0,2],[0,2],[0,2],[0,1,2],[0,1,2],[0,1,2],[2],[2],[2],[1],[0,1],[0,1],[1],[1,2],[1,2],[0,1],[0,1,2],[0,1],[1],[2],[1,2],[2],[2],[2],[2],[2],[1,2],[2],[2],[0,2],[0,1],[0,1],[0,1],[0],[0,1],[0,1],[1],[1],[1],[0],[0,2],[2],[2],[2],[2],[0,2],[1],[1,2],[1],[1],[1],[1],[1],[0,1],[0,1],[0,1],[1],[2],[2],[0],[0],[0],[0],[0,2],[1,2],[0,2],[0,2],[0,2],[0],[1],[1,2],[0,2],[2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[2],[1,2],[2],[0,2],[0,2],[0,2],[0],[0],[0],[0,2],[2],[2],[0,2],[2],[0,1],[0],[0],[0],[0],[0],[1,2],[0,1,2],[0,1,2],[0,1],[1],[1],[0],[0],[0],[0],[1],[1],[1],[0,2],[0,2],[0],[0],[1,2],[1,2]],"unprintable_filaments":[[2],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_constraint_117","seed":10117}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/constraint_87.json b/tests/filament_group/golden/config_a/constraint_87.json new file mode 100644 index 0000000000..d15d493eae --- /dev/null +++ b/tests/filament_group/golden/config_a/constraint_87.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":15640,"full_score":7498.304000000001},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":5},"machine_info":{"machine_filament_info":[[{"color":"#690A58FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#13D9ACFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#255B88FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#14AD07FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#E1E180FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A69E85FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#9F27DAFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#96A697FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[3,3],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4"],"filament_info":[{"color":"#84C1C1FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#1EB5C4FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#8D50E5FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#F22BC4FF","is_support":false,"type":"PA","usage_type":1},{"color":"#B7A86EFF","is_support":false,"type":"PA","usage_type":1}],"flush_matrix":[[[0.0,494.378173828125,256.524658203125,43.245582580566406,405.5243835449219],[16.6104679107666,0.0,150.26849365234375,400.1143493652344,30.314559936523438],[24.301469802856445,130.10775756835938,0.0,536.2122192382813,383.1336669921875],[437.3901062011719,272.96868896484375,82.35665893554688,0.0,17.11191177368164],[468.4289245605469,355.7682800292969,452.1650085449219,45.59552764892578,0.0]],[[0.0,491.8825378417969,205.77655029296875,349.1083984375,506.652099609375],[101.32499694824219,0.0,175.80380249023438,120.50504302978516,438.80804443359375],[152.76100158691406,355.5727233886719,0.0,581.8612060546875,585.173583984375],[546.7792358398438,22.963092803955078,407.84173583984375,0.0,105.83439636230469],[356.05926513671875,145.5247344970703,230.94595336914063,345.7974548339844,0.0]]],"layer_filaments":[[0,3,4],[0],[0],[0],[0],[0],[4],[4],[1],[1],[1],[3],[1],[1],[3],[0,1,4],[0,1],[0,1,3],[0,1],[1],[0],[0,3],[0,3],[2],[3,4],[0,2],[2,4],[4],[3],[3],[3],[1],[2],[4],[4],[4],[4],[0,3,4],[0,3],[0,3,4],[0,4],[0,3,4],[0,2,3],[0,2],[0,2],[0,2],[0,2],[0],[0],[0],[0,3,4],[3,4],[1,3,4],[3,4],[3,4],[3],[2],[4],[4],[4],[4],[4],[1],[1],[1],[1],[1],[1,4],[1],[1,3],[2,3],[2,3,4],[2,3,4],[3,4],[3,4],[0,1,3],[0,1],[0,1],[0,1,2],[0,1,2],[1,2],[1,2],[1,2],[0,2,3],[0,2,3],[0,2,3],[3],[3],[0,3,4],[0,2,3,4],[0,2,3,4],[0,2,3],[2],[2],[2],[0],[1],[1],[1],[4],[1,4],[0,4],[0,3,4],[0,3,4],[0,3,4],[0,3,4],[0,3,4],[0,3,4],[3],[3],[3],[0,3],[0,3],[0],[4],[3,4]],"unprintable_filaments":[[],[0,1]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_constraint_87","seed":10087}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/mode_bestfit_161.json b/tests/filament_group/golden/config_a/mode_bestfit_161.json new file mode 100644 index 0000000000..a8c50d5aa0 --- /dev/null +++ b/tests/filament_group/golden/config_a/mode_bestfit_161.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":22348,"full_score":10641.052800000001},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":1,"total_filament_num":7},"machine_info":{"machine_filament_info":[[{"color":"#CA0BBFFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#04BBE7FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#0C9192FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D03AE7FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#58ED4CFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F0F7E7FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#C01A00FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#41BF7EFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6"],"filament_info":[{"color":"#15D1F3FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#2E765BFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#F7F661FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#1F8FA4FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#548538FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#49CDDAFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#77400CFF","is_support":false,"type":"TPU","usage_type":1}],"flush_matrix":[[[0.0,522.1661987304688,100.72758483886719,133.01226806640625,491.89971923828125,10.22260570526123,398.2569580078125],[199.46890258789063,0.0,193.49847412109375,173.7811737060547,254.3165283203125,524.8251342773438,11.158357620239258],[25.300485610961914,185.6349334716797,0.0,14.763650894165039,527.9827270507813,503.7408142089844,196.4144287109375],[14.506301879882813,388.3427429199219,592.0447387695313,0.0,43.87137222290039,568.1431274414063,473.7308654785156],[320.220703125,309.9248352050781,39.37203598022461,47.134002685546875,0.0,97.27034759521484,458.011962890625],[572.5841674804688,336.4319152832031,47.922828674316406,278.3333740234375,182.32958984375,0.0,402.6477966308594],[447.379150390625,588.4238891601563,13.493745803833008,433.3789978027344,390.13360595703125,461.5366516113281,0.0]],[[0.0,298.9002380371094,586.3795776367188,271.62158203125,272.1965637207031,152.54571533203125,239.88775634765625],[99.5313949584961,0.0,165.59657287597656,83.9988021850586,219.39901733398438,418.60491943359375,575.6079711914063],[35.19260787963867,44.58149719238281,0.0,212.56053161621094,139.3209686279297,596.1610107421875,564.784423828125],[488.8506774902344,419.78521728515625,321.46514892578125,0.0,46.86149597167969,310.4212341308594,303.2931213378906],[531.5128173828125,116.25019073486328,207.16612243652344,50.03121566772461,0.0,385.4001770019531,108.3058090209961],[497.9175720214844,444.3203125,331.2178649902344,499.4423828125,546.33642578125,0.0,352.6327209472656],[423.0767822265625,189.04090881347656,132.35194396972656,453.5607604980469,29.324968338012695,336.557861328125,0.0]]],"layer_filaments":[[0,3,4,5],[0,4,5],[0,1,4,5],[1,4,5],[1,5],[4],[4],[5],[5],[5],[5],[6],[1],[1],[1,3],[1,3],[0,1,3],[0,3,4,5],[1,4,5],[1,4],[3,4],[0,1],[0,1],[0,1],[0,1],[1,5],[1,5],[1],[1],[1],[4],[4],[3,4],[0,1,6],[0,1,6],[1,3,6],[1,3,6],[6],[6],[3,6],[3,6],[3,6],[0,3,4,5],[0,3,4,5],[0,2,3,4,5],[0,2,3],[0,3],[0,3],[0,3],[0],[0,4],[4],[2,3,4,6],[2,4],[2,4],[5],[5],[5],[5],[2,5],[2,3,5],[2,3,5],[2,3,5],[2],[2,3,4],[2,3,4],[0,3,4],[0,3,4],[3,4,6],[0,3,4,6],[0,3,6],[0,3,6],[1,3,4,5],[0,3],[1,3,5,6],[5,6],[4,5,6],[3,4],[3],[1,3],[3],[2,3,5,6],[3,5,6],[5],[2],[6],[6],[4,6],[6],[6],[4,6],[1,4,6],[4],[0],[0],[0,5],[5],[6],[0,1],[0,1],[0,1,3],[0],[0],[0],[0,3],[0,3],[0,3],[0,3,5],[3,5],[3],[3],[3],[3],[3,5],[3,5],[0,3,5],[0]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_mode_bestfit_161","seed":10161}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/mode_match_150.json b/tests/filament_group/golden/config_a/mode_match_150.json new file mode 100644 index 0000000000..028a4b21a4 --- /dev/null +++ b/tests/filament_group/golden/config_a/mode_match_150.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":28788,"full_score":13492.236799999999},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":1,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#2C1334FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#672D31FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#40C111FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#0D6A9EFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#1C9D92FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#DFD03AFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#9F1CE2FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3F8A30FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[3,3],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#3F3A9BFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#2A420FFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#37A850FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#EB9B49FF","is_support":false,"type":"PA","usage_type":1}],"flush_matrix":[[[0.0,357.30389404296875,131.00808715820313,575.68603515625],[289.8275451660156,0.0,56.926780700683594,548.9874877929688],[323.252685546875,156.2064666748047,0.0,210.6259002685547],[469.44366455078125,165.70809936523438,174.34884643554688,0.0]],[[0.0,141.2342529296875,146.28591918945313,193.52146911621094],[548.3370971679688,0.0,404.035400390625,559.38232421875],[110.14042663574219,127.97674560546875,0.0,582.9161376953125],[221.37879943847656,321.6277160644531,375.734619140625,0.0]]],"layer_filaments":[[0,1,2],[0],[0],[1],[1],[1],[1],[1,3],[2],[2],[2],[0],[0,1,2],[1,2],[2],[2],[2],[2],[2],[3],[0,3],[0,3],[0,2],[2],[1,2],[1,2],[1],[0,1,2],[0,1],[0,1],[1,3],[0,1,3],[0,1,3],[0],[0,2],[0],[0],[0],[0],[0],[0,1,2],[0,1,3],[1,3],[1,3],[1,3],[1,3],[1,2,3],[0,1,2,3],[1,2,3],[0,1,2],[0,1,2],[0,1],[0,1],[0,1],[0,1,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,1],[1,2,3],[1,2],[0],[1,3],[0],[0],[2],[2,3],[1,2],[2],[1,2],[0,1],[1],[1,2],[1],[0,3],[0,3],[1,3],[1,3],[1,3],[1,3],[1],[1],[1],[1],[1],[1],[1],[1],[0,2],[0,2],[0,2,3],[1,2],[1,2],[1,2],[2],[2],[2],[2],[1,3],[1],[1],[1],[2,3],[2],[2],[2],[2],[2],[2],[2],[0,1],[0,2,3],[0,2,3],[0,2],[0,2],[0,2],[0],[1,3],[1,3],[3],[1,3],[0,3],[0,2,3],[0,2,3],[0,2,3],[3],[3],[3],[2],[1,2]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_mode_match_150","seed":10150}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/mode_time_164.json b/tests/filament_group/golden/config_a/mode_time_164.json new file mode 100644 index 0000000000..b2e8603532 --- /dev/null +++ b/tests/filament_group/golden/config_a/mode_time_164.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":64356,"full_score":30765.881599999997},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#7AFE12FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F3D57DFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F4843FFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D302D9FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#862964FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#ECD787FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#CD4477FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#CF1299FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[3,3],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#5437F4FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#86643DFF","is_support":false,"type":"ABS","usage_type":1},{"color":"#CB5794FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#BDDC19FF","is_support":true,"type":"PLA-S","usage_type":0}],"flush_matrix":[[[0.0,252.5859832763672,68.72093200683594,506.5740661621094],[550.3593139648438,0.0,403.29571533203125,335.01531982421875],[456.1624755859375,429.42291259765625,0.0,292.1879577636719],[118.39462280273438,469.7047424316406,255.89027404785156,0.0]],[[0.0,291.6563415527344,301.4433288574219,30.20578956604004],[390.76141357421875,0.0,549.512451171875,536.046875],[177.678955078125,17.97789192199707,0.0,569.9893798828125],[395.5279541015625,295.8275146484375,39.73347854614258,0.0]]],"layer_filaments":[[0,2],[0,2],[0,2,3],[0,1],[0],[0],[0],[0,1],[0],[1,3],[3],[2,3],[2,3],[3],[0,3],[0,3],[3],[1],[1],[1],[3],[3],[3],[3],[2,3],[2,3],[2,3],[0,2,3],[1,3],[3],[0],[0],[0,3],[0,2,3],[0,2],[2],[0,3],[0,3],[2,3],[0,2,3],[0,2,3],[0,2,3],[2],[2],[2],[2],[1,2],[1,2],[0,2],[0],[0],[0],[0],[0,2],[1,2,3],[0,3],[3],[0,3],[0],[0],[0],[0,1],[3],[2],[3],[3],[1],[1],[1],[1],[2],[2],[3],[1],[1],[1],[1],[1],[0,1,2],[0,1,2,3],[0,2,3],[0,3],[3],[0,3],[0,2,3],[1,2,3],[0,1,3],[0,2,3],[1],[1],[3],[3],[3],[0,1,2],[0,2],[0,1,2],[0,1,3],[0,1,3],[0,1],[0],[0],[0,1],[2],[2],[1],[1],[1],[1],[2],[2,3],[1,2,3],[1,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2],[1,2,3],[1,3],[1,3],[3],[1,2],[2,3],[2],[1],[1],[1],[1],[1,2],[1],[2],[2,3],[3],[3],[3],[3],[1,3],[1,3],[1],[1],[1],[1],[1],[1],[0,3],[0,1,2],[0,2],[1],[2,3],[2,3],[2],[2,3],[1,2,3],[1],[1],[0,1,3],[0,3],[3],[0,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,1,3],[0,1,2,3],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,3],[0,2],[2],[1,2],[1,2],[0,1,3],[1,3],[0,3],[1],[1],[1,2,3],[0,3],[1],[1,3],[1],[0,1],[0,1,2],[1,2,3],[1,3],[0,1,3],[0,1],[1,3],[1],[0],[0],[3],[3],[3],[3],[3],[2,3],[2],[2],[2],[0,2],[3],[0,3],[3],[0,2,3],[0,2],[0,1,2],[0,1,2],[0,1],[1],[1,2],[1,2],[2],[0,2],[0,1],[0,1],[1,2,3],[0,1],[0,1],[1],[1],[0,1,3],[0,1],[0,1,2],[0,1,2],[0,1,3],[1],[0,1],[0,1],[0,1],[1,2],[1,2,3],[2],[2],[0,2],[2],[2,3],[2,3],[2,3],[2,3],[2,3],[3],[1,3],[3],[3],[2],[2],[2],[2,3],[0,3],[3],[3],[0,3],[3],[3],[1,3],[0,1,3],[0,1,2],[1],[2,3],[1,2,3],[2,3],[2,3],[1],[1],[0],[0,2],[0,2],[0,3],[0,3],[0,2,3],[0,2],[0,2],[0,2],[2],[2],[2],[0,2],[1,2],[2],[0,1,3],[0,2],[0,2],[0,2],[1],[1,3],[1,3],[2,3],[2,3],[0,3],[0,2],[0],[0],[0,2],[0],[2],[2],[2],[1],[2],[1],[1],[2],[0],[0,3],[0],[0],[0],[0],[0],[0],[0,2,3],[0,2,3],[2,3],[2],[2],[1],[1],[1,3],[1],[2],[2],[2],[1,2],[1,2],[0,1,3],[0,1,3],[0,3],[0,3],[0,3],[0],[1],[1],[1],[3],[0],[0],[0],[0],[2],[2],[3],[3],[2,3],[0,2,3],[0,1,2,3],[0,1,2,3],[1,2,3],[3],[3],[1,3],[1,2,3],[0,1,3],[1],[1,2],[0,1,2],[0,1,3],[0,1],[0,1],[0,1],[0,1,3],[0,1,3],[0,1,3],[0,2,3],[0,2],[0,2,3],[2],[1],[1],[1,2],[2],[2],[2],[2],[2],[2,3],[2],[1,2],[2,3],[1,2,3],[0,1,2,3],[1],[1],[0,1],[1],[1],[1],[1],[1],[1],[1],[1],[0],[0,3],[0,1,3],[0,1,3],[0,3],[2],[1,3],[1,3],[1],[0],[0],[1],[1],[1,2],[1,2],[1,2],[1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,2,3],[1,3],[1],[3],[1,3],[1],[1],[1],[1],[1],[1],[0],[0],[0],[0,2],[0,1],[2],[2],[3],[0,3],[3],[1],[0],[2],[2],[0],[0,1],[0,1,3],[1],[1],[1],[2],[0,1],[3],[2,3],[2,3],[0,2,3],[0,1,2,3],[0,1],[0,1],[1],[0],[3],[0,3],[0,1,3],[0,1],[0],[0],[2],[0],[0],[0,2],[0,1],[1],[1],[1,2],[1,2],[0,2],[0,1,2],[0,1,2],[1],[1,2,3],[1,2,3],[1],[1],[1],[1],[1],[1],[2],[0],[3],[1,3],[1,3],[0,1,2],[0,2],[0,2],[2],[0,2],[0,2],[0,2,3],[0,2,3],[0,1,2,3],[0,1]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":true}},"metadata":{"config_type":"A","id":"A_mode_time_164","seed":10164}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/stress_55.json b/tests/filament_group/golden/config_a/stress_55.json new file mode 100644 index 0000000000..5e7b15c071 --- /dev/null +++ b/tests/filament_group/golden/config_a/stress_55.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":222312,"full_score":105174.72320000001},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":7},"machine_info":{"machine_filament_info":[[{"color":"#792831FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#0D150DFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#BAC560FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#35442EFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#C8783BFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#8E74A6FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#7E25D4FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#919CB3FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6"],"filament_info":[{"color":"#2A4A90FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#ECC7F1FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#95EE13FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#0F38D0FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#5B846AFF","is_support":false,"type":"PA","usage_type":1},{"color":"#F6E5FCFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#4A6533FF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,344.3797302246094,482.3527526855469,40.38117980957031,261.9287109375,170.18678283691406,116.24755096435547],[322.2475280761719,0.0,55.518951416015625,101.1526870727539,67.68023681640625,91.6056137084961,107.67850494384766],[328.8105773925781,570.3705444335938,0.0,561.5994873046875,452.2191162109375,576.5702514648438,240.8799591064453],[52.24696731567383,561.7581176757813,494.2055969238281,0.0,184.8818817138672,547.2175903320313,596.841552734375],[165.24452209472656,494.86285400390625,151.33480834960938,131.38433837890625,0.0,495.6569519042969,349.7553405761719],[48.451419830322266,453.2647705078125,280.7269287109375,70.33975982666016,382.3203430175781,0.0,556.371826171875],[541.539794921875,415.5547790527344,295.0630798339844,49.46228790283203,326.1522521972656,389.5788269042969,0.0]],[[0.0,237.69448852539063,43.353824615478516,344.63360595703125,421.31878662109375,526.4661254882813,131.27520751953125],[413.2799072265625,0.0,359.4131164550781,412.3663330078125,466.2528381347656,583.1257934570313,293.466796875],[417.49371337890625,137.5216064453125,0.0,125.9495620727539,413.9273376464844,533.7991333007813,256.642333984375],[64.1956787109375,103.259765625,424.9698791503906,0.0,60.511993408203125,458.4743957519531,297.8572692871094],[116.54857635498047,481.745361328125,324.94854736328125,308.89715576171875,0.0,369.8573303222656,177.64871215820313],[492.65338134765625,163.64085388183594,529.6907958984375,104.297607421875,250.75653076171875,0.0,217.0224151611328],[565.6396484375,332.9861145019531,111.19014739990234,170.36233520507813,111.83739471435547,295.5626525878906,0.0]]],"layer_filaments":[[3,4],[4,6],[4,6],[4,6],[4,6],[4,6],[6],[2,6],[6],[4],[4],[0],[6],[6],[6],[3,6],[3,6],[3,4,6],[3],[0],[0,3],[0,3,6],[3,6],[1,3,6],[1,3,6],[1,3,6],[1,3,6],[0,1,3],[3],[0,2,3,4],[0,2,3,4],[0,3],[0,3],[0,3],[0,3],[5],[5],[0,1,4,6],[1],[6],[1,3,5],[0,3],[0,3],[0,5],[5],[1,3,4],[1,3,4],[3,4],[3,4],[3,4],[3,4],[1,5],[2],[2],[2,4],[2,3,4],[2,3,4],[2,3],[2,3,4],[2,3,4],[0,2,3],[0,2,5],[0,2,5],[1,2,4,5],[2,4],[1,2,6],[3,4],[3,4],[3],[2],[0,1,3,6],[6],[4,6],[6],[1,6],[1,6],[1,6],[1,3,6],[1,3,6],[1,3,5],[3,5],[0,3,4,6],[0,3,6],[0],[1],[1,3],[1,3,5],[1,3,5],[0,1,5],[0,1],[0],[0,5],[5],[5],[5],[0],[4],[4],[4],[1,5],[1,5],[5],[5],[1,5],[1],[1],[1,2],[1,2],[1,2,3],[0,2,3,5],[2,3],[2,3,6],[2],[2],[2],[2],[2],[2],[2],[0,3,4,6],[0,1,4],[0,4],[0,1,4],[1,4,6],[3],[1,3],[1],[3],[4],[4,6],[4],[4],[1,4],[1,6],[1,6],[1,6],[1],[1],[1],[1],[1],[1,2,3,6],[2,3,4],[2,3,4],[0,5],[2,5],[2,5],[2,5],[2],[1,2],[1,2,3],[1,3],[1],[6],[1],[3],[3],[3,6],[4,6],[4,6],[6],[6],[5],[5],[2,5],[2,5],[1,2,5],[1,2],[1,2],[1,2],[2],[1],[1,6],[1,4],[1],[0],[2],[2],[1],[1,2],[1,2],[0,1,2],[0,2,5],[2],[6],[0,1,3],[0,1],[1],[3],[3],[0],[0],[0],[0],[0],[0],[4],[4],[4],[3,5,6],[3,6],[2,3,4,5],[1,2,3,4,5],[2,3],[0,4,6],[0,4,6],[0,4,6],[0,2,6],[0],[0],[5],[3],[3],[5],[5],[2,5],[2],[2],[2],[6],[2],[2],[2],[2],[6],[6],[6],[5,6],[0,5,6],[0,5],[0],[0,6],[0,6],[0,6],[0,6],[0,5,6],[0,4,5,6],[0,4,6],[0,4,6],[0,4,6],[0,6],[0],[0],[0],[0,6],[0,4,5,6],[0,4],[0],[0,2,3,5],[0,3,5],[3],[3],[3],[0,4,5],[2,6],[2,5,6],[5,6],[5,6],[6],[6],[4,5],[4,5],[4,5],[4,5],[5],[0,4],[0],[0,3],[0,3],[0,3],[3,5],[3,4],[3,4],[4,5],[4,5],[5],[1,3,5,6],[6],[2],[5],[5],[5],[2,5],[5],[5],[5,6],[5,6],[5,6],[6],[5,6],[5,6],[2,5,6],[5,6],[5],[2,5],[0,2,5],[5],[5],[5],[4],[4],[4],[4],[2,4],[4],[1,4],[4],[4],[4],[3,4],[0,4],[0,1],[0,3],[0,3],[0,3,4],[0,3],[3],[3],[3],[4],[1,4],[1,4],[1,4],[1,4],[0,1,4],[0,1],[0,1],[0,1],[0,1],[0],[0],[0],[0,3],[0,3],[0,3],[3],[3],[3],[1],[2],[2],[2,6],[2,3,6],[2,6],[2,6],[2,6],[0],[0],[0],[0],[2],[2],[5],[0,5],[0,5],[0,1,5],[0,6],[0,6],[0,6],[0,5,6],[0,5,6],[5],[0,3,6],[0,1,2,3],[0,1,2],[0,2,4,5],[0,2],[0,2],[0,2],[2,6],[6],[6],[6],[6],[6],[3],[3],[0,3],[0,3],[3],[3,6],[3],[3],[3],[3],[5],[2,5],[1],[0],[0],[0,3],[0,3],[0],[0,1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0,2],[2,4],[2,4],[2,3,4],[3],[2,3],[2,3],[3,5],[5],[5],[2,5],[2,6],[0,2],[0],[0],[0],[5],[5],[5],[5],[5],[5],[5],[1],[1],[5],[5],[4],[1,4],[1,4],[3,4],[3,4,5],[3,4,5],[3,5],[1,5],[1],[1],[1,3],[1],[1],[6],[6],[6],[5,6],[5],[5],[0,2],[2],[2],[2],[0,3,4,6],[3,4],[0,5],[0],[3],[3],[3],[0],[0,4],[0,4,5],[4,5],[4],[4],[0],[0],[0,1],[0],[3],[3],[3,6],[3,6],[3,6],[1,3,4,5],[3,4,5],[3,4],[4,6],[4,6],[0,4,6],[0,4,6],[4],[6],[6],[6],[0,2,3,4],[2,4,6],[2],[0],[0,2],[0,2,4],[0,2,4],[0,6],[0,6],[0,6],[0,6],[0,6],[0,6],[0,5,6],[5],[5],[5],[5],[3],[2],[0,5,6],[6],[6],[3,6],[1,3,6],[1,2,3],[1,3,5],[0,1],[1,2],[0,3,6],[0,3,6],[6],[6],[5,6],[5,6],[5,6],[6],[6],[4],[4],[1,3,4],[1,4],[1,4],[2,4],[2,4],[1,2,4,5],[0,1],[0,1],[5],[0],[0,6],[1,2,3],[1,2,3],[1,3,4,6],[1,4],[2,6],[6],[3,6],[3,4,6],[3,4],[0,3,4],[0,3,4],[0,2,3],[4],[1],[6],[2],[2],[2],[4,5],[1],[1],[1],[6],[6],[6],[6],[1],[1,3],[1,3],[1,3],[3,4],[3,4],[3,4],[3,4],[1,3,5],[5,6],[5,6],[1,5,6],[1,5,6],[1,5,6],[1,6],[6],[4,6],[1,2,6],[1,2],[1,2],[2],[2],[3,5,6],[5],[3,5],[5],[5],[0,2,5,6],[2,5,6],[1,2,5],[1,2,5],[1,4],[1,4],[1,4],[1,4,6],[0,1,5],[1,5],[1,2,3,6],[1,3,6],[1,4],[1],[1],[6],[6],[0,4,5,6],[0,2,4,6],[0,2,6],[0,2],[0,2],[3],[2,5],[0,2],[0,2,6],[2,6],[6],[6],[5],[1,5],[0,1,5],[0,1,5],[0,1,5],[0,1,5],[0,6],[0,6],[1],[1],[1,2],[1,2,3],[2,5],[2,5],[2,5],[5],[4],[6],[6],[0,6],[0,6],[5],[5],[2,5],[0,2],[2,3],[4],[4],[5],[5],[5],[0,5],[1],[1,3],[3],[3],[3,5],[1,2,4,5],[1,4,5],[1,4],[1],[1],[0],[1,5],[1],[1],[6],[1],[1],[1,2],[0,1],[0,1],[0,1,2],[0,1,2],[1],[1,6],[1,2,3,5],[1,2,3],[1,3,6],[6],[6],[0,2,3,5],[2,3],[0,3,4,5],[3,4,5,6],[1,3,4,6],[1,6],[1,6],[1,6],[4,5],[4],[1],[0,3,5,6],[0,3],[0,1],[0],[0],[0,5],[5],[5],[5],[2,5],[2,5],[1,2,5],[1,5],[1,6],[1,5],[5],[4],[4],[4,6],[4],[0,4],[1],[1],[5],[5,6],[5,6],[0,6],[0,3,6],[0],[3],[3,5],[3,5],[3,5],[0],[0],[0],[0],[1],[1],[1],[2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,1],[1],[1],[1],[1,5],[5],[5],[2],[2,4],[1,2,4],[1,2,4],[0],[0],[0],[1],[6],[0,1,2,6],[0,1,2,6],[0,1,6],[0,1,4,5],[0,1,5],[0,1,5],[0,5],[3,5],[5],[3,5],[5],[5],[2],[2],[2],[0,2],[0],[0],[0],[1],[1],[1],[1,5],[1,5],[0,1],[0],[0,5],[0,2,4],[0],[0],[0],[0],[6],[0],[0],[6],[6],[2,6],[2,6],[5],[5],[5],[5],[5],[5],[5],[0],[0],[0],[0],[0,4],[0,4],[0],[0],[0],[0],[0,1],[0,1],[2,6],[0,6],[2],[3],[3],[4,5,6],[4,5,6],[4,5,6],[4,5,6],[1,4,5,6],[5,6],[1,6],[1,2,6],[1,6],[1],[1],[6],[6],[5],[3],[3],[5],[4,5],[5],[5],[2,5],[5],[5],[0],[0],[3],[3],[3],[5],[5],[5],[2,5],[2,3,5],[2,3,5],[2,5],[5],[0,1,4,6],[1,4,6],[6],[4],[4],[2,4],[2,4],[2,4],[2,4],[2,4],[1,2,4],[1,4],[0,3,4,6],[0,4],[0],[0],[5],[5],[5],[2],[2],[2],[0,1,3,4],[0,1,3,4,6],[1,3,4,6],[3,4,6],[3,6],[6],[5,6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[6],[2],[1,2],[1,2,6],[1,2,6],[2],[2],[0,2],[0,2,5],[0,5],[5],[0],[0],[0],[0],[0],[0],[0],[0,6],[0,6],[0,1,2,4],[0,1,2],[4],[0,2,3],[0,2,3],[0,2,3],[0,2,3],[0,2,3],[0,2,3],[0,2],[4,6],[4],[1],[1],[1],[1],[1,5],[1,5],[1],[1],[5],[1,2],[1,3],[1,3],[3],[3,4],[3,4],[3,4],[3,6],[3,6],[3,6],[3,6],[2,6],[0,2,3,4],[3,4],[3,4],[1,3,4],[1,3,4],[3,4],[3,4],[3,4],[4],[4],[4],[4],[6],[6],[0,6],[0,1,6],[0,1,6],[0,1,6],[0,1,6],[1,6],[1,6],[6],[2,6],[2,6],[5,6],[5,6],[4,5,6],[2,4,5,6],[2,4,5],[2],[2],[2],[2,3],[2],[3],[0],[2,4,5],[2,4,5],[4,5],[4],[1],[1],[1],[1],[1,2],[2],[2],[0],[0],[0],[0],[0],[1,2,3,4],[0,1,2,3],[0,1],[1,4],[1,4],[4],[1],[1],[3],[3],[0],[0],[0,2],[0,2,6],[0,2,4,6],[0,1,4,6],[0,4],[0,3,4],[1,2,3,5],[1,2,5],[2,4,5],[2,4,5],[2,4],[2,4],[2,4],[2,3],[2],[0],[0,1],[1],[1,2],[2],[1],[1,2],[0,1,2],[0,2],[2],[2,4],[1,2,4],[2],[0,2],[0,2],[0],[6],[5],[5],[5,6],[6],[0],[0],[0],[0],[0],[3],[6],[1,6],[1,3,6],[1,2,3,6],[1,2,3],[2,3,5],[2,3,5],[3,5],[3,5],[3,5],[3],[3],[4],[3],[3],[3],[3],[0,1,3],[0,1,3],[0,3],[0,3],[1,2,3,6],[2,3,6],[3],[3],[3],[6],[5],[1,2],[1,2,6],[1,2,6],[2],[0,2],[0],[0],[5],[0],[1],[5],[5],[3],[3,6],[0],[0],[0,2,5,6],[0,1,2,5,6],[2,5],[2,5],[2,5],[2,5],[5],[0],[4],[4],[4,6],[4,6],[4,6],[4,6],[0,5,6],[0,5,6],[5],[6],[5,6],[5],[5],[5],[3],[1,3],[0,1,3,6],[0,3,4],[0,3,4],[0,4],[0],[0,6],[0,5,6],[0,4,5,6],[0,5,6],[0,5,6],[0,5,6],[0,5,6],[0,5,6],[0],[0],[0],[0,1],[3],[3],[4],[1],[0],[0],[1],[1],[1,5],[1],[1],[1],[0],[0],[6],[6],[2,6],[2,6],[2,6],[2],[2],[3],[3],[4],[0,4]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_stress_55","seed":10055}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_a/stress_68.json b/tests/filament_group/golden/config_a/stress_68.json new file mode 100644 index 0000000000..35ce570c3c --- /dev/null +++ b/tests/filament_group/golden/config_a/stress_68.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":192895,"full_score":91621.172},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":7},"machine_info":{"machine_filament_info":[[{"color":"#C10C3FFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D6EC60FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#6997F2FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#1F1DE4FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#84BD1BFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#5B92D0FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#BA63BAFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#5198BFFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,true]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6"],"filament_info":[{"color":"#DFAC59FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#F65BE6FF","is_support":false,"type":"PA","usage_type":1},{"color":"#298FDDFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#4DF3A6FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#DE840AFF","is_support":false,"type":"PLA","usage_type":1},{"color":"#CEEF3AFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#309940FF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,86.73371887207031,368.560791015625,577.5296630859375,329.58966064453125,436.9564208984375,202.6211395263672],[265.9327392578125,0.0,184.9813995361328,81.10008239746094,502.81817626953125,50.81895065307617,35.91518020629883],[305.206298828125,552.2982788085938,0.0,80.26722717285156,434.3873596191406,125.67747497558594,323.0937805175781],[188.6085662841797,186.19570922851563,33.98442077636719,0.0,42.24768829345703,588.0347900390625,81.06825256347656],[344.5270080566406,88.18656921386719,467.6105041503906,569.0555419921875,0.0,39.199684143066406,57.63194274902344],[183.13156127929688,420.84442138671875,597.6102294921875,451.87506103515625,50.71337890625,0.0,331.3912048339844],[53.49460983276367,101.29570770263672,552.233642578125,221.33038330078125,581.5220336914063,331.9902038574219,0.0]],[[0.0,173.55361938476563,123.41706085205078,218.31134033203125,545.6212768554688,235.2119598388672,237.24371337890625],[200.88046264648438,0.0,567.8236083984375,523.511962890625,99.36125183105469,261.3605651855469,251.3693084716797],[447.2699890136719,481.9408264160156,0.0,459.9869079589844,471.4654235839844,457.8411865234375,154.9784698486328],[309.6800537109375,573.5164794921875,350.1246643066406,0.0,27.96612548828125,519.700927734375,66.02371215820313],[18.68804931640625,277.83917236328125,334.7834167480469,548.5271606445313,0.0,292.3869323730469,134.24508666992188],[285.8016357421875,173.82510375976563,540.353271484375,458.15631103515625,507.45208740234375,0.0,345.29998779296875],[419.1427001953125,208.54754638671875,345.3580322265625,484.8681335449219,279.7955627441406,57.570682525634766,0.0]]],"layer_filaments":[[1,5],[1,5],[1,5],[1,2,5],[1,5],[1],[1],[5],[5],[4,5],[4],[4],[2,4],[2],[2],[2],[1,2,4],[1,2,4],[1],[1],[6],[6],[4,6],[6],[0,3,5],[3],[3],[3],[4],[3],[4],[4],[2,4],[2],[1],[1],[1],[3,5],[3,5,6],[3],[3],[6],[6],[0],[0,4],[0,4],[0],[0],[0],[0],[0],[0],[3],[3],[3],[1,3],[1,3],[1,2,3,6],[1,2,6],[1,2,4,6],[1,4,6],[0,4,6],[0,1,5],[1,5],[1,5,6],[1,5],[1,5],[3,4,5,6],[3,4,5],[4,5],[4,5],[3,4],[6],[6],[0,2,5,6],[0,2],[1],[4],[1],[1],[6],[6],[3,6],[3],[5],[0,5],[1,2,3],[0,1,3],[0,1,6],[1],[5],[1,5,6],[1,6],[1,6],[1,3,6],[1,6],[0,2,3,5],[0,1,2,5],[0,1,2,5],[0,1,2,5],[2],[0],[6],[2],[2],[1,2],[1,2,3],[1,2,3],[3],[3,6],[0,3,6],[0,3],[0,1,3],[0,1,3],[0,3],[0,3],[0,3],[0,5],[0,2,5],[2,5],[1,3],[1,3],[2,3,4,5],[1,2,3,5],[2,3,4,5],[4,5],[0,4,5],[5],[0,2,4],[2,4],[2,4],[2,4],[0,2,3,6],[0,1,2,3,6],[1,2,3],[3],[5],[3,5],[3,5],[3,5],[5],[0,4],[0],[0],[3,5,6],[3,5],[0,3,5],[0,3,5,6],[0,3],[0,3,4],[0,4],[0,4],[0,4],[0,3,4],[3,4],[3,4],[1,4,6],[1,3],[1],[1],[1],[1,2],[1,2],[0,1,2],[3,5],[2],[2,4],[2,4],[2,4,6],[2,4,6],[0,2,4,6],[0,2,4,6],[0,2,4,6],[0,1,2,6],[0,4,5],[0,5,6],[5,6],[1,2,5],[1],[1],[1],[1,2,5],[1,2],[0,1,3,5],[1,3,5],[0,2,6],[0,1],[0],[0,2],[2,4],[2,4,5],[4],[1],[2,6],[2,6],[2],[5],[2,5],[2,5],[5,6],[5,6],[5],[1],[1],[4],[2,3],[3],[0,2,5,6],[0,1,3],[2,4],[2,4],[3,4],[3,4],[1,2,3],[1,2,3,4],[1,3],[3,4],[3,4,6],[3,4,6],[3,6],[3,6],[3,6],[0,3,6],[3],[3],[3,5],[3,5],[3,5],[3],[6],[1,6],[0,6],[0],[0,3],[5],[5],[5],[1],[1],[1],[0,1],[1],[0],[0],[0],[3],[2,6],[4],[3,4],[3,4],[3,5],[3,5],[3,5],[3,5],[3,5],[4],[4],[4],[4],[0,4],[4],[4],[4],[4],[6],[6],[5,6],[6],[6],[6],[6],[0],[0],[4],[4],[4],[1],[0,1],[0,6],[0],[0],[0],[0],[0],[0],[2,5,6],[4,5,6],[0,4,6],[4,6],[6],[6],[6],[6],[4,6],[0],[3],[0,2,5],[2,5],[2,4,5],[1,5],[5],[0,1],[0,1],[0,1],[0,2,5,6],[1],[1],[1],[1],[0,5,6],[0,5,6],[0,3],[0,3,5],[3,5],[3,5],[3,5],[3],[3],[3],[1,3],[1,3],[0,1,2],[0],[6],[5,6],[5,6],[5,6],[5,6],[5,6],[5],[4],[4],[3],[0,3],[3,4],[3,4],[3,4],[0,3],[0,3],[3],[3],[3],[3],[3,4],[3,4],[3],[2,4],[4],[4],[6],[4,6],[2,4],[4],[4],[3,4],[3],[3],[1,3],[1,3],[1,3],[1],[6],[6],[1,6],[1,6],[1],[4],[0,4],[0,4],[0,4],[0,4],[0,6],[0],[0,2],[2,4],[2],[2,3],[2,3],[3],[3],[2],[0],[0,3],[0,3],[0,3],[0],[1,5],[1,5],[1,4,5],[4,5],[4,5],[4,5],[1,5],[1,5],[1,5],[1,5],[1,2,5],[1,2,5],[1,5],[1,5],[2,5],[2,5],[2,5],[2,5],[5],[5,6],[6],[6],[6],[6],[3],[3],[2],[5],[5],[5],[5,6],[6],[6],[6],[4,6],[3],[0,1,3,6],[6],[6],[6],[0],[0],[0,6],[0,6],[0,6],[5,6],[5,6],[6],[3],[0],[0,3],[2,3],[1,3],[6],[6],[1],[1,6],[6],[3],[0,5],[0],[0,3,4],[0,1,3,4],[0,1,4,5],[0,1,4,5],[0,4,5],[0,4,5],[4,5],[5],[4,5],[4],[3,4],[0,1,4,6],[0,1,6],[0,1],[0,1,6],[0,6],[2],[2],[6],[5],[5],[5],[4,5],[0,4,5],[0,4,5],[4],[4],[0],[0],[0,3],[0,1],[0],[3],[3],[3,5],[2,3],[2,3,6],[2,3,6],[2,3],[2],[2],[2],[1,2],[2],[6],[6],[3],[3],[3],[3],[3,6],[3,6],[6],[6],[6],[5,6],[6],[4],[4],[4],[4,5,6],[5,6],[4,5],[4,5],[2,3,5,6],[2,5,6],[2,6],[2,6],[2,6],[0,2,6],[0,6],[0],[0],[0],[6],[6],[1],[0,1,5,6],[0,1,5,6],[5,6],[2,4],[1,3,4,5],[1,3,4,5],[1,3,4],[1,2,3],[1,2,3],[1,4,5,6],[1,4,5,6],[1,3,4,5,6],[1,4,6],[1,3,6],[1,3],[0,3,4],[2],[2,3],[0,2,3],[0,3],[0],[0,3],[0],[0,2,4],[0,2,4],[0,2],[2,5],[2,5],[2,5],[2,5],[2,5],[1],[3,5],[1,3,5],[3,5],[3],[3],[6],[1],[1],[1],[1],[1],[3],[3],[3],[3],[3,5],[2,3,5],[0,2,3,5],[0,3,5],[1,4,6],[1,4,6],[0,1,6],[0,2],[3],[3],[2],[2],[1,2],[3],[3],[3],[3],[0,3],[2],[2],[2],[2],[2],[2],[0,4,5],[0,4,5],[4],[4],[2,4],[2,4,5],[2,4,5],[0,2,5,6],[0,4,5],[5],[5],[4],[0],[0],[0,5],[4,5],[0,1,6],[0,5,6],[0,5,6],[0,2,5],[0,2,4],[0,2,4],[3,5],[3,4,5],[3,4,5],[0,3,4,5],[0,3,5],[0,3,5],[5],[5],[5],[5],[3],[3,5],[3,5],[5],[3],[3],[3,5],[3,5],[5],[5,6],[5,6],[5],[5],[1,3,5,6],[1,3,5,6],[3,5],[3,5],[0,3,5],[3],[3],[1,3,4,6],[1,3,4,6],[4,5],[4,5],[4,5,6],[2,4,5,6],[2,4],[5],[2,5],[2,5],[6],[3],[3],[1,3],[2,3],[2,3],[3],[3],[3],[3],[6],[0,2,3,6],[2,3,6],[0,1,6],[1,6],[1],[1],[0,4,5],[0,4],[4],[1,4,5,6],[1,5],[1,5],[1],[1],[4],[3,5],[3,5],[3,5],[3],[2],[2],[2],[2],[0,2],[0,2],[2],[2],[2],[2],[2],[2,6],[2,6],[6],[4],[4],[2,4],[2,4],[2,4],[1,4],[4],[4],[3,4],[4],[4],[4],[1,4],[1,3],[3,6],[3,6],[3,6],[1,4],[0,4],[0,2,4],[2,4],[1,4],[1,4],[1,3,4],[3,5],[0,3,5],[3,5],[3,4,5],[4,5],[5],[0,3],[0,3],[0],[0,4],[0,2,4],[0,4],[4],[2],[2],[3],[3],[3],[1,3,4,5],[1,5],[3],[3,6],[3,4,6],[3,4,6],[3,4,6],[0,4,6],[0,4,6],[0,1,6],[0,3],[0,3],[3],[3],[3,4],[1,4],[4],[1,2],[1],[1,2],[1],[1],[1,2],[2],[2],[2,6],[2,4,6],[4],[4],[4,6],[0,4],[0,2,4],[5,6],[1,6],[0,1,6],[0,5,6],[0,5,6],[0],[0],[0,2],[2],[2],[1],[1],[4],[4],[4,5],[3,5],[3,5],[2,3,5],[2,5],[2,6],[6],[6],[6],[3],[3],[3],[3,5,6],[3],[1,3],[1,3],[1,3],[1,3],[3],[1],[1,3,4,6],[1,2],[1,2],[1],[0],[0],[0,4],[4],[3],[3],[0],[5],[0,4],[0,4],[2],[0,1,4,6],[0,1,5,6],[0,6],[4,6],[4,5],[4],[6],[5],[1],[0,2,4,6],[0,2,4],[0,4],[4],[0],[5],[5],[5],[5],[2],[2],[4],[1,2,3,4],[1,2,3],[1,2,3],[1,2,3],[1],[3,4],[5],[5],[5],[5],[4,5],[4,5],[4,5],[4],[4],[6],[6],[1],[3],[0,1,5,6],[5],[5],[4,5],[0,2,3],[1,3,5],[3,5],[3],[3],[2,5],[2,5],[2,5],[2,5],[0,1,2],[1],[1],[1,5],[1,5],[1,4,5],[4,5],[4,5],[5],[5],[0,5],[5],[5],[5],[5],[2,5],[2,3,5],[2,3,4,5],[2,4,5],[2,3,4],[2,3,4,6],[2,4,6],[4,6],[4],[4],[1,4],[4],[3,4,5,6],[4,5],[4,5],[0,4,5],[0,4],[3,4],[3,4],[4],[3,4],[2,3],[2,5],[2,5],[2,5],[5],[3],[3],[3],[3,6],[0,1,5],[0,1],[1,6],[1,3,6],[1,3,6],[1,3,6],[1,3],[0,3],[3,4],[2,4,5],[2,5],[2],[2,5],[2,5],[6],[2],[3],[3],[3],[1,3],[1,3],[2],[2],[2],[2],[0],[0],[3],[1,3,4,6],[2,4,6],[4],[0,4],[0,4],[4],[4],[4],[0,4],[0],[0,5],[2,5],[2],[0,2,3,5],[1,3,4,5],[1,3,4,5],[1,3],[1],[4],[1],[1],[2],[1],[4],[4],[0,4],[0,2,4],[2],[0,2],[0,1,2],[0,1],[0,3],[0,2,3],[0,3],[0],[0],[0,6],[2,3,5],[2,3,5],[1,2],[1,2],[2,3],[2,3],[0,1,2,4],[0,1,4],[0,1,4],[1,4],[4,6],[4,6],[4,6],[4],[1,4],[4],[0,4],[0,4],[0],[0,6],[5],[0],[5],[3,5],[5],[5,6],[1,2,3,4],[2,4],[2,4],[0],[0],[0],[0],[0,2],[1,6],[1,6],[1,6],[2,3,4,6],[3,4,6],[3,4,5,6],[0,2,5],[0,2],[0,2,5],[0,2,5],[2,5],[2,5,6],[2,5],[2,5],[0],[0,6],[1,2,4],[6],[6],[6],[5,6],[5,6],[2,3,4],[3,4],[3,4],[4],[5]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"A","id":"A_stress_68","seed":10068}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/basic_24.json b/tests/filament_group/golden/config_b/basic_24.json new file mode 100644 index 0000000000..d2783abf8b --- /dev/null +++ b/tests/filament_group/golden/config_b/basic_24.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":184.0},"context":{"group_info":{"filament_volume_map":[2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":3},"machine_info":{"machine_filament_info":[[{"color":"#58191BFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#65BA4BFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#8198CBFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#ACC0ABFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#22ED52FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#C09D59FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#2DA502FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F7A2FAFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2"],"filament_info":[{"color":"#D0206DFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#8F4679FF","is_support":false,"type":"PA","usage_type":1},{"color":"#29B62DFF","is_support":false,"type":"ABS","usage_type":1}],"flush_matrix":[[[0.0,22.997100830078125,311.9136962890625],[467.8121032714844,0.0,309.3307189941406],[409.413330078125,543.3587646484375,0.0]],[[0.0,424.8780517578125,513.323974609375],[432.9106750488281,0.0,186.18800354003906],[419.3179016113281,409.17095947265625,0.0]]],"layer_filaments":[[0,1],[0,2],[0],[0,1],[0,1,2],[1],[1],[1],[1],[2],[0],[0,2],[0],[0],[0,2],[0,1],[0],[2],[2],[2],[2],[2],[2],[1,2],[1,2],[1],[2],[2],[0,1],[0,2],[1,2],[1],[1],[0,1],[0,1,2],[2],[2],[2],[1],[1],[2],[2],[0],[1],[0],[0,1],[0,1],[0,1],[1],[1],[1],[0,1],[1,2],[0,1,2],[1,2],[1,2],[1,2],[1,2],[0,2],[0,1],[0,1],[1,2],[1],[1],[2],[2],[2],[2],[1,2],[1],[1],[1],[1],[0],[0],[2],[0,2],[0,1,2],[2],[2],[2],[0,2],[0,1,2],[0,2],[2],[1],[1],[1],[2],[2],[2],[1,2],[1,2],[2],[2],[2],[0,2],[0,2],[2],[0,2],[0],[0],[0],[0,1],[0,1],[0,1],[0,1],[0,2],[0,2],[0],[0,2],[2],[1,2],[2],[1,2],[0,2],[0],[0,2],[1],[1],[1],[2],[0,1]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_basic_24","seed":20024}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/basic_27.json b/tests/filament_group/golden/config_b/basic_27.json new file mode 100644 index 0000000000..85470a1678 --- /dev/null +++ b/tests/filament_group/golden/config_b/basic_27.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":439.0},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":5},"machine_info":{"machine_filament_info":[[{"color":"#CE9589FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#C1CA1FFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#63C10EFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#1FB0EDFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#D1526EFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FFFDCCFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FE458BFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FE7A24FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,8],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4"],"filament_info":[{"color":"#E892ACFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#9BF6B9FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#B37CAAFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#E57574FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#4821E8FF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,375.2281494140625,463.1433410644531,91.72261810302734,543.7777709960938],[40.411563873291016,0.0,46.204158782958984,133.43045043945313,140.9217987060547],[385.8175354003906,90.685302734375,0.0,140.52508544921875,75.50867462158203],[316.38568115234375,89.43927764892578,424.980224609375,0.0,27.291486740112305],[50.60981369018555,200.03822326660156,547.7901000976563,466.6471862792969,0.0]],[[0.0,240.17831420898438,577.3026123046875,222.15658569335938,590.8341064453125],[424.3199157714844,0.0,434.2823486328125,209.71908569335938,437.5057373046875],[349.07037353515625,464.85870361328125,0.0,32.95913314819336,527.3640747070313],[256.4498596191406,298.9818115234375,598.7887573242188,0.0,31.422487258911133],[529.8190307617188,558.2802734375,43.493682861328125,432.5175476074219,0.0]]],"layer_filaments":[[1,2,4],[1,2,4],[1,4],[1,4],[4],[4],[2],[2,4],[2,4],[2,4],[2,3],[1,2,3],[2,3],[2,3],[3],[3],[0,4],[0,4],[0,4],[0],[0],[0,3],[0,2,3],[2],[2],[1,2],[1,2],[0,2],[0,2],[0,2],[0],[0,2,4],[0,2,4],[0,1,3],[0,1,3,4],[0,1,2,3],[0,1,2,3],[2,3],[1,2,3],[1,2],[2],[3],[0,2,4],[0,4],[0,4],[1,4],[0,1,4],[0,1,4],[0,4],[4],[4],[4],[3],[3],[3],[0,1,4],[2],[0,2],[0,2],[0,2,4],[0,1,2],[0,1],[0,1],[1],[1],[1],[1],[3],[3],[3],[4],[3,4],[3,4],[4],[4],[4],[4],[4],[2],[2],[2],[2,4],[2,3,4],[3],[0,2,4],[0],[0],[1],[1],[2],[2],[2],[1],[1],[0,1],[0,1,2],[0,2],[1,3],[1,3],[1,3],[0,1],[0,1,3],[0,1,3,4],[0,1,3],[0,3],[3],[2,3],[2],[2],[2],[1],[3],[2,3],[1,3],[3],[3],[2],[2,4],[0,3,4],[3,4],[3],[0,3,4],[0,4],[3,4],[2,3],[1,2],[1,2],[1,2],[1,2],[1,2],[2],[2],[1,2],[1,2]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2,3,4]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":1},{"diameter":"0.4","extruder_id":1,"group_id":3,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":4,"volume_type":3}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_basic_27","seed":20027}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/basic_47.json b/tests/filament_group/golden/config_b/basic_47.json new file mode 100644 index 0000000000..1df8ef8d0e --- /dev/null +++ b/tests/filament_group/golden/config_b/basic_47.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":279.0},"context":{"group_info":{"filament_volume_map":[2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":3},"machine_info":{"machine_filament_info":[[{"color":"#21E724FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#B2066AFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#727804FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#CBC06DFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#0EF122FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#7299D2FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#EA9A57FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3A2E9EFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2"],"filament_info":[{"color":"#88704DFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#D3D1CCFF","is_support":false,"type":"PLA","usage_type":1},{"color":"#F8C24BFF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,123.0057144165039,149.25132751464844],[140.3647918701172,0.0,395.5540771484375],[354.4726257324219,160.0218048095703,0.0]],[[0.0,249.49559020996094,285.7671203613281],[366.1941223144531,0.0,411.5499267578125],[69.0042724609375,557.7216186523438,0.0]]],"layer_filaments":[[0,2],[0,1],[0,1],[0,2],[0,2],[0,1,2],[0,1,2],[0],[0],[0],[0],[1],[0,1],[0],[0],[0,1],[1],[0,1],[0,1],[0,1],[0,1],[1,2],[2],[1],[1],[1],[0],[0],[0],[0],[0],[1],[1],[1],[2],[1,2],[1,2],[1],[1,2],[2],[1,2],[1],[1,2],[1,2],[1,2],[2],[2],[1,2],[1],[0],[0],[0],[0,1],[0,1],[1],[0,1],[1],[1,2],[0,1],[0,1],[0,1],[0,1],[0,1,2],[1,2],[1,2],[1,2],[1,2],[2],[2],[2],[1],[1],[1],[1],[1],[1],[0,1],[0],[0],[0],[0],[0],[0],[0],[0],[0,1],[1],[1,2],[1],[0,1],[0],[0],[0],[0],[0],[0],[0,1],[0,2],[2],[0],[1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[0,2],[1],[1],[1],[0,1],[0,1,2],[0,2],[0],[1],[0],[0],[0],[0],[0],[0,2],[0],[0],[0],[0],[0],[0],[0,1],[0],[0],[0,1],[1],[1],[1],[2],[0,2],[2],[0,2],[0],[2],[1,2],[0,1],[0,1],[0,1,2],[0,1],[0,1],[2],[2],[0,2],[1,2],[1],[1,2],[1,2],[1,2],[1,2],[1],[1],[1],[1],[1],[1],[1],[0,1],[0,1],[0,1],[0],[0],[0],[0],[0],[0],[2],[1],[1],[0],[0],[0,2],[1],[1],[1,2],[1,2],[0,1,2],[0,1,2],[0,1,2],[0],[0],[0],[0,2],[2],[0,1],[0],[1,2],[2],[1],[1,2],[1,2],[1,2],[0,1,2],[1],[1],[1],[1],[1],[0],[0,1],[1],[2],[1],[1,2],[0,1],[0,2],[0,1,2]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":3}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_basic_47","seed":20047}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/constraint_103.json b/tests/filament_group/golden/config_b/constraint_103.json new file mode 100644 index 0000000000..7f8fe551d5 --- /dev/null +++ b/tests/filament_group/golden/config_b/constraint_103.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":12987,"full_score":6744.9032},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#1BC545FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D494DDFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#99E903FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#6C8B32FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#961DFEFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FF2B42FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#BFEBE0FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A6F508FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#2093D1FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#4B9E95FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#79642EFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#DC89BAFF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,145.34756469726563,196.37205505371094,358.7149353027344],[25.324295043945313,0.0,117.23784637451172,303.9642333984375],[553.1095581054688,434.2644348144531,0.0,28.46591567993164],[561.9080810546875,554.3380737304688,435.35601806640625,0.0]],[[0.0,412.2175598144531,165.17893981933594,252.97967529296875],[259.94940185546875,0.0,117.8436279296875,560.5171508789063],[168.64022827148438,568.7840576171875,0.0,28.568143844604492],[517.0733642578125,385.4801330566406,224.5548095703125,0.0]]],"layer_filaments":[[0,3],[1,3],[0,3],[0,1,3],[0,1,3],[1,3],[0,1,3],[1,2,3],[0,2],[2],[2],[2],[3],[1,2,3],[2,3],[1,2,3],[3],[3],[3],[3],[0,3],[3],[3],[2],[3],[2],[2],[0,2,3],[0,2,3],[0,1,2],[0,2],[2],[2],[2],[2],[2],[2],[2],[1,2],[1,2],[1,2],[1,2],[1,2],[2],[2],[2],[1],[1],[3],[3],[1],[0,1],[0,1],[0,1],[0,2,3],[0,2,3],[0],[0],[0,1],[0,1],[0,1,3],[0,1,3],[0,1,3],[3],[2],[2],[2],[2,3],[3],[0],[1,2,3],[3],[3],[1],[1],[1],[1],[0],[0,3],[0,3],[3],[3],[0,3],[3],[3],[3],[3],[2,3],[2,3],[2,3],[2,3],[0,2,3],[0,2,3],[0,3],[1,2,3],[3],[1],[3],[0],[0],[2],[2],[0,1,3],[0,3],[0],[0],[0],[0,2],[0,2],[2],[2],[2],[0,2],[2,3],[2,3],[2,3],[0,2,3],[0,2,3],[0,1,2,3],[0,2,3],[0,2,3],[2,3],[2],[2],[1,2],[2],[2],[0,3],[0,1],[0,1],[3],[3],[0,1,3],[0,1,3],[0,2,3],[0,3],[0],[0,2],[2],[0],[0,1],[0,1],[0,3],[0,3],[0,3],[0,3],[0,1,2],[0,2],[2,3],[1,2,3],[0,1,2],[3],[3],[3],[3],[1],[0,1],[0,1,3],[0,1,3],[0,1,2,3],[1,2,3],[1,2,3],[0],[0],[0],[0],[1],[3],[3],[0,1,2],[1,2],[2],[0,2],[0],[0,2],[0,2],[0,2],[1,2],[1,2],[0,1,2],[2],[1,2],[1,2],[1,2],[1,3],[1],[1],[1,3],[3],[0,1,3],[0,1],[0,1],[0,1],[0],[0],[0],[0],[2],[1],[1],[1],[3],[3],[3],[0,3],[0,3],[0,3],[0,2,3],[0,2,3],[0,1,2],[0,1,2],[1,2],[0,1],[0,1,3],[0,1,2],[0,1,2,3],[0,1,2,3],[1,3],[1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[1],[1],[3],[3],[0,3],[0,3],[0,1,3],[0,1],[1],[0],[0,2],[0,2,3],[2,3],[1,2,3],[0,1,2,3],[0,1,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,1],[1]],"unprintable_filaments":[[],[3]],"unprintable_volumes":{"2":[3],"3":[1]}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":3}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_constraint_103","seed":20103}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/constraint_88.json b/tests/filament_group/golden/config_b/constraint_88.json new file mode 100644 index 0000000000..b9cd2be222 --- /dev/null +++ b/tests/filament_group/golden/config_b/constraint_88.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":9750,"full_score":4926.6},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#037005FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D87849FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#F3CE18FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#BCFEA7FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#924B26FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3A216BFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D0924FFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A345ADFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#7FA1F1FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#5864ACFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#F36945FF","is_support":false,"type":"PA","usage_type":1},{"color":"#F02F44FF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,500.582275390625,562.5870971679688,81.93852233886719],[51.72758865356445,0.0,90.24585723876953,490.09320068359375],[430.67327880859375,232.1397247314453,0.0,146.47518920898438],[161.84280395507813,211.6325225830078,363.18682861328125,0.0]],[[0.0,554.25244140625,69.40193176269531,157.41722106933594],[122.196533203125,0.0,229.16275024414063,209.3227996826172],[192.6871337890625,78.21271514892578,0.0,35.126708984375],[227.9981689453125,364.66082763671875,66.126220703125,0.0]]],"layer_filaments":[[0,1,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,3],[0,3],[0,2],[0,1,3],[3],[1],[0],[2,3],[2],[2],[0,1,3],[0,1,3],[1,2,3],[0,1,2,3],[0,1,2,3],[0,2,3],[0,1,2],[0,1,2],[0,2],[0,2],[2],[2],[2],[0,2],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[0],[2],[0,2],[0,2],[2],[2,3],[1,2],[1],[0],[0],[0,1,3],[1],[1],[0,2,3],[1,2],[1],[1],[2],[2],[1,2],[1,2],[1],[1,2],[1,2],[1,3],[3],[3],[1],[1],[0,1],[0,1],[0],[0,1],[0,1],[0],[1,2,3],[0,1,3],[0,1,2],[0,1],[1,2,3],[2],[2],[2],[2],[2],[1],[2,3],[1,2],[0],[0],[0],[0,2],[0],[0],[0],[0,2],[0,1,3],[0,1,3],[0,1,3],[1,3],[1],[0],[0],[0],[0,3],[0,3],[0],[0],[0],[1],[1,2],[1,2],[2],[0,2],[0,2],[0,2],[0,2],[1],[1],[1],[1],[1,2],[1],[1],[3],[0,3],[0,3],[0,2,3],[2,3],[2,3],[2],[2,3],[2,3],[3],[3],[1],[1,2],[0,1,2],[2],[2],[3],[3],[0,1,2],[0,1,2],[0,2],[0,2],[0],[0],[0],[1,2,3],[1,2,3],[1,2,3],[0,1,2],[0,1],[0,1],[1,2],[1,2],[0,1,2],[0,1,2],[1,2,3],[1,2,3],[1,2,3]],"unprintable_filaments":[[0],[2]],"unprintable_volumes":{"1":[1],"2":[1],"3":[1]}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":1}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_constraint_88","seed":20088}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/constraint_97.json b/tests/filament_group/golden/config_b/constraint_97.json new file mode 100644 index 0000000000..e4858e52c7 --- /dev/null +++ b/tests/filament_group/golden/config_b/constraint_97.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":3367,"full_score":2146.2712},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":5},"machine_info":{"machine_filament_info":[[{"color":"#2A5557FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#995701FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#CBB5F1FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#E09394FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#38D65DFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A65DE8FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#D6E92AFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#21A474FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,6],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4"],"filament_info":[{"color":"#341F11FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#58D9A4FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#11D7FFFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#756DEFFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#D28F74FF","is_support":false,"type":"TPU","usage_type":1}],"flush_matrix":[[[0.0,40.422149658203125,281.1308898925781,420.726318359375,245.7325439453125],[564.1063842773438,0.0,80.42797088623047,132.09776306152344,33.372379302978516],[29.10088539123535,327.1266784667969,0.0,318.0596923828125,352.4109191894531],[79.35222625732422,349.1927795410156,450.20599365234375,0.0,473.4333190917969],[84.93012237548828,343.9147033691406,480.2047119140625,440.6584167480469,0.0]],[[0.0,203.69725036621094,148.45620727539063,208.9656524658203,217.2571258544922],[170.0343780517578,0.0,516.4771728515625,587.4338989257813,442.1988830566406],[37.863525390625,265.5264892578125,0.0,318.85748291015625,227.68455505371094],[257.746826171875,217.14395141601563,120.68830108642578,0.0,310.3852233886719],[327.35687255859375,328.03076171875,271.71405029296875,420.61297607421875,0.0]]],"layer_filaments":[[1,2],[1],[1],[1],[1],[0,1],[1],[2],[1],[1,3],[4],[1],[4],[4],[4],[4],[2],[2,4],[4],[4],[2],[1,2],[1,2],[1],[0],[0],[0],[0,3],[2],[2],[2,3],[2],[2],[2],[2],[2],[2],[2],[0],[0],[2],[3],[4],[4],[2],[2],[2],[2],[2],[2],[2,3],[2,3],[2,3],[0,2,3],[1,3],[1,3,4],[1,3,4],[1,3,4],[3],[0],[1],[1],[1],[1,4],[1,4],[1,4],[0,1,4],[0,1,3,4],[0,1,3],[0,3],[0,3],[2,3,4],[2,4],[2],[2],[3],[1,3],[1,3,4],[1,2,3,4],[0,1,2,3,4],[0,1,2,4],[2,3,4],[2,3,4],[1],[4],[1,4],[1,4],[3],[3],[3],[3],[3],[1,3],[1,3,4],[1,3,4],[1,3],[0,1,3],[0,1,2,3],[0,2,3],[3],[1,3],[0,3,4],[2,3,4],[2,4],[2,3,4],[2,3,4],[0,2,3,4],[0,2,3,4],[0,1,2,3,4],[0,3,4],[0,3,4],[0],[0],[0,4],[4],[0,2],[0,2],[2],[2],[2],[0,2,3],[0,2,3],[0,1,2,3],[1,2,3],[2,3],[2,3],[0,2],[0,2,3],[2,3,4],[0,2,3],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[1,2],[2],[2],[0,2],[0,2],[0,2,3],[0,2,3],[0,3],[0]],"unprintable_filaments":[[3],[]],"unprintable_volumes":{"3":[3],"4":[0]}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2,3]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":3},{"diameter":"0.4","extruder_id":1,"group_id":3,"volume_type":1}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_constraint_97","seed":20097}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/mode_bestfit_162.json b/tests/filament_group/golden/config_b/mode_bestfit_162.json new file mode 100644 index 0000000000..8b1e86d1e5 --- /dev/null +++ b/tests/filament_group/golden/config_b/mode_bestfit_162.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":3336,"full_score":2002.2096},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":1,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#28AC58FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#412846FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#733049FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#0AC1B4FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#A402D9FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#0E94B8FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3F2B52FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#CC874FFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#2739B9FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#103A81FF","is_support":false,"type":"PA","usage_type":1},{"color":"#4B971AFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#82A327FF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,160.58099365234375,186.70541381835938,293.4424133300781],[452.10089111328125,0.0,427.1346435546875,482.00482177734375],[26.20694351196289,235.17530822753906,0.0,410.3768615722656],[269.29888916015625,244.5442657470703,496.617919921875,0.0]],[[0.0,409.6128845214844,39.27631378173828,447.314697265625],[520.747314453125,0.0,143.31735229492188,21.33603286743164],[532.3141479492188,215.94216918945313,0.0,394.37481689453125],[321.899169921875,174.60623168945313,109.6452407836914,0.0]]],"layer_filaments":[[1,2,3],[1],[0,1],[0,1],[0,1],[0,1,2],[2],[0],[0],[2],[2],[0,3],[0,3],[0,2,3],[0,2,3],[0,2,3],[0,1,2,3],[0,1,2],[0,2],[0,2],[0,2],[1,2],[2],[2],[2],[2],[1,2],[1,2,3],[1,2,3],[0,2,3],[2,3],[3],[3],[3],[2,3],[2,3],[1,2],[0,2],[0,2],[2],[2],[2],[0,2],[2],[2],[0,1],[0,1],[1],[1],[1],[1],[1,2],[1],[0,2],[0,2,3],[2,3],[3],[0],[0,3],[3],[3],[2,3],[2,3],[2,3],[0,1],[0,1],[1],[1,3],[0,1,3],[0,1],[0,1,2],[0,1,2],[0,3],[0],[2],[2,3],[0,2,3],[0,1],[1],[2],[0],[0,2],[0,2],[2],[0,3],[0,1],[0,1],[0],[0,3],[0,2],[0],[0,1],[1],[1],[1],[0,1],[0],[0],[0,2,3],[3],[3],[3],[0,2],[0,2],[0,1],[0],[0],[0,1],[0,1,2],[0,2],[0,2],[0,1,2],[2,3],[2,3],[2,3],[3],[1,3],[1,3],[3],[1],[0,1,3],[0,3],[0,3],[0,3],[3],[3],[1],[0,1],[0,1],[0,1,2],[0,1],[0,1],[0,1,2],[0,1,2,3],[0,2,3],[3],[3],[3],[3],[1,2,3],[1,3],[1,2,3],[1,2,3],[1,2],[1,2],[1,2],[1],[1,2],[0,1,2],[2,3],[2,3],[3],[3],[0],[0,1],[0,1],[0,1],[0,2],[0,3],[2,3],[2,3],[2,3],[2],[2],[2],[0],[0,3],[0],[0],[0]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_mode_bestfit_162","seed":20162}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/mode_match_148.json b/tests/filament_group/golden/config_b/mode_match_148.json new file mode 100644 index 0000000000..65bd1c3ddf --- /dev/null +++ b/tests/filament_group/golden/config_b/mode_match_148.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":77523,"full_score":36613.432799999995},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":1,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#A3C1E2FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#6A88DEFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#413E53FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#4A7B53FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#589926FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#E58AF5FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#671FEFFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#C57874FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#BC965EFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#787D81FF","is_support":false,"type":"PA","usage_type":1},{"color":"#E927DEFF","is_support":false,"type":"PA","usage_type":1},{"color":"#F0994BFF","is_support":false,"type":"ABS","usage_type":1}],"flush_matrix":[[[0.0,163.1319122314453,22.072425842285156,178.8388671875],[484.3791809082031,0.0,220.6125946044922,247.07647705078125],[292.3028259277344,472.3754577636719,0.0,145.34214782714844],[79.97977447509766,308.6223449707031,316.60772705078125,0.0]],[[0.0,236.01913452148438,198.16650390625,445.4165954589844],[115.48052978515625,0.0,357.607177734375,379.4151306152344],[273.1755676269531,80.1114730834961,0.0,554.5277099609375],[91.31120300292969,511.2794189453125,19.784793853759766,0.0]]],"layer_filaments":[[0,2,3],[3],[3],[3],[3],[1,3],[1],[1],[1],[0,1],[0],[0,1],[0,1],[0,1],[0,1,3],[0,1,3],[0,2,3],[0,1,2,3],[0,1,2,3],[0,1,3],[0,1,3],[0,1,2,3],[1,2],[2],[2],[2],[2],[2],[2],[2],[2],[0,1,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,3],[0,3],[3],[3],[3],[1],[3],[3],[2],[0,2],[0,3],[0,3],[1],[1],[1],[0,1],[0,1],[0],[0],[0,1],[0,3],[0],[0],[0],[3],[3],[1],[3],[3],[2,3],[2,3],[0,2,3],[0,2,3],[0,2,3],[2],[2],[0,3],[0],[0],[0],[0,2],[0,2],[2],[2],[2],[1],[1],[0,1],[0,1],[0,1],[0,1],[0],[0],[0],[0],[0],[3],[3],[0,1,3],[0,1,2,3],[1],[1],[1,3],[2],[0],[0],[0],[0],[0],[0],[0,3],[0,2],[0,1,2],[0,1,2,3],[0,1,2,3],[0,1,3],[1,3],[1,3],[0,2,3],[0,2,3],[0,2,3],[0,1,2,3],[1,2,3],[1,3],[1,3],[1,3],[1,3],[1],[1],[1],[1],[2,3],[2,3],[2,3],[1,3],[2],[2],[2],[2],[0,2],[2],[3],[3],[2],[2],[2],[2],[2],[1],[1],[1],[0,1,3],[0,1,2],[0,1,2],[2,3],[0,2,3],[3],[0],[0],[0],[0,2],[0,1,2],[0,1,2],[0,1,2],[1,2,3],[0,2],[0,2,3],[2,3],[3],[1],[1],[2,3],[2,3],[1,2,3],[1,3],[1,3],[2,3],[2],[2],[1],[1,2],[1],[1],[3],[3],[1,3],[3],[1],[1],[1,2],[2,3],[2,3],[0,3],[0],[3],[1],[1],[0],[2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2,3],[1,2],[1,3],[1,3],[3],[3],[2,3],[2],[1,2],[2],[2],[0,2,3],[0,2,3],[0,3],[0],[0,1],[0,3],[0],[0,3],[0],[0],[0],[0,2],[0,2],[2],[2],[0,2,3],[0,1,2,3],[1,3],[3],[0,3],[0,3],[2,3],[2,3],[2,3],[2],[0],[3],[3],[1,3],[0,1,3],[0,2,3],[2],[2],[1,2],[0,1,2],[0],[1],[1,2],[2],[2],[2,3],[2,3],[0,2],[0,2],[0,1,2],[0,1],[0,1],[0],[0],[0,1,2],[0],[0,2],[0,1,2],[0,1,2],[0,2],[0,1,3],[0,1,3],[1],[3],[3],[0,1,2],[1,2],[1,3],[1,2,3],[1,2],[1,3],[1,3],[0,1,3],[0,3],[0,1,2],[0,2],[0,2],[0,2,3],[0,2],[2],[2],[2],[3],[3],[3],[1,3],[3],[3],[3],[3],[3],[1,2,3],[1,2],[2],[0],[0,3],[0,2,3],[3],[0,1],[0],[0],[2],[2],[0],[0],[0,2],[0],[0,3],[0,3],[0,3],[0,3],[0,3],[0,1],[0,1],[3],[2],[2],[2],[0],[1],[1],[0,1],[0,1],[0,1],[1],[1],[1],[1],[2],[2],[0,2,3],[2,3],[2,3],[2,3],[3],[1,3],[0,1,3],[1,3],[1,3],[1,3],[1,2,3],[1,2,3],[0,1,3],[0,1,2,3],[0,1,2,3],[0,2],[1,2,3],[1,2,3],[1,2],[1,2],[1],[1],[1],[1,3],[1,3],[3],[3],[3],[3],[3],[3],[3],[1,3],[2,3],[0],[0,2],[0,2],[0,2],[0,1,2],[0],[2],[0],[0],[1,2,3],[2,3],[1,2],[1,2],[0,2,3],[0,2,3],[0,2,3],[0,3],[0,2,3],[2],[2],[2],[0,2],[0,2],[0,2],[0],[0,3],[0,2,3],[0,2,3],[0,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[0,1,2,3],[0,1,2,3],[0,1],[1],[0,2],[0],[3],[2,3],[2,3],[2,3],[2,3],[0,2,3],[0,2,3],[0,2],[0,2],[0,2],[3],[3],[0],[0],[2],[2,3],[3],[3],[1,3],[1],[1],[2],[2],[2,3],[2,3],[2],[2],[2],[2],[0,1,2],[1,3],[1,3],[1,2],[1,2],[1,2],[1,2],[2],[2],[2],[3],[3],[2],[2],[2],[2],[0,2,3]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":3},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_mode_match_148","seed":20148}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/mode_time_168.json b/tests/filament_group/golden/config_b/mode_time_168.json new file mode 100644 index 0000000000..3093f7d779 --- /dev/null +++ b/tests/filament_group/golden/config_b/mode_time_168.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":5010,"full_score":2616.536},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":5},"machine_info":{"machine_filament_info":[[{"color":"#A7BDFDFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#E4B564FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#64E4F7FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#79AE21FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#BB3A10FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#342AAEFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#1B853FFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#C98C73FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4,4],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4"],"filament_info":[{"color":"#B0F63DFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#053F79FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#2236EAFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#3E1A46FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#E193E6FF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,357.560302734375,158.03790283203125,78.87968444824219,56.35820388793945],[312.62969970703125,0.0,578.679443359375,354.6175537109375,333.78289794921875],[385.2695007324219,297.87310791015625,0.0,18.705421447753906,101.41615295410156],[106.06452941894531,286.4847412109375,112.56126403808594,0.0,244.12152099609375],[234.8699951171875,51.119590759277344,95.25473022460938,578.6362915039063,0.0]],[[0.0,354.75567626953125,51.230716705322266,514.29296875,451.8372802734375],[30.5628719329834,0.0,426.8621520996094,304.156005859375,114.46688079833984],[305.9984436035156,567.757568359375,0.0,254.84019470214844,480.94757080078125],[302.3028259277344,503.4031982421875,186.15228271484375,0.0,498.27532958984375],[198.755859375,412.3115234375,207.9266815185547,364.662841796875,0.0]]],"layer_filaments":[[1,2,4],[1,2],[1,2],[1,2],[1],[4],[4],[4],[0,4],[0,4],[1,2],[2],[2],[0,1,4],[0,1,2],[0,1,2],[0,2],[0],[0,4],[0,3,4],[0,2,3,4],[2,4],[0,2,4],[0,1,4],[0,1,2],[0,2],[0,2,3],[0,3],[0],[0],[2],[2],[2],[0,2],[0,1],[1],[1,2],[1],[1,3],[1,3],[3],[4],[0,3,4],[0,3,4],[4],[4],[4],[4],[4],[4],[2,4],[3],[3],[0],[4],[2,4],[2],[1],[4],[4],[4],[2,3,4],[1,2,4],[2,4],[3,4],[1],[1],[2],[2,3],[2,4],[2,4],[2,4],[2,4],[2],[2],[2],[2],[2],[2],[0],[0],[0,4],[0],[0],[1],[2],[1,2,4],[1,2],[1,2],[1],[1],[1],[1],[0],[0,4],[4],[4],[4],[1],[1],[1],[0,1],[0,1],[0,1],[0,3],[3],[0,1,4],[0],[4],[2],[2],[2],[0],[2],[2],[2],[2],[2,3],[0,2,4],[4],[4],[1,4],[4]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":true}},"metadata":{"config_type":"B","id":"B_mode_time_168","seed":20168}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_b/stress_53.json b/tests/filament_group/golden/config_b/stress_53.json new file mode 100644 index 0000000000..32373ebb47 --- /dev/null +++ b/tests/filament_group/golden/config_b/stress_53.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":221651,"full_score":108544.89360000001},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":9},"machine_info":{"machine_filament_info":[[{"color":"#6E4AA1FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#074FAAFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#26FDADFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#3BE7E3FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}],[{"color":"#1BEEBCFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#24B63FFF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#1D8B58FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#94CF37FF","extruder_id":1,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[5,5],"prefer_non_model_filament":[false,false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6","GFL_7","GFL_8"],"filament_info":[{"color":"#946C77FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#A7626FFF","is_support":false,"type":"PA","usage_type":1},{"color":"#292239FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#598D3EFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#2655E9FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#B55473FF","is_support":false,"type":"PA","usage_type":1},{"color":"#41372CFF","is_support":false,"type":"ABS","usage_type":1},{"color":"#03F543FF","is_support":false,"type":"PA","usage_type":1},{"color":"#D6D645FF","is_support":false,"type":"PA","usage_type":1}],"flush_matrix":[[[0.0,291.2544860839844,422.10552978515625,418.0701904296875,292.8345642089844,339.3817443847656,405.2729797363281,365.58258056640625,86.30725860595703],[483.2503662109375,0.0,69.84707641601563,224.38035583496094,203.733642578125,224.8706817626953,294.561279296875,259.9091796875,272.02471923828125],[137.32522583007813,361.85614013671875,0.0,340.92767333984375,345.4422302246094,40.56327438354492,16.491357803344727,536.1297607421875,126.11983489990234],[203.38404846191406,210.85462951660156,114.1908950805664,0.0,562.6904296875,593.2681274414063,91.98974609375,590.84033203125,576.554931640625],[540.142333984375,132.3505401611328,494.5915222167969,81.36819458007813,0.0,64.4636459350586,214.88343811035156,126.16731262207031,296.77410888671875],[498.908447265625,461.8762512207031,406.3509216308594,592.5803833007813,242.8012237548828,0.0,497.3305358886719,487.568603515625,52.52210998535156],[205.15016174316406,113.19947052001953,217.03443908691406,332.4522705078125,586.600830078125,351.0008544921875,0.0,101.60228729248047,581.4674682617188],[473.035400390625,158.81935119628906,112.75211334228516,521.93798828125,303.3479309082031,460.9828796386719,375.4153747558594,0.0,456.6717834472656],[115.22876739501953,315.8811950683594,53.31958770751953,429.3057556152344,363.285400390625,305.8374328613281,327.2394714355469,356.9198913574219,0.0]],[[0.0,475.2527160644531,292.96661376953125,256.10455322265625,61.476932525634766,211.08169555664063,570.1622314453125,564.0394287109375,203.28515625],[568.154052734375,0.0,408.3011169433594,558.2335815429688,343.4308166503906,264.95001220703125,579.4437866210938,14.230875015258789,137.31179809570313],[135.64334106445313,582.063232421875,0.0,231.6909942626953,565.8902587890625,33.517860412597656,528.9524536132813,222.16119384765625,39.8148193359375],[224.55397033691406,80.74559783935547,407.32220458984375,0.0,486.5089111328125,189.3687744140625,218.08384704589844,476.9054260253906,415.141845703125],[80.25811767578125,116.48699951171875,147.13758850097656,562.3987426757813,0.0,405.1090087890625,466.7985534667969,282.1239013671875,27.882604598999023],[163.51449584960938,77.7492904663086,564.928466796875,420.79595947265625,50.73676681518555,0.0,435.3114318847656,293.3190612792969,475.1477966308594],[552.1832885742188,300.7683410644531,306.0501403808594,566.5839233398438,70.6010513305664,102.84969329833984,0.0,340.595458984375,299.34326171875],[94.5458755493164,72.97537231445313,205.3549041748047,505.8253479003906,18.799774169921875,502.36639404296875,526.6951293945313,0.0,429.6299743652344],[441.624755859375,242.9843292236328,171.42227172851563,386.14263916015625,383.2626647949219,191.22093200683594,291.0565490722656,85.72862243652344,0.0]]],"layer_filaments":[[0,2,5,7,8],[0,5,7,8],[5,7],[5,7],[7],[1],[1],[6],[6],[7],[4,7],[4,7],[2,4,7],[7],[0],[2],[2,4,5,7,8],[4,8],[4],[6],[7],[7],[7],[2],[0,2],[2],[0],[1],[1],[1],[1,7],[1,7],[1,6,7],[6,7],[3,6,7],[3,6,7],[3,6,7],[3,6,7],[3,5,7],[3,5,7],[3,5,7],[3,5,7],[4,5],[3],[3,5],[3,4],[3],[4],[4],[4],[1],[1],[1],[1,3],[1,3,8],[1,8],[0],[0,8],[8],[8],[7,8],[2,7],[2,7],[2,7],[7],[7],[7],[7],[7],[1,7],[1,7],[1,7],[1],[1],[1,5],[1,3,5],[3,8],[3,8],[3],[3],[6],[6],[0,6],[6],[5],[5],[5],[0,3,8],[0,3,8],[0,3],[0],[8],[3,8],[3,8],[3],[3],[3],[2,7,8],[6,7,8],[4,6,8],[1,4,6,8],[1,4,6,8],[1,4,6,8],[1,2,8],[0,1,2,8],[1],[1],[3],[3],[3],[3],[3],[3,5,8],[4,5],[4,5],[4,5,8],[4,5,6,8],[4,5,6],[0,6,7],[0,2,6],[0,2,6],[2,5,6],[5,6],[2,6],[2,4,6],[2,4,6],[2,4,6,8],[6,8],[1,8],[2,8],[3],[5],[5],[5],[0],[6],[8],[8],[2,4,6],[0,2],[0],[0],[0,3],[0],[0,2],[0,2,5],[0,4,5],[0,4,5,6],[0,5,6],[0,6],[6],[3,6],[1,3],[1],[6],[8],[3],[3],[3],[3],[3,4,5],[5],[0],[0],[0],[0,1,3,5,7],[0,1,4,5,7],[0,1,4,5,7],[0,1,4,5],[4,6],[4,6],[4,6],[4,6],[0,1,2,5,8],[0,1,2,5,8],[0,1,2,5,8],[0,1,5,8],[2,4,6],[2,4,6,7],[4,6,7],[6],[2,5,7,8],[2,7,8],[2,8],[0,2],[0,2],[2],[1,2],[1,2],[1],[1],[1,3],[3],[1,3],[8],[8],[0,3,4],[0,1,3,4],[0,1,3],[0,3],[0,2,8],[0,2,4],[0,1,2,4],[1,4],[1,4],[1],[8],[3,5,7],[3,5,7],[1,2,3,6,8],[1,2,3,8],[2,3,8],[2,4,8],[4,7],[4,5,7],[4,5,6,7],[4,5,7],[4,5,7],[3,6],[3,6],[3,5],[3,5],[3,5],[0,2],[0,2],[2],[1],[3,5,8],[1,3],[1,2],[1,2],[1,2],[1,2],[2,5],[1,6,7],[1,6,7],[1,6],[0,1,6],[3,6],[3,5],[5,6],[3,5,6],[3,5],[3,4,5],[2,3,5],[3,5,7],[0,4,8],[0,8],[0,8],[0,1],[0,7],[0],[4],[0,4],[0],[0,1],[0,1],[0,1],[0,8],[4,8],[4,8],[4,8],[4,8],[4,8],[8],[3],[2,3,4,6,8],[0,2,3,4,6],[0,2,4],[3,4],[3],[3,7],[0,1,7],[1,7],[7],[7],[7],[2,3,5],[2],[7],[0,7],[7],[6,7],[6,7],[7],[0,1,2,5,7],[0,1,2],[0,1,2],[0,1,2],[0,1,2],[0,1,3],[0,2,3],[0],[1],[1],[0,1],[0,1,8],[1,2],[2,3],[2,3],[0,1,4,5,6],[0,1,5],[0],[7],[1],[1,3],[1],[5,7],[7],[1,7],[0,4,5,8],[0,5,8],[1,5,8],[8],[0],[0,7],[7,8],[7,8],[7,8],[7,8],[4,7,8],[2,7,8],[2,4,7,8],[1,5,6],[1,5,6],[1,5],[1,5],[5],[5],[6],[7],[7],[1,6],[1,3,6],[1,7],[1,7],[1,3,4,6],[1,4,6],[1,4,5,6],[0,5,6],[0,5,6],[5,6],[1,5,6],[5,6],[5,6],[5,6],[5],[3],[4],[4],[4,7],[7],[2,7],[2,5,8],[2,5,8],[2,5],[2,5],[6],[1],[3],[3],[2,3,5,8],[2,8],[2,8],[2,8],[3,8],[3,4,8],[2,3,4,8],[1,2,8],[1,2,8],[1,2,8],[1,8],[1,8],[8],[8],[8],[8],[8],[8],[8],[3],[1],[0],[0,2],[0,2],[0,2],[0,2],[2],[2],[4],[3,4],[3],[1],[1],[8],[7],[7],[6],[6],[6],[6],[1,4,5],[1,4],[1,4,5],[1,4],[1,4],[1,4],[1],[6],[0,6],[0,6],[0,4],[0,4],[4],[4],[4],[1,2,5],[1,5],[1,5],[5,8],[5,8],[5,8],[5],[5],[5],[5,7],[5,7],[1,5],[1,7],[1,7],[7],[7],[5],[5,7],[3,5,7],[1,3,5,7],[1,5,7],[1,2,7],[1,3,7],[1,2,3,4,5],[1,4,5],[1],[1],[1],[3,4,5,7,8],[4,5,7,8],[4,7,8],[8],[8],[8],[7,8],[4,7,8],[4,7,8],[7],[4,7],[7],[7],[1,7],[1],[1],[1],[1,6],[1,3,6],[3,6],[0,3,6],[8],[8],[6,8],[2,8],[2,7],[7],[1],[1],[1],[8],[8],[8],[8],[4,8],[4,8],[3,4,5,6,8],[4],[3],[2,3],[2,3],[3],[3],[6,7,8],[6,8],[6],[6],[1,2,5,8],[1,2,3,5,8],[1,2,3,5,8],[1,2,3,5],[1,3],[1,2,3],[2],[2],[2],[2],[2],[1],[1],[1],[1],[2,3,4,6,7],[3,4,6,7],[4,7],[4,7],[4,5,7],[4,7],[4],[4],[7],[7,8],[8],[3],[5],[5],[7],[1],[0],[0],[0],[0],[8],[8],[2,6,7],[2,3],[1],[1],[2],[1],[1],[1],[0],[0],[0],[0,4],[0,4],[0],[0,3],[0,3,4],[0,3,4],[0,3,4],[3,7],[3,5,7],[5],[5],[1,5],[4],[0,4],[0,4,6],[4,6],[1,2],[2,5],[2,4,5,6],[2,4,5,6],[2,4,5,6],[2,4,5,6],[2,4,5,6],[2,4,5],[4,5,6],[4,6],[2,6],[2,7],[7],[1],[1,2],[2,8],[8],[8],[1,8],[1],[0,2,4,5,6],[0,2,4,5,6],[2,4],[2,4],[2,4],[4],[4],[1],[1],[1],[1],[1,7],[1,7],[1,4],[1,5],[5],[4],[0,3,4,8],[0,3,4,7],[0,3,7],[0],[0],[0],[0],[0],[0],[7],[7],[5],[5],[2,3],[2],[0,2],[7,8],[8],[6,8],[0,3,4,8],[1,2,8],[2,8],[5],[5],[0,2,5,7],[0,2,5,8],[2,5,8],[5,8],[0,3,4,7],[3,5,6,7,8],[3,5,6,7],[3,6],[2,3,6],[2,6],[2,6],[6],[6],[4,6],[1,3,4,7,8],[1,2,3,4,7],[1,2,3],[2,8],[8],[1,8],[7],[7],[3,4,5,6,7],[3,4,6],[1],[3],[3],[4,5,8],[4,5],[4,5],[4,5],[5],[5],[5,7],[6],[6],[6],[6],[6],[3],[2,3],[2,3],[3],[1,3],[1,4],[1,7],[6],[2],[2],[2],[2],[1,2],[1,2],[2],[2],[2,8],[2,8],[0,2],[0,2],[2],[2],[2,5],[2],[2],[2],[2,5,6,7],[6,7],[1,6,7],[1,6,7],[1,6,7],[7],[5,7],[7,8],[6,7],[3,6,7],[6,7],[7],[3],[6],[6],[8],[8],[8],[8],[2],[2],[2],[2],[2],[1],[1],[8],[8],[5,8],[1,5,8],[1,8],[8],[8],[2,7],[2,6,7],[2,6,7],[0,1,2,4,8],[1,2,4,8],[2,3,4,6],[2,3,4,6],[2,3,4,6],[3,4],[3,4,5],[4,5],[4,5],[4,5],[5],[6],[6],[7],[4],[4],[5],[5],[5],[5],[5],[5],[5],[2,5],[4,5],[5,7],[4,5],[5],[5],[5],[0],[0],[2],[0,1,2,5,6],[0,6],[0,6],[0,6],[0,6],[0],[0],[0],[8],[4],[6],[6],[5,6],[5,6],[5],[5],[3,4,5,7],[3,5,8],[3,5],[3,5],[3,5],[5],[0],[1],[2,5,8],[2,8],[8],[0],[0],[0],[0],[0],[0],[6,7],[6,7],[0,6,7],[0,1,6,7],[1],[1],[1],[5],[1],[1],[5],[0],[8],[8],[3,8],[8],[0,3,4,5,8],[0,3,8],[0,3,6,8],[0,3],[3],[3,4],[3,4],[3,4],[2,7],[2],[4,5],[5,6,7,8],[5],[1,2,4,7,8],[2,4,6,7],[1,6],[0,1,6],[6],[6],[6],[1,6],[1,6],[1,6],[1],[1,8],[3,7],[3,5],[3,5],[5],[5],[3,5],[3,6],[6],[6],[1,6],[1,6],[1,6],[1],[1],[1,2],[1,2],[1,2],[2,5],[7],[0,7],[1,2,3,7,8],[1,2,7,8],[2,5,7],[2,7],[2,7],[2,7],[2,7,8],[2,7],[7],[7],[6,7],[7],[1],[1,6],[0],[0],[1,3],[1,3],[1,3],[6],[6],[0],[0,8],[0,8],[0],[0,7],[7],[7],[3,4,6],[3,4,6],[4,6],[0,4,6],[4],[4],[4],[4,7],[4,7],[7],[7],[4,7],[3,7],[3],[3],[2],[2],[2,5],[2,6],[6],[5,6],[6],[0,6],[0,6,8],[0,8],[8],[8],[8],[4],[2,4],[1,2,6,7,8],[1,2,6,7,8],[1,2,3,6,8],[1,2,3,4,6,8],[1,2,3,4,6,8],[1,2,3,4,6,8],[1,3,4],[1,3,4],[1,3],[1,3],[0,1,3],[0],[6],[5,6],[6],[6],[6],[6,7],[6],[3,6],[3],[3],[3],[3],[5],[4,5],[4,5],[0,1,2,5,8],[0,1,2],[0,1],[1],[1],[1,3],[1,3,8],[1,3,5],[3],[3,6,7],[3,6,7],[3,6],[3,6],[6],[6],[5,6],[5,6],[8],[4],[4],[4],[1,4],[4],[4],[4],[4],[4,6],[4,6],[4,6],[1,3,8],[3],[3,5],[3],[2,6],[1,2,6],[1,2,6,8],[1,6],[1,5],[1,5],[1,5,8],[0,5,8],[0,5],[5,8],[5,7,8],[5],[5],[7],[7,8],[5],[0,3,6,8],[0,3,6,8],[2,6],[2,6],[2,6],[0,6],[1,4,6,8],[1,4,8],[1,8],[1,8],[8],[8],[5],[5],[5],[5],[5],[8],[2],[2],[2],[2],[2,5],[0,5],[0,5],[0,4],[0,4,5],[0,4,5],[1,3,8],[1,3,5],[1,3],[1,3],[3],[1,3],[0,1,4,5,6],[0,1,4,5,6],[0,4,5,6],[0,5,6],[0,5,6,8],[0,5,6,8],[0,5,7],[0,7],[0,4,7],[0,4,7],[0,4,7],[0,4,7],[0],[0],[0],[4],[4],[0,7],[3,7],[2,3,4,6,8],[2,3,6,8],[2,6,8],[1,6,8],[1,6,8],[1,6,8],[0,4,5,6],[4],[2,4],[2,4],[2,4],[2,4],[2],[2],[2,3],[2,3],[2,3],[3],[0],[8],[0,3,4,7],[0,3,4],[2,5,7],[2,5,7],[2],[2],[2],[2,4],[2],[2],[2],[2],[2],[5],[5],[5,7],[3,5,6,7],[1,3,5,6,7],[2,3,5],[2,3,5],[3,5],[3,5,7],[3,7],[1,7],[1,7],[1,7],[1,4,7],[2,4,7],[2,4,7],[2,7],[0,2,7],[2],[5],[5,6],[5,8],[5,8],[2,8],[2],[2],[8],[8],[7],[8],[2],[2],[2],[2],[2],[2],[3],[3],[3],[3,5],[1],[1],[1],[1],[1],[1],[6],[6],[6],[6],[1,2,7],[2,3,7],[1,2,3,7],[0,1,7],[0,7],[0,7],[0,6,7],[7],[0,7],[0,7],[0,7],[0,7],[0,7],[0,7],[0,7],[7],[1],[1,2],[1,2,7],[1,2,7],[1,2,7],[1,2,7],[1,2,7,8],[1,7],[1,6,7],[0,4,7],[0,7],[0,5,7],[0,5,7],[7],[7],[7],[0],[1,4,7,8],[1,4,6,8],[4,6],[0,2,6],[0,6],[0],[0],[0],[8],[8],[8],[0],[0],[0,3],[1],[1],[1,4],[1,4],[4,5],[4],[4],[7],[2,7],[0,1,3,6,7],[2,6],[2],[2],[2,8],[2,8],[2,8],[2,8],[2],[2,7],[2,7],[7],[5],[5],[7],[7],[1,7],[0],[0],[4],[4],[1,4],[1,4],[1,2,4],[1,2],[1],[1,6],[1,4,6],[6],[6],[4,6],[2],[2],[2,4,6],[4,6],[4,6],[2,6],[6],[5,6],[0,6],[0,6],[0],[0],[0,7],[0,4,7],[4,7],[4],[6],[6],[5],[0],[0],[0,3],[0,3],[0,3],[0,3],[3,7],[3],[3,6],[3,6,7],[1,2,4,8],[2,4,8],[4,7,8],[4,7,8],[1,4,8],[1,4,7,8],[1],[1],[8],[2,3,4],[1,2,4],[4],[4],[7],[7],[0,7],[3],[2,3],[2,3],[2,3],[3],[3],[2,3,5,6,8],[2,5,6],[6],[6],[6],[4,6],[4,6],[4,6,8],[2,5,8],[2,4,8],[2,3,4],[2,4],[6],[6],[6],[0,6],[6,7],[6,7,8],[7,8],[7,8],[7],[2],[5],[5],[2],[2,4],[2],[2],[6],[0,3],[0,3,7],[0,3,5,7],[0,8],[4,8],[3,4,8],[1,3],[1,3,5],[1,3,5],[3,5],[3],[0,3],[0,3],[1,2,5,8],[2,4,5,8],[2,4,5],[2,4,5],[1,2,3,6],[1,2,3],[1,3],[1,2,3],[1,2,3,7],[1,3,7],[1,3,7],[1,3,7],[1,3,7],[1,3,7],[1,3],[1,3,6],[1,3,6],[1,3,6],[1,3,6,7],[1,3,7],[3],[3],[3],[3],[4,5],[3,4],[3,4,6],[3,4,6],[3,4,6],[1,2,7],[0,2,4,5,7],[0,2,3,4],[3,4],[3,4],[3,4],[3,4],[3,4],[0,3],[0],[8],[8],[1],[1],[0,1,2,3],[1],[7],[4,7],[0,4],[2],[6],[6],[1],[0,3,4,5,8],[0,2,8],[0,2,8],[0,2],[0,3,7],[0,3],[0,3],[0,3],[3],[3,5],[3,7],[3,7],[0,1,2,7,8],[0,2,5,7],[4,8],[4,8],[8],[8],[3],[3],[3,5],[3,5],[5],[2],[7],[1,7],[1,7],[1],[1],[5],[2,5,6],[2,5],[2,5],[2,5],[3],[3],[3],[3],[4,5,7,8],[2,3,4,5,7],[0,2,3,4,5,7],[2,3,4,5,7],[1,4,5,8],[1,4,5,8],[1,4,8],[1,8],[1,8],[1],[1],[1],[1,5],[1,5],[1,5],[1,5],[1,5],[4,5],[4,5],[4,5],[5],[5],[6],[2],[2],[2],[4],[7],[7],[7],[0,7],[0,7],[0,6],[0,6],[0],[1,4,6,7],[6,7],[6],[6],[8],[8],[6],[6,8],[3,6],[3,6],[3,6],[2,3,6],[3,6],[3,6],[6],[8],[8],[3,8],[6],[6],[6],[6],[2,6],[2,6,7],[2,6],[2,6],[2,6],[1,3,8],[1,2,8],[1,2,4,8],[1,2,4],[0,2,4,6],[0,2,6],[2,6],[6],[3,6],[0,1,2,3,7],[0,1,2,3,8],[0,1,3,5,8],[1,3,8],[1,3,8],[3],[6],[4],[7],[3,7],[3,7],[3,7,8],[2,4],[2,4],[4],[4,5],[4,5],[4,5],[4,5],[5],[5],[5],[3],[3],[3],[3],[3],[3],[8],[2,8],[2,8],[5],[0,1,4,6],[0,4,6],[0,4,6],[0,6],[0,5],[0,5],[5],[5],[0,2,3,4,8],[0,2,4,7,8],[0,7,8],[0,4,8],[0,4],[4],[4],[3],[3,5],[3],[0,3],[3],[3],[4],[4],[4,6],[4,6],[4,8],[8],[4],[4],[4],[4],[4],[5],[5],[5],[5],[5],[5],[5],[2,5],[1,2,5],[1,2,5,8],[2,3,4,5],[1,2,3,5],[1,2,5],[0,1,2,5],[2,5],[2,5],[2,5],[2,5],[2,5,6],[2,6,7],[2,6,7,8],[0,2],[0,2],[2,5],[2,5],[2,5],[2,5],[6],[1],[1],[1],[1],[6],[6],[5,6],[1,5,6],[1,5,6],[1,5],[1,2,5],[1,5,8],[5,8],[5],[5],[5],[5],[6],[6],[6],[7],[4],[4],[4,5],[5],[2,5],[2],[2],[2],[1],[0,4,5],[0,4,5,8],[0,1,4,5,8],[3,8],[5,8],[8],[1,2,3,6],[1,2,5],[1,2,5,7],[1],[1],[2],[2,7],[2,6,7],[6],[6],[6],[6],[5,6],[1,2,5,7,8],[1,5,7,8],[1,5,7,8],[5,7],[5],[5],[5,7],[5,7],[5,7],[7],[8],[8],[8],[8],[6,8],[6,8],[8],[8],[8],[6,8],[6,8],[3,6],[3,6],[6],[6],[6],[1],[1,2],[8],[7],[7],[7,8],[2,7,8],[1,8],[1,8],[1,6,8],[6,8],[4,6],[4,6],[4,6],[4],[7],[0,2,3,4,7],[0,2,4],[0,1,2,5,6],[1,2,5,6],[1,2,5],[1,2,5],[1,2,5],[1,2,5],[1,2,5],[2,5,6],[3,6,7],[5,7],[5,7],[5,7],[5,7],[5,6,7],[5,6,7],[6,7],[6],[4,6],[4,6],[4,5,6],[4,5,6,8],[4,5,6,8],[4,8],[2,7,8],[1,2,7],[1,2,4,7],[0,2,4,7],[0,1,4],[0],[0],[0,4],[0],[0],[5],[0,5],[0,5],[0,1],[1,2],[1,2],[6],[6],[0,4,5,7,8],[0,4,5,6,7],[0,5,6],[0],[0],[0],[0],[1],[5],[0,5],[5],[0,4,5],[3],[3],[7],[6,7],[6],[4],[2],[1,2],[1,2],[2],[2],[2],[2],[2],[2],[1],[1],[1],[1],[1],[1,2],[1,4,5,7],[1,2,3,6,7]],"unprintable_filaments":[[],[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0],"1":[1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":1,"group_id":1,"volume_type":3},{"diameter":"0.4","extruder_id":1,"group_id":2,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true,true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"B","id":"B_stress_53","seed":20053}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_c/basic_3.json b/tests/filament_group/golden/config_c/basic_3.json new file mode 100644 index 0000000000..a6534e289d --- /dev/null +++ b/tests/filament_group/golden/config_c/basic_3.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":533.0},"context":{"group_info":{"filament_volume_map":[2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":3},"machine_info":{"machine_filament_info":[[{"color":"#FD981AFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#6618F5FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#BBA143FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#26550AFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[3],"prefer_non_model_filament":[false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2"],"filament_info":[{"color":"#911BD7FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#89C1C0FF","is_support":false,"type":"PA","usage_type":1},{"color":"#C64EE6FF","is_support":false,"type":"ABS","usage_type":1}],"flush_matrix":[[[0.0,64.12446594238281,186.0951385498047],[482.5750427246094,0.0,78.35060119628906],[161.81735229492188,233.08798217773438,0.0]]],"layer_filaments":[[0,1],[0,1],[0],[0],[0],[0],[0,2],[1,2],[1,2],[0],[0,2],[0,1],[0],[0,2],[0,2],[2],[2],[1],[0,2],[0,2],[0],[0,2],[2],[2],[2],[0],[0],[0,1],[0,1],[0,2],[1,2],[1,2],[0,1],[0],[0],[0],[0,2],[0,1,2],[1,2],[0],[0],[0],[0],[2],[0,2],[0,2],[1,2],[1,2],[0],[0],[2],[2],[0],[0],[2],[2],[0,2],[0,2],[2],[1,2],[1,2],[1,2],[2],[2],[1],[1],[1],[1],[1],[0,1],[0],[0],[0,2],[0,2],[0,2],[0],[0],[0,2],[1,2],[1,2],[1,2],[0,2],[1,2],[1,2],[2],[2],[2],[0,1],[0,1],[1],[1],[0],[0,2],[0,2],[0,2],[0,2],[0,2],[0,1],[0],[0],[0,1],[0,1],[1],[1,2],[1],[1],[0],[0,2],[0,2],[0,2],[0,2],[0],[1],[1],[0,1],[0,1],[1,2],[0,1],[0,1],[1],[0],[0,2],[0,2],[0],[0],[0],[0],[0,2],[2],[0],[1],[0,2],[0,2],[0,1,2],[0,2],[0,2],[0,2],[1,2],[2],[2],[1]],"unprintable_filaments":[[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0,1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":0,"group_id":2,"volume_type":2}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"C","id":"C_basic_3","seed":30003}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_c/basic_33.json b/tests/filament_group/golden/config_c/basic_33.json new file mode 100644 index 0000000000..ed05b5f639 --- /dev/null +++ b/tests/filament_group/golden/config_c/basic_33.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":0,"full_score":608.0},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":5},"machine_info":{"machine_filament_info":[[{"color":"#93FE0AFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#FE6A12FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#E78D3BFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A20CB0FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[5],"prefer_non_model_filament":[false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4"],"filament_info":[{"color":"#C51507FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#D366B2FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#D07D0EFF","is_support":false,"type":"PLA","usage_type":1},{"color":"#E4C00AFF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#12B359FF","is_support":false,"type":"PETG","usage_type":1}],"flush_matrix":[[[0.0,274.9917297363281,455.0113830566406,551.6867065429688,562.2197265625],[345.1457214355469,0.0,337.8075866699219,484.70074462890625,465.59490966796875],[332.17742919921875,481.7458801269531,0.0,339.1631164550781,394.23785400390625],[317.8833923339844,417.9119873046875,523.1845092773438,0.0,164.09495544433594],[455.5447692871094,228.3113555908203,309.9906311035156,487.07562255859375,0.0]]],"layer_filaments":[[1,3,4],[1,2],[1,2,4],[2,4],[2,4],[2,4],[3,4],[3,4],[1,3,4],[0,3,4],[0,1,3,4],[0,1,3,4],[0,1,2,3,4],[1,2],[1],[0],[4],[2],[2],[2,4],[0,2],[0,2,3],[1,2],[1],[1],[1,4],[4],[0,4],[1],[1],[1],[1,2],[0,3,4],[1,2,3],[1,2],[0,1,2],[0,1,2],[0,1,2],[2,4],[2,4],[2],[2],[1],[1],[0],[1,3,4],[0,1,3,4],[0,1,2,3],[0,1,3,4],[0,1,2],[0,2],[0,2],[2],[2],[2,3],[2,3],[0,1,4],[0,4],[0,4],[0,4],[0,2,4],[0,4],[0],[0,2],[0,2],[0,2],[0,2],[0],[0],[2],[2],[2],[0,2],[0,2],[0,2],[0],[2],[2],[2],[2],[1],[0],[0],[0],[0],[2],[2,3],[3,4],[3],[3],[0,2],[4],[0],[0],[2,3],[2,3],[2,3],[2],[1,2,4],[1,2],[1,2],[1,2,3],[2,3],[0,3],[0],[0,3],[0,2,3],[0,2],[2],[2],[2],[2],[1],[1],[1]],"unprintable_filaments":[[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0,1,2,3,4]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":0,"group_id":2,"volume_type":2},{"diameter":"0.4","extruder_id":0,"group_id":3,"volume_type":3},{"diameter":"0.4","extruder_id":0,"group_id":4,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"C","id":"C_basic_33","seed":30033}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_c/constraint_85.json b/tests/filament_group/golden/config_c/constraint_85.json new file mode 100644 index 0000000000..9c03487aac --- /dev/null +++ b/tests/filament_group/golden/config_c/constraint_85.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":8700,"full_score":4679.32},"context":{"group_info":{"filament_volume_map":[2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":4},"machine_info":{"machine_filament_info":[[{"color":"#D04D20FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#408006FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#A31F43FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#846951FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[4],"prefer_non_model_filament":[false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3"],"filament_info":[{"color":"#92C1F9FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#B0D9AAFF","is_support":false,"type":"PA","usage_type":1},{"color":"#5855D4FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#2CEAEAFF","is_support":false,"type":"PLA","usage_type":1}],"flush_matrix":[[[0.0,263.98394775390625,335.4018249511719,562.2523193359375],[514.525390625,0.0,491.3005676269531,28.14336585998535],[562.559814453125,351.77215576171875,0.0,321.54388427734375],[304.2557067871094,320.45123291015625,470.2841796875,0.0]]],"layer_filaments":[[2,3],[3],[3],[3],[1,3],[1,2,3],[0,1,2],[2],[2],[2],[2],[2],[2],[1],[1,2],[0,2],[0,2],[0,2],[1],[1],[1],[1],[1],[1],[1,3],[1,3],[1,3],[0],[0],[0],[0],[0],[3],[3],[3],[1,3],[1,3],[2],[2],[0,2],[2,3],[2,3],[3],[3],[1,2],[1,3],[1,3],[1,3],[0,1,3],[1,3],[3],[3],[3],[0,3],[0,1,2],[2],[2],[3],[3],[2,3],[1,2,3],[1,2,3],[1],[1],[1,2],[1,2],[1,2],[1,2],[2],[2,3],[2,3],[3],[0,2,3],[0,2,3],[0,1,2,3],[0,1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[0,1,3],[0,1,3],[0,1,3],[0,1,2,3],[2,3],[2,3],[2],[2],[0,2],[0,2],[0,2],[0,1,2],[1,2],[2,3],[2,3],[2],[2],[0,1],[0],[1,3],[2,3],[2],[2,3],[3],[3],[3],[0,2],[0,2],[0,2],[0,2],[0,1,2],[0,1,2],[0,1,2],[0,2,3],[1,3],[1,3],[1,3],[0,1],[0,1],[1,3],[3],[2,3],[3],[3],[0,3],[0],[0],[0,3],[0,1],[0,1],[0,1],[1,3],[1,3],[3],[3],[3],[2,3],[2],[2],[1],[1],[0,1,2],[0,1,3],[2,3],[2,3],[3],[1,3],[1,3],[0,1,3],[0,2],[1,3]],"unprintable_filaments":[[]],"unprintable_volumes":{"2":[1],"3":[1]}},"nozzle_info":{"extruder_nozzle_list":{"0":[0,1,2]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":0,"group_id":2,"volume_type":2}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"C","id":"C_constraint_85","seed":30085}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_c/stress_66.json b/tests/filament_group/golden/config_c/stress_66.json new file mode 100644 index 0000000000..de57c92ac6 --- /dev/null +++ b/tests/filament_group/golden/config_c/stress_66.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":222454,"full_score":117843.1344},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":16},"machine_info":{"machine_filament_info":[[{"color":"#9723D6FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#EFC01BFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#1EFEFCFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#06BB93FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[16],"prefer_non_model_filament":[false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6","GFL_7","GFL_8","GFL_9","GFL_10","GFL_11","GFL_12","GFL_13","GFL_14","GFL_15"],"filament_info":[{"color":"#FD165AFF","is_support":false,"type":"ABS","usage_type":1},{"color":"#ACE178FF","is_support":false,"type":"PA","usage_type":1},{"color":"#F5E1C4FF","is_support":false,"type":"PA","usage_type":1},{"color":"#FAD42BFF","is_support":false,"type":"PA","usage_type":1},{"color":"#ECAF69FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#C57761FF","is_support":false,"type":"PA","usage_type":1},{"color":"#00D43EFF","is_support":false,"type":"PLA","usage_type":1},{"color":"#1B183DFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#42C8D4FF","is_support":true,"type":"PLA-S","usage_type":0},{"color":"#9E820CFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#6EFA32FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#C200D9FF","is_support":false,"type":"PETG","usage_type":1},{"color":"#820C29FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#B956DFFF","is_support":false,"type":"ABS","usage_type":1},{"color":"#8B273CFF","is_support":false,"type":"ABS","usage_type":1},{"color":"#91B44AFF","is_support":true,"type":"PLA-S","usage_type":0}],"flush_matrix":[[[0.0,350.8710021972656,556.156494140625,131.57212829589844,264.03289794921875,270.5172119140625,53.87075424194336,305.956298828125,31.526546478271484,303.4163513183594,238.9023895263672,375.3182678222656,277.0335388183594,513.9209594726563,447.4983825683594,198.42149353027344],[107.57652282714844,0.0,129.1732177734375,287.8129577636719,210.99322509765625,164.73182678222656,129.17172241210938,355.39776611328125,51.827919006347656,217.5868377685547,106.62547302246094,351.341064453125,414.035888671875,347.29730224609375,585.4154052734375,349.0646057128906],[18.81222152709961,502.07562255859375,0.0,482.6243591308594,452.79150390625,507.6612854003906,392.7107849121094,334.48651123046875,28.603099822998047,77.24398040771484,299.47381591796875,257.1522216796875,493.5286560058594,224.06558227539063,465.6399230957031,38.92766571044922],[23.67986297607422,424.5287170410156,406.32958984375,0.0,581.2352294921875,559.201171875,548.3690795898438,458.03662109375,347.8531799316406,211.65956115722656,138.69918823242188,596.22314453125,64.93783569335938,369.5606384277344,462.3384704589844,450.8909912109375],[249.47984313964844,294.8421630859375,311.9303894042969,311.2370910644531,0.0,29.337980270385742,127.47315979003906,14.153016090393066,508.3543701171875,183.4864959716797,13.187865257263184,119.6075210571289,592.15576171875,22.624086380004883,328.7447509765625,132.05868530273438],[489.9524841308594,484.7672119140625,430.89141845703125,195.78912353515625,535.0629272460938,0.0,290.4599304199219,499.508544921875,98.51454162597656,284.4607849121094,129.02725219726563,163.6967315673828,147.62289428710938,27.92174530029297,153.07701110839844,543.1622924804688],[103.314697265625,573.92822265625,256.1690673828125,10.18743896484375,11.878326416015625,108.08622741699219,0.0,314.4029541015625,78.79996490478516,525.9464111328125,46.16083526611328,544.1360473632813,404.7229919433594,61.09773254394531,559.2588500976563,474.85693359375],[344.5564270019531,553.497314453125,433.0024108886719,437.758056640625,474.4132080078125,82.42955780029297,18.8521728515625,0.0,22.66818618774414,424.13043212890625,156.5281982421875,568.3748779296875,263.234375,571.3795776367188,173.0449981689453,85.22390747070313],[445.014404296875,292.1539001464844,220.01882934570313,389.284912109375,399.1071472167969,154.06930541992188,99.3953628540039,227.187744140625,0.0,350.8926086425781,431.9893798828125,96.61743927001953,164.4599151611328,357.43927001953125,100.85946655273438,12.405088424682617],[210.86514282226563,384.3556213378906,211.51168823242188,448.1416015625,237.37158203125,51.59539794921875,578.5836181640625,480.72747802734375,133.35000610351563,0.0,427.8106689453125,292.0931701660156,118.81458282470703,34.85047149658203,48.10995101928711,317.3188171386719],[289.9429016113281,29.940914154052734,283.58013916015625,522.5332641601563,328.88299560546875,21.404468536376953,144.9403076171875,294.7574768066406,542.6959228515625,39.80388259887695,0.0,277.4481201171875,344.23199462890625,400.5013122558594,261.291015625,417.19378662109375],[246.73165893554688,480.8538513183594,474.3553161621094,137.09371948242188,266.6170654296875,441.81341552734375,178.04946899414063,493.87481689453125,321.55755615234375,447.8287048339844,132.25660705566406,0.0,598.4675903320313,195.58702087402344,514.1093139648438,154.39248657226563],[55.33924865722656,493.1473388671875,317.0562744140625,170.9210662841797,138.06414794921875,218.4690399169922,213.34619140625,319.8687744140625,223.04310607910156,99.0023422241211,54.549720764160156,170.64219665527344,0.0,398.5270690917969,449.4154052734375,487.51336669921875],[391.6927795410156,264.591552734375,241.1332244873047,297.80145263671875,242.81507873535156,510.2083435058594,411.347900390625,560.9168701171875,73.83235168457031,407.8707580566406,463.3819885253906,566.5651245117188,204.8097381591797,0.0,13.694512367248535,40.67295837402344],[266.3017578125,482.95379638671875,251.57232666015625,471.4652404785156,214.6371307373047,382.2000427246094,94.41663360595703,383.8544921875,540.4373779296875,390.12359619140625,209.5383758544922,331.80560302734375,480.8057556152344,370.5046081542969,0.0,453.93743896484375],[464.98651123046875,188.6639862060547,447.35528564453125,172.0170440673828,278.3719787597656,383.2669677734375,262.7256774902344,204.7328643798828,96.01773834228516,512.75537109375,476.2604675292969,423.23651123046875,387.2073974609375,438.5225524902344,147.1442413330078,0.0]]],"layer_filaments":[[1,2,3,4,5,8,13],[1,2,3,4,5,8],[1,3,4,5,8],[1,3,4,5,7],[1,4,5,7],[1,4,5],[4,6],[4,6],[2],[2,13],[2,3],[2,3],[3,13],[3,13],[11],[11],[11],[3,11],[3,11],[5,11],[5,11,12],[11,12],[11,12],[11,12],[6,11,12],[6,11,12],[1,6,11,12],[1,11,12],[1],[0,3,4,5,7,8,11,13,15],[0,3,4,5,7,8,11,15],[0,3,4,5,7,8,11,15],[3,8],[2,3],[2,3,11],[1,14,15],[1,14,15],[14],[3,14],[3],[3],[5,11,12,13],[11],[1],[1,8],[1,8],[13],[13],[11],[2,4],[0,1,3,6,9,12,13,14],[0,1,9,12,13],[0,1,9,12,13],[1,9,13],[1,5,9],[1,5,9],[1],[1,7],[1,7],[1,7,9,10],[1,6,10],[0,3,10,14,15],[0,10,14,15],[4,10,14,15],[1,10,14,15],[1,14,15],[1,14,15],[1,14,15],[1,13,14,15],[1,13,14,15],[14],[7,14],[7,14],[7,14],[7,14],[7,14],[14],[6],[6,10],[2,6,10],[6,10],[6],[6],[6,8],[6,8],[6,8],[8,9,10,14,15],[9,10,14,15],[9,10,12],[4,9,10],[9],[11],[11],[8,11],[8],[8],[8],[9],[9],[9],[7,9],[7,9,13],[9],[3,4,5,6,8,12,15],[3,8,12],[0,3],[0,3],[0,6],[0,1,6],[1],[1],[1],[1],[1],[1],[0,1],[0,1,14],[0,1,14],[1,14],[14],[2],[2,5],[2],[2],[3,13],[3],[3,7],[3,7],[3,7],[3,7],[3,7],[1,3,7],[1,7],[3,12,14],[3,14],[3,7,14],[3,7,14],[3,7,14],[3],[3,5],[3,15],[3,15],[3,4,15],[4,15],[15],[12,15],[12,15],[12,15],[11,15],[15],[15],[15],[12,15],[12,15],[15],[8],[8],[8,15],[15],[15],[2],[2],[12],[12],[1,12],[12],[9],[3],[3],[3],[13],[13],[6,13],[11],[1],[1],[1,9],[9],[12],[12],[12],[3],[3,4],[3,15],[3],[3],[2],[15],[15],[1,3,7,12,15],[1,3,5,7,15],[1,3,7],[3,7],[3,7],[2,3,7],[2],[2],[1,3,4,6,7,9],[1,7,9],[1,5,7,9],[1,5,7,9],[7,9],[4,7,9],[3,4,9],[3,4,8],[3,4,8],[3,4],[4],[2,3,7,8,9,11,13,14,15],[2,7,8,9,11,14],[2,7,8,9,11],[7,8,9,11],[7],[7],[7],[11],[11],[12],[1,6,7,8,10],[1,2,5,7,13,14],[2,13,14],[2,13,14],[2,13,14,15],[15],[15],[3],[3],[3],[3],[3,7],[7],[7],[7],[1],[13],[13],[14],[11],[11],[11],[11],[10],[0,10],[0,9,10],[0],[0],[0],[0],[0,5],[0,5],[0,5],[0,5,14],[0,14],[0,14],[14],[14],[14,15],[14,15],[9,15],[11,15],[1,15],[1,2,5,6,7,10,11,13,14],[1,5,6,10,11,13,14],[5,6,11,13],[5,6],[5,6],[5,6],[6],[1,6],[1,13],[1,10,13],[13],[13],[4],[4],[4],[4,9],[4,9],[4,7,9],[4,7,9],[7],[8],[8],[8],[11],[11],[11],[11],[2,3,5,7,9,10,12,14,15],[7,9,10,15],[7,9,10,15],[9,10,15],[5,9,15],[9,12,15],[9,12,15],[4,9,15],[4,9],[4,9,12],[9,12],[6,12],[1,3,5,6,9,10,11,12,14],[5,6,9,10,11,12,14],[5,6,9,10,12],[5,9,12],[5,9,12],[5,9],[5],[5],[5],[5],[5],[5],[5],[5],[5],[9],[9],[9],[9,14],[9,14],[9,14],[9,14],[9],[9,12],[9,12],[9],[5],[5,13],[0,1,4,5,7,8,15],[0,1,5,7,8,15],[0,5,7,8,15],[0,5,7,8,11,15],[1,5,7,8,11],[1,5,11,13],[1,5,11,13],[5],[8],[8],[8,13],[8,13],[2,13],[13],[13],[13],[13],[1],[1,15],[1,15],[6],[6],[2,6],[2],[2,3,5,6,7,8,12,15],[2,5,8,12,15],[2,5,8,15],[5,6,8,15],[0,5,15],[0,5,8],[0,5,8],[5,8,9],[8],[8],[6,8],[8,12],[8,12],[8,12],[8],[5],[5],[5],[11],[9,11],[9],[9,12],[9,12],[5],[5,7],[3,5,7],[3,5,7],[1,5,7],[1,5,7],[1,2,5,7],[1,5,12],[5,12],[2,5,12],[2,5,10,12],[2,10,11],[10],[10],[2],[2,10],[1,2,10],[1,10],[4,10],[4,8,10],[4,10],[4,10],[6,15],[15],[1],[1,9],[1],[1],[1],[8],[0,1,3,7,8,9,10,15],[0,1,3,9,15],[0,2,4,7,13],[0,2,4,15],[0,2,4,15],[10,15],[15],[9],[9,13],[13],[2,4,6,8,10,11,14,15],[2,8,10,14,15],[3,5,6,9],[3,5,6,9],[3,5,6,9,14],[3,5,6,9],[3,6,9],[0,1,6,7,10,13,14],[3,10],[3,9,10],[3,10],[3,10],[3,10],[10],[10],[10],[10],[10,13],[8,10,13],[10,13,15],[10,13,15],[2,3,4,5,6,7,8,14,15],[2,3,4,5,6,7,8,14],[2,4,5,6,7,8,14],[2,6,7,8,12,14],[2,6,7,8,12,14,15],[6,7,12,15],[12,15],[15],[15],[15],[3],[6],[6],[12],[12,15],[6,12,15],[2,6],[2,6],[1,2,6],[2,6],[2,6],[8,10,15],[8,10,15],[15],[15],[15],[15],[15],[5,8,14],[5,14],[5],[15],[15],[12],[12,13],[12,13],[12,13],[12,13],[12],[6,8,14],[6,14],[4,5,14,15],[4,5,14,15],[5,14,15],[5,14,15],[5,14,15],[1,3,4,5,6,8,9],[1,2,3,4,5,8],[4],[4],[0,4],[0,1,4],[0,2],[0,2],[2],[1,3,8,14],[1,7,8,10,12],[1,7,12],[1,12],[1],[1,5],[1,5],[1,5],[1,5],[1,5],[1,5,11],[1,5,7,11],[1,5,11],[1,5],[1,5,12],[1,12],[1,12],[1],[1],[1],[4,7,8,10,12,13,15],[10,12,13],[12],[11,12],[11,12],[12],[12],[5,12],[5,12],[10,12],[11],[13],[13],[9],[1],[0,3,5,8,10,11,14,15],[0,1,3,5,11,14,15],[3,4,6,7,10,13,15],[3,4,6,7,13,14],[6,13,14],[1,4,8],[1,4],[4],[4,14],[0],[3,6],[3,6],[3,6],[6],[6],[6,8],[6],[6],[2,6],[2,4,6],[4],[1,3,7,15],[1,4,7],[1,7],[1,7],[1,7],[1,7],[1,3,7],[1,3],[0,2,3,7,9,10,11,13,15],[0,2,3,7,9,11,12,13,15],[0,2,3,11,12,15],[0,2,3,11,12,15],[9,11,12,13],[9,11,13],[7],[14],[14],[8],[6],[2],[2],[2],[2],[2],[0],[8],[3,5,7,8,12,14],[5,7],[5],[5],[11],[0,3,4,5,6,9,10,12],[3,4,6,9,12],[3,4,6,9,12],[3,4,9,12],[0,6,11,14],[0,3,7,10,11,13,14,15],[3,7,10,11],[3,10,11],[3,10],[3],[2],[2],[5],[5],[5],[6],[6],[15],[15],[12],[6],[15],[3],[3,8],[3,8],[3,8,11],[3,8,11,14],[11,14],[11,14],[11,14],[11,14],[0,11,14],[11,14,15],[11,14],[11,14],[11],[11],[11],[11],[11],[11],[11],[8,11],[3,8],[3,8],[8],[2],[2],[2,10],[0,1,2,7,10,12,14],[0,1,2,7,14],[1,2],[2],[2],[2,15],[2,10],[2,10],[10,15],[10],[10,11],[10],[6],[13],[7],[7],[5],[5],[5],[5,6],[6],[6],[6],[12],[12],[8],[1,2,6,8,9,12,13,14,15],[2,6,8,9,10,13,15],[1,2,6,9],[1,6,9],[1,3,6,9],[1,3],[1],[1],[1],[1,14],[1,14],[7,8,12,13],[0,7,8,12,13],[5,7,8,9,10,11,14,15],[5,7,8,9,11,15],[8,9,15],[9,15],[9],[9],[9,12],[9,11,12],[5,11],[5,11],[5],[8],[1],[1],[3,5,12],[3,5],[3],[3,11],[8,11],[8,11],[8],[4],[4],[4],[4,14],[4,14],[3],[5,6,10],[9,14],[9,14],[1,9,14],[14],[14],[14],[9,14],[9],[9],[8],[8],[10],[0],[0],[0],[9],[9],[7],[7],[7,14],[7,14],[4,7,14],[1,4,7,14],[1,4,7,14],[1,4,7],[1,4,7],[1,4,7],[0,1,7],[1,7],[1,7],[1],[3],[3],[2],[3],[3],[14],[14],[15],[1,15],[1,15],[0,2,4,12,13,14],[0,2,7,12,13,14],[2,7,12,14],[2,12],[2,12],[2,8,12],[2,8,12],[2,8,12],[1,8],[0,1],[0,1],[1,15],[6,10],[6],[4],[0],[0],[3],[6],[6],[6],[6],[6],[6],[6],[6],[6],[11],[1,7,15],[3,4],[3,4],[4],[2,8,9,12],[2,8,9],[9],[9],[9],[9],[8],[5,8],[0,2,6,12,13],[2,6],[6,7,10,13,14],[4,6,13,14],[4,13,14],[4,13,14],[4,14],[4,14],[4,14],[4],[3,11],[1,7,8,10,11,12,13,15],[1,7,8,10,11,12,13],[5,8,11,14],[5,11,14],[5,14],[14],[12],[0,1,6,9,10,12,13,14,15],[3,6,7],[3,6,7],[6,7],[7],[7],[1,2],[2],[5],[5,12],[10],[10],[0,6],[6],[6],[12],[12,14],[12,14],[2,3,11],[1,9,10,11,14],[1,9,11,14],[9,14],[9,14],[9],[0,2,3,4,5,6,9,10,12],[0,2,3,5,6,10,11,12],[2,3,5,8,10,11,12],[3,5,8,10,12],[0,1,3,5,7,9,10,14,15],[7,8,12,15],[0,1,6,7,8,13],[6,7,8,11],[6,8,11],[11],[4],[1],[15],[7,15],[7,14,15],[7],[2],[2],[2],[12],[12],[8],[1,2,3,5,8,9,14,15],[1,2,3,4,5,8,9,14,15],[2,3,4,9,14,15],[0,1,5,7,10],[0,7,10],[7,10],[8,10],[8,10],[2,7,8,11],[2,8],[2],[2],[2],[2],[15],[15],[8],[6,8],[6,8,14],[14],[2,7,11,13,14],[7,11,13,14],[7,11,13,14],[7,11,13],[1,5,7,8,9,11,13,14],[1,7,8,9,11,13,14],[7,8,13,14],[7,8,13,14],[7,8,13,14],[5,8],[5],[5,14],[14],[3,6,13],[3,6,13],[1,4,6,7],[1,4,6],[1,4,6],[6,12],[3,6,12],[3,6,12],[6],[6,12],[0,5,7,9,10,14],[0,5,7,10,14],[0,7,10,14],[2,11,14],[11,14],[0,6,7,9,12,15],[0,6,7,9,15],[0,7,15],[7,15],[2,7],[8],[8],[4],[12],[12],[13],[13],[13],[13],[13,14],[13],[13],[13],[0],[6,8,11,13],[6,8,13],[8,13],[13],[13],[13],[13],[9],[9],[12],[0,1,2,4,5,6,9,11,15],[2,4,5,6,9,11,15],[2,5,6,8,11,15],[5,6],[5,6],[5,6],[2,3,4,5,8,10,13,15],[2,3,4,8,13,15],[4,8,11,13,15],[2,8,11,13],[2,3,8,11,13],[7,8,11,13],[8,11,13],[1,9,13,14,15],[1,6,9,13,14,15],[1,9,13,15],[1,9,13,15],[1,9,13],[9,13],[9],[4,9],[4,5],[4,5,11],[9],[5],[5,12],[5,12],[0],[8],[8],[8],[8],[4,8],[4,8,11],[8,11],[11],[14],[14],[14],[14],[14],[2,14],[0,2,14],[0,2,12,14],[0,2,5,14],[2,3,5,14],[2,5,14],[5,14],[5,14],[5,14],[3],[8],[0,8],[0,8],[8],[8],[5],[13],[0,1,3,5,9,12,13,15],[0,1,3,12,15],[1,3,12,15],[1,3,14,15],[14,15],[14,15],[14,15],[14,15],[14],[2],[2],[1],[3,5,8,9,13,15],[3,5,8,9,13],[5,8,9],[9],[9],[9],[9],[9,14],[0,2,4,6,7,13,15],[0,2,6,7,13],[0,2,7],[0,2],[0,2,4],[0,2,4],[0,2,4,14],[1,3,4],[1,4],[1,5],[1,5],[1],[4],[4],[0,2,7,8,10,12,13,14],[8,10,12,13,14],[8,10,13,14],[10,13,14],[10,14],[10,14],[10],[10],[6,10],[6],[1],[1],[1],[1,2],[1,2],[1,2,8],[2,7,8,13],[2,7,13],[2,7],[2,9],[4,6,11],[4,6,8,11],[4],[0],[5],[5],[5,9],[6],[9],[6,8,13,15],[6,8,13],[2,6,8,13],[2,8],[8],[8],[8],[1],[6],[4,6,7,10,12],[4,6,7,8,10,12],[1,7,12],[1,12],[1,10,12],[1,12],[11],[11],[11],[12],[6,12],[2,8,10,11,12,14,15],[2,8,10,11,12,14,15],[2,8,10,11,12,15],[5,14],[14],[10],[0,10],[10],[10],[10],[5],[5],[5,11],[11],[11],[11],[11],[11],[11],[11],[11],[11],[11],[1],[0,2,3,6,7,8,12,14,15],[0,6,7,8,14,15],[6,7,8,14,15],[0,14],[0,1,2,4,9,14,15],[0,2,4,14,15],[0,15],[0,15],[0,8,15],[1,13,14],[1,14],[1,12],[10,12],[12],[10],[10],[10],[0,5,9,10,12],[0,9,10,12],[0,9,10,12],[5,15],[5,6,15],[5,6,15],[5,6,15],[5,15],[1,3,6,7,8,9,13],[1,3,6,8,9,13],[1,3,8,9,13],[1],[1],[1],[11],[11],[6,11],[6,11],[6],[6],[6],[2],[13],[5,13],[3,5,13],[0,3,5,13],[0,3,5,13],[0,3,5],[0,3,5],[5],[2,3,5,8,14],[3,5,8,14],[3,5,8,14],[3,5,8,14],[2,4,5,6,7,8,9,10],[5,6,7,8,9,10],[0,3,4,6,7,8,11,14,15],[0,3,4,5,6,11,14,15],[3,4,5,11,14,15],[4,11,13,15],[4,15],[4,6,15],[4,6,12],[12],[12],[12],[9,11,12,13],[6],[0,1,3,4,7,11,12,14],[4,7,11,14],[7],[7,12],[12],[12],[12],[10,12],[6,12],[6],[6],[10],[13],[0],[3],[0],[14],[14],[14],[13,14],[13],[2],[2],[2,13],[2,13],[5],[5],[5],[5],[5],[13],[10,13],[6],[6],[5],[5],[5],[5,11],[5],[3,4,5,8,9,10,11,14,15],[4,8,9,14,15],[4,12,15],[4,12],[11,12],[11],[11],[0,3,4,5,6,7,10,11,15],[0,3,4,6,10,15],[2,5,7,9,11,12,15],[3,5,7,9,11,12,15],[1,5,7,12,15],[3,5,7,12,15],[3,5,7,12,14,15],[3,5,7,12,14,15],[0,1,4,5,12],[2,7,11],[2,11],[2,15],[15],[2,15],[2,15],[2,9,15],[2,5,9,15],[2,5],[2],[1,3,12,13,14,15],[1,3,12,13,14,15],[1,13,14],[1,13],[1,13],[1,13],[13],[13],[1,13],[1],[10],[10],[10],[10],[1,8],[1],[6,7,8,9,11,12,14],[7,9,12,14],[4,7,9,12],[4,7,9,12],[4,7,9,11,12],[11,12],[11,12],[9],[8],[8,11],[7,8,11],[7,8,11],[7,11],[7,11],[7,11],[7,11],[7,10,11],[7,10,11],[10,11],[10,11],[11],[11],[11],[11],[11],[5],[2,5],[2,5],[2,5],[2,5],[2],[9],[5],[2,5,6,9,12],[5,6,9],[5,6,8,9],[8,9],[6,8,9],[6,8,9],[6,8,9],[1,5,6,8,11,13,14],[1,5,6,8,11,14],[1,6,8,9,14],[6,8],[6],[6],[2],[2],[0,2,3,4,5,9,11,12,15],[2,3,4,5,11,12,15],[2,3,4,5,10,11,12,15],[2,3,4,9,10,11,12,15],[2,4,10,11,12,15],[2,4,15],[2,4],[2,14],[2,10,14],[4,5,9,10,11,12,13,15],[4,5,9,11,13],[4,5,9,11,13],[5,9,11,13],[5,9,11,13,15],[9,13,15],[13,15],[13],[13],[6,13],[1],[1],[1],[1],[7],[4],[4],[4],[4],[4],[1,4],[15],[3],[3],[3],[2,12,14],[0,1,2,3,4,12,13,14],[0,1,3,4,13,14],[0,1,13,14],[0,1,9,13,14],[0,9,13],[0,4,9],[0,4,7,9],[0,4,7,9],[0,4,7,9,15],[3,4,7,9],[1,4,5,8,12],[0,1,4,5,8],[0,1,8],[0,1,8],[0],[0],[0,4,7,15],[0,4,7,15],[8,10],[8,9,10],[8],[8],[0,8],[0,8],[8],[0,2,4,9,10,12,13],[2,4,9,12,13],[4,6,9,12,13],[0,4,12,13],[4,12,13],[4,13,15],[4,12],[4,12],[4,5,12],[4,5,12],[4,5,12],[4,5,12,13],[5,12,13],[5,11,12,13],[0,4,5,9],[9],[9],[9],[9],[9],[9],[9],[9],[9],[9],[2,9],[2,9],[2],[2,15],[2],[7],[7],[7],[7],[9],[3,7],[3,7],[7],[4,7],[4,7],[4,7,10],[4,7,10],[7],[4,7],[4,7,9],[2,3,4,5,6,10,11,14],[2,4,5,6,14],[2,5,6,14],[5,6,13,14],[2,6,14],[2,6],[6],[1,4,10,14],[1,6,10,14],[10,14],[14],[2,14],[2,14],[2,10,14],[2,14],[2,14],[2,14],[2],[2,15],[2,15],[15],[15],[7,15],[15],[1],[1,10],[3],[0,4,6,8,9,11,12,15],[0,2,6,8,9,11,12,15],[0,2,8,9,11,12,15],[0,2,8,9,11],[2,9,11],[11],[9,11],[0,2,4,6,10,13,14],[2,4,6,10,13,14],[1,2,4,6,10,13,14],[1,2,4,6,10,13,14],[1,2,4,13,14],[1,2,13],[13],[7],[2,3,4,10,12],[4,10],[0,4],[4],[4],[4],[4],[0],[0,3],[0],[0,4,8,9,13],[0,8,9],[0,9,14],[9,14],[0],[12],[12],[6],[0,1,2,3,13],[0,1,3,13],[1,3,13,15],[3,15],[15],[1,15],[6],[6,11],[7,11],[11],[9],[11],[0,1,2,7],[0,1],[0,1],[1],[1],[8],[8],[4],[4],[12],[12],[12],[12],[14],[2,5,6,8,9,10,11,13,14],[2,5,6,9,12,14],[2,5,6,9,12,13],[2,5,6,9,12,13,15],[2,6,9,13,15],[12,13],[12],[8,12],[8,15],[15],[10,15],[10,15],[10],[10],[0,10],[0,1,6,9,11,13,14,15],[0,1,6,9,11,13,14],[1,4,9,14],[9],[9],[2],[2,14],[2,13,14],[2,13,14],[2,11,13,14],[2,9,11,13],[2,9,11],[5,9],[3,4,9,14],[3,4,5,9,14],[3,4,9,11,14],[0,1,2,8,11,12,13,14,15],[1,8,11,12,13,14,15],[1,11,12,13,14,15],[1,11,12],[11,12],[2,15],[15],[0,15],[5,15],[5,15],[5,15],[5,12,15],[5,11,12,15],[2,5,11,12],[5,11],[2,5,8,10,11,12],[5,8,9,10,11],[5,8,9,10,11,13],[2,9,10,11,13],[9,10,11,13],[0,3,4,5,8,10,12,13],[3,4,8,12,14],[12,14,15],[0,3,4,7,11,13,14,15],[7,11,13,14],[7,13,14],[7,13,14],[0,4,14],[0,4,14],[0,4,14],[4,14],[4,14],[4,14],[2],[10],[10],[1,2,3,5,7,8,9,12],[2,3,5,7,9,12],[2,5,7,9],[5,7,9],[7],[6],[6],[6],[5],[13],[0,1,2,3,5,8,10,14],[1,3,10,14],[1,3,10,15],[1,15],[1,2,15],[1,3,15],[15],[10,15],[2,5,6,12,14],[2,5,6,14],[2,14],[1,12,13],[1,12,13],[12],[12],[4],[4],[7],[14],[6],[6],[10],[1,2,6,9,11,12,14,15],[6,9,11,12,14,15],[6,12,14,15],[12,14,15],[12,14,15],[14,15],[14,15],[3,14,15],[4,5,8,11,13,15],[1,4,5,8,11,13],[1,4],[4],[4,9],[1,5,7,10,11,12,14,15],[0,1,7,12,14,15],[1,11,12,14,15],[1,11,14,15],[11,14],[11,14],[6,11,14],[6,11],[6],[14],[7,8,9,11],[8,11],[4],[4,14],[4,14],[4,14],[4],[6],[6],[12],[12],[12],[12],[12],[3,11,15],[3,7,11,15],[6,7,11],[8,12],[8],[8],[8],[8],[8],[8],[8],[1,8],[8,11],[8,11],[8,11],[1,4,5,8,13],[1,4,8,13,14],[1,4,8,13],[1,4,8,13],[1,4,8,13],[1,4,8,13],[1,4,8,13,14],[1,4,8,13],[1,4,13],[1,4],[2,4,6,8,14],[2,4,6,8,11],[2,6,11],[2,6,11,12],[6,11,12],[6,11,12],[11,12],[11,12,14],[11,12,14],[11],[2],[3],[3,9],[9],[4,7,9,11,13,14],[4,10,11,13,14],[4,10,11,14],[4,10,11,14],[10,11,13],[3,10,13],[10],[10],[10],[10],[10,12],[8],[7],[7],[4],[1,4,5,10,12,15],[10,12,15],[10,12,15],[10,12],[8,10,12],[8,10,12],[8,12],[8,12],[7,8,12],[12],[12],[12],[2],[0],[13],[13],[3,13],[3,8,10,12],[3,8,10,12],[2,3,8,10,12],[2,3,8,10,12],[2,3,8,15],[4,8,15],[2,4,8,15],[2,4,8],[2,4],[4,10],[4,13],[8],[0,1,10,13],[0,1,10,13],[0,1,10,13],[1,10,13],[1,2,3,4,5,7,10,11],[1,3,4,5,7,10,11],[1,5,7,10,11],[5,7,10,11],[7,11],[11],[11],[11],[10,11],[10,13],[1,13],[1,8,13],[1,12,13],[1,12,13],[12,14],[12,14],[12],[11],[11,13],[3],[3,4],[3,4,6],[3,4,6],[3,6],[3,6,11],[1,4,9,10,11,12,13,14,15],[4,10,11,12,13],[1,10,11,12,13],[3,4],[4,7],[4,7],[4,7],[7,9],[3,7],[3,7],[7],[7],[7],[0,7],[6,7],[7],[2,3,5,9,10,12,14,15],[2,3,5,9,14,15],[6,9,15],[2,6,13,15],[2,6,13,15],[2,3,7,10,11,13,14,15],[4,7,15],[4,15],[15],[15],[15],[15],[15],[4,15],[8,11],[0,2,3,8,9,10,11,15],[0,2,3,9,10,11,15],[2,3,10,13,15],[10,13,15],[11,15],[11,15],[12],[4],[4],[1,4],[1,4,11],[1,4,10,11],[1,10,11,14],[1,9,10,11,14],[10],[5],[5,11],[11],[11],[11],[11],[11],[11],[2],[4],[4],[6],[6],[6,11],[11],[10],[5,10],[5,10],[5,10],[5,10],[5,8],[5,8],[5,8,11],[8,11],[11],[10,11],[10],[5,10],[10,14],[10,14],[10,14],[2,5,7,8,9,13,14],[2,8,14],[3,4,6,9,10,11],[3,10],[3,5,10],[3,5],[3],[1,2,4,5,6,9,11,12,14],[5,6,9,11],[5,9,11],[5,11],[5,9,11],[1,2,6,7,8,9,11,12,13],[1,2,6,8,9,11,12,13],[1,2,6,8,11,12,13],[1,2,7,8,11,12,13],[2,8,13],[2,8,13],[2,8,13],[8,13],[6],[6],[6],[3,6,8,14,15],[3,13,15],[3,15],[3,13,15],[3,6],[6],[8],[2,3,4,7,9,10,11,14],[3,4,7,8,9,10,11,14],[0,4,7,8,9,11,14],[4,7,8,9,14],[0,4,8,14],[4,5,8,9,10,11,13,14,15],[4,5,9,10,11,13,14,15],[4,5,9,11,14,15],[4,5,9,11,14,15],[1,9,11,14,15],[1,9,11,15],[9,11,15],[9,11,15],[9,11,14,15],[2,9,11,14],[2,4,11,14]],"unprintable_filaments":[[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0,1,2,3,4,5]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":0,"group_id":2,"volume_type":2},{"diameter":"0.4","extruder_id":0,"group_id":3,"volume_type":3},{"diameter":"0.4","extruder_id":0,"group_id":4,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":5,"volume_type":1}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"C","id":"C_stress_66","seed":30066}} \ No newline at end of file diff --git a/tests/filament_group/golden/config_c/stress_79.json b/tests/filament_group/golden/config_c/stress_79.json new file mode 100644 index 0000000000..316a2831b0 --- /dev/null +++ b/tests/filament_group/golden/config_c/stress_79.json @@ -0,0 +1 @@ +{"base_result":{"constraints_ok":true,"flush_cost":188809,"full_score":99786.7624},"context":{"group_info":{"filament_volume_map":[2,2,2,2,2,2,2,2,2,2,2,2,2,2],"has_filament_switcher":false,"ignore_ext_filament":false,"max_gap_threshold":0.01,"mode":0,"strategy":0,"total_filament_num":14},"machine_info":{"machine_filament_info":[[{"color":"#1818B5FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#242DAFFF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#8FAB47FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1},{"color":"#730315FF","extruder_id":0,"is_extended":false,"is_support":false,"type":"PLA","usage_type":1}]],"master_extruder_id":0,"max_group_size":[14],"prefer_non_model_filament":[false]},"model_info":{"filament_ids":["GFL_0","GFL_1","GFL_2","GFL_3","GFL_4","GFL_5","GFL_6","GFL_7","GFL_8","GFL_9","GFL_10","GFL_11","GFL_12","GFL_13"],"filament_info":[{"color":"#C454A5FF","is_support":false,"type":"PLA","usage_type":1},{"color":"#8A280EFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#99B981FF","is_support":false,"type":"PA","usage_type":1},{"color":"#4F4EEDFF","is_support":false,"type":"PA","usage_type":1},{"color":"#3B848BFF","is_support":false,"type":"PETG","usage_type":1},{"color":"#92EBB0FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#D7D54FFF","is_support":false,"type":"PLA","usage_type":1},{"color":"#4908A9FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#E52D79FF","is_support":false,"type":"ABS","usage_type":1},{"color":"#077562FF","is_support":false,"type":"TPU","usage_type":1},{"color":"#3AF9ACFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#E06495FF","is_support":false,"type":"PA","usage_type":1},{"color":"#AEBEACFF","is_support":false,"type":"TPU","usage_type":1},{"color":"#17620CFF","is_support":false,"type":"PA","usage_type":1}],"flush_matrix":[[[0.0,507.8175354003906,12.282039642333984,458.6227111816406,151.99313354492188,41.9571418762207,481.5407409667969,84.34210205078125,476.7975158691406,533.977294921875,289.3343505859375,253.70343017578125,519.951171875,38.62238311767578],[73.79644012451172,0.0,374.6180725097656,552.4855346679688,75.35685729980469,188.3751983642578,55.848392486572266,457.86541748046875,247.13882446289063,115.25961303710938,189.31077575683594,246.9374542236328,539.9744262695313,264.8404541015625],[264.5006103515625,118.5875473022461,0.0,566.7469482421875,14.153543472290039,109.0737075805664,454.4181213378906,108.54997253417969,466.4681091308594,522.0209350585938,518.3394775390625,571.572509765625,124.19403839111328,380.1978759765625],[440.6690979003906,489.7338562011719,581.3970336914063,0.0,24.283815383911133,466.5624084472656,38.613380432128906,304.7287292480469,567.1316528320313,593.2388305664063,309.55950927734375,422.9061279296875,18.652530670166016,70.66016387939453],[65.31436157226563,465.73638916015625,92.28398132324219,461.3265075683594,0.0,106.87614440917969,91.8896255493164,558.3407592773438,59.85609817504883,482.4892883300781,217.8892059326172,301.2346496582031,580.7737426757813,369.61541748046875],[85.37371826171875,526.1563720703125,61.08623123168945,177.25234985351563,369.93829345703125,0.0,434.1587829589844,85.04975891113281,573.1224365234375,546.1277465820313,31.582847595214844,54.758750915527344,478.6239013671875,536.4218139648438],[488.75054931640625,585.7280883789063,115.05328369140625,15.230630874633789,103.4936294555664,286.1462097167969,0.0,491.2708435058594,132.85693359375,469.4877014160156,344.30718994140625,516.8123779296875,103.40480041503906,99.40608978271484],[46.94160461425781,446.26214599609375,587.1228637695313,588.1201171875,564.0452880859375,210.57479858398438,448.9099426269531,0.0,25.0284366607666,292.4790344238281,19.416879653930664,306.29522705078125,375.7415771484375,324.88555908203125],[270.2590637207031,276.18096923828125,438.46234130859375,587.2749633789063,450.7281799316406,574.2225341796875,39.95879364013672,487.3291015625,0.0,347.0226135253906,77.09314727783203,278.0384216308594,588.56494140625,47.08266067504883],[568.7543334960938,486.5984191894531,12.514281272888184,282.7850036621094,121.19220733642578,36.03042221069336,89.54720306396484,441.6962585449219,234.33749389648438,0.0,444.839599609375,388.8111267089844,98.14652252197266,12.461390495300293],[277.8235778808594,210.00161743164063,534.9747924804688,72.15264129638672,464.4512634277344,190.87738037109375,206.89056396484375,281.5173645019531,480.6430358886719,445.0953674316406,0.0,356.1513977050781,337.17523193359375,117.91357421875],[74.55474090576172,73.66073608398438,190.5296173095703,499.7807312011719,227.67930603027344,77.03294372558594,173.46502685546875,310.28369140625,69.92254638671875,386.5397033691406,548.3720092773438,0.0,219.50723266601563,46.78370666503906],[439.58966064453125,125.4782943725586,540.2744750976563,217.459228515625,72.90486145019531,253.74099731445313,471.8619384765625,561.8896484375,549.1911010742188,475.2398376464844,429.5606689453125,374.4393615722656,0.0,285.8063049316406],[221.6659393310547,507.56805419921875,433.44476318359375,196.56707763671875,317.6894836425781,547.0717163085938,210.13377380371094,216.10325622558594,78.3891830444336,576.9972534179688,517.0712280273438,586.732177734375,447.4285583496094,0.0]]],"layer_filaments":[[2,3,4],[0,12],[12],[13],[1,13],[1,13],[1,13],[1,5,13],[1,5,9,13],[1,13],[1,2,3,8],[1,2,3],[2,3],[2,3],[2,3],[6],[6],[6],[10],[13],[13],[13],[2],[2],[2],[2],[2],[5],[5],[5],[9],[11],[9],[9],[5],[2,5],[2,5],[2,5],[2,5],[5,12],[4,5,6,12],[4,6],[4],[0,1,5,7,10,11,12],[0,1,11,12],[0,11],[9],[7],[10],[10],[10],[10],[4],[3,4],[3,4,13],[3,13],[3,13],[2],[2,10],[2,6,10],[2,6,10],[6,12],[0],[4,6,7,8,9,10],[6,7,9,10,11],[10,11],[6,10,11],[10],[4],[4],[2],[2],[12],[12],[2,4,9,10,11,12,13],[2,4,9,12],[2,4,12],[12],[12,13],[12,13],[6,10],[1,6],[1,6],[4,7,10,12],[4,7,9,10,12],[4,10,12],[4],[4],[4],[4,5],[4,5],[11],[2,11],[10,11],[7,10,11],[7,10],[2,9,12,13],[2,3,12,13],[2,12,13],[7,8],[1,3,4,7,8,9,13],[4,7,8,9,13],[8,9,13],[8,9,13],[8,9,13],[8,9],[10],[4,10],[0,4,10],[4,10],[4,10],[4,5],[4,5],[4,5,7],[4,5],[0,1,2,5,7,9,12],[5,6,7,9],[5,7,9],[0,1,6,7],[0,1,6,7],[1,7],[1,7],[1],[1],[2],[2],[3,4,6,7,8,10,13],[0,4,8,10],[4,8,10],[4,8,12],[8,12],[8],[11],[11],[11],[11],[0,1,4,6],[1,4,6,9],[1,4,6,9],[1,4],[4],[4,10],[10],[10],[9],[9,10],[3,9,10],[3,9,10],[3,10],[10],[13],[13],[10],[10],[0,3,4,6,10],[0,3,4,6,10,11],[0,3,4,6,10,11],[0,6,10,11],[6,10,11],[6],[3],[3,4,5],[3,4,5],[4,5],[5],[4,5],[4,6,10,13],[4,6,10,13],[1,4,6,10,13],[13],[13],[5,7,8,13],[1,5,7,8,13],[1,13],[0,13],[0],[0,9],[0],[0],[0],[13],[13],[13],[0,13],[0,8,13],[0,8,13],[0,5],[2,11],[2,11,12],[2],[9],[9],[9],[0,1,2,4,5,6,7,12],[0,1,4,5,12],[0,1,4,5],[1,3,4,5],[1,3,4],[1,3,7],[0,1,3,7],[0,1,3],[0,1,3],[3,8],[3],[0,1,2,3,8,10,11,13],[0,1,2,3,7,8,10,13],[1,2,3,10,13],[1,2,10,13],[2,4,10],[2,7,10],[0,2,3,5,6,8,10,12],[0,2,3,6,8,12],[2,3,6,8,11,12],[2,12],[2,12],[2,12],[12],[0,4,7,9],[0,4,7,9,10],[0,3,4,7,10],[0,3,7,10],[0,3,9,10],[0,3],[0,6],[6,12],[12],[2,3,4,12],[2,3,12],[2,3,10,12],[3,10,12],[10],[5],[5],[13],[2,13],[13],[12],[1,4,5,6,11,12,13],[1,4,5,11,12],[1,5,11,12],[0,1,5,11,12],[0,1,5,12],[0,1,12],[0,1,12],[1,2,3,7,9,10,11],[1,2,3,7,9,10,11],[1,2,3,4,9,10],[1,2,9,10],[1,10],[1],[1],[1],[6],[6,13],[6,13],[6,13],[0,2,7,12,13],[0,2,7],[2,7],[2,7],[7],[7],[2,7],[2,7],[2],[2],[5],[5],[9],[9],[9,13],[4,9,13],[9,13],[13],[13],[5,13],[5,13],[11],[11],[10],[3],[3],[3],[3],[3],[3],[3],[9],[9],[9],[4],[4],[4],[2,4],[2,4],[4],[4,5],[4,5],[11],[11],[11],[5,9],[4,5,9],[3,9],[9],[9],[9],[2],[2],[2],[2],[2,12],[2,12],[2,12],[2],[2],[12],[12,13],[8],[8],[8],[4,8],[4],[11,13],[11,13],[8,11,13],[11,13],[11,13],[5,11,13],[5,13],[4,13],[11],[4,11],[4,11],[4,11],[5,9],[9],[9,12],[3,9],[13],[4,13],[1],[1],[8],[0,1,2,8,9,13],[1,5,8,9,13],[1,5,8,9,10,13],[5,8,9,10,11,13],[4,8,11],[8],[0,1,2,3,5,7,9,12],[0,1,5,7,9],[0,1,5,7,9],[0,1,3,5,9],[0,1,3,5,9],[0,1,3,9],[0,1,3,9,12],[0,9,12],[0,12],[0,3,12],[0,3,12],[1,5,8,11,13],[13],[13],[3,5,6,7,8,9,11,13],[3,5,6,8,9,11,13],[3,8,9,10,11],[3,8],[3,8],[8],[0],[0],[0],[0,9],[0,9,13],[0,9,13],[0,13],[0,2],[0,2],[0,2],[0,2,6],[3,4,13],[3,13],[3,13],[3,13],[3,13],[1],[1],[1],[1],[1],[3],[13],[0,13],[0,12],[0,1,12],[1,12],[1],[1,10],[1],[1],[1],[1],[12],[12],[12],[12],[0,7,12],[0,7,12],[7],[7],[6],[6],[4,7],[6],[8],[7,8],[7,8],[7,8],[7],[7,8],[0,4,5,7,9,13],[0,4,5,7,9,11,13],[0,4,5,7,9,11,13],[0,5,9,11,13],[0,5,9,11,12],[5,9],[5,9],[9],[1,9],[1,3,9],[1,9],[1,6,9],[1,9],[9],[9,11],[9],[0],[0],[7],[7],[0,2,3,5,6,8,11,13],[0,2,3,5,6,8],[0,3,5,6,8,10],[5,7,8],[5,7],[1,5],[1],[1],[1],[1],[8],[8],[3],[1],[12],[4,12],[12],[5],[4],[11],[3,11],[3,11],[3,11],[3,11],[3,7,11],[3,7,11],[3,11],[3,11,12],[0,1,2,3,5,7,11],[3,5,7,11,13],[0,3,5,7,11,13],[0,3,4,7],[0,3,4,7],[0,7],[0,7],[0],[0],[8],[1],[1],[4],[4],[4],[12],[12],[2,12],[2,12],[2,12],[2,9],[2,9],[0,1,2,9,11,13],[0,1,2,11,13],[2,11,13],[0,1,2,6,7,12,13],[1,7,12,13],[1,7,10,12],[7,10,12],[7,12],[0,7,12],[0,7,12],[0,7,12],[0,7,10],[0,10],[0,10],[0,10],[10],[11],[11],[11],[3],[13],[13],[9,13],[9,13],[9],[9],[9,13],[3,13],[3],[3],[3],[3],[3],[2],[2],[0,1,3,8,9,11,13],[1,3,8],[0,1,3,8],[1,2,3],[1,2,3],[2,12],[2,12],[2,9,12],[2,12],[12],[12],[11,12],[11],[11],[11],[6],[4],[4,5],[4,5],[5,7],[5,7],[7,13],[5,13],[5],[9],[8,9],[8,9],[9],[7],[0,7],[7],[7],[7],[7],[7],[0],[0],[0],[0,10],[0,10],[0,1,10],[0,1,10],[1],[1],[9],[9],[7,9],[7],[7],[1],[7],[7],[12],[1,3,4,6,11,12,13],[1,4,6,12,13],[1,13],[1,13],[1],[0],[0,10],[10],[3],[1],[6,12],[6],[6,11],[2],[2],[6],[6,11],[6,11],[12],[12],[0,4,11],[4],[4],[4],[4],[0],[0],[0],[0],[0,3],[0,3],[0,3,13],[3,10,13],[3],[3],[3],[1,3],[1],[1],[1,5],[0,5],[0,5],[0,5],[1],[2],[2],[2],[2],[2],[0,2],[0],[0,3],[0,3],[3],[3],[11],[11,12],[1,2,3,5,7,10,11,12],[1,2,5,7,10,11,12],[1,2,5,7,10,11],[1,2,7,10,11],[2,11,13],[1,2,11,13],[2,11,13],[2,3,9,12],[3,8,11],[5,8,11],[8],[7,8],[7],[10],[10],[10],[10],[7],[8],[7],[7],[7],[7],[7,8],[7],[3,7],[7],[8],[3,8],[3,8],[3,8],[3,8],[7,8],[0,7],[6],[6],[13],[5],[5,9],[5,9,10],[9,10,13],[10,13],[13],[5,6,8,9,12],[6,8,9,12],[8,9,12],[8,9,12],[8,12],[8],[8,12],[8,12],[4],[4],[4],[4],[2],[2],[10],[10,13],[13],[13],[6,13],[6],[6,12],[6,12],[6,12],[10,11],[0,10,11],[0,1,10],[0,10],[0,11],[9,11],[3,9,11],[11],[1,7,12],[1,7],[1,7],[7,10],[7],[0,7],[0,7],[0,2,7],[1],[1],[1],[1,6],[9],[9],[4,10],[4],[4,11],[4,11],[11],[5,11],[5],[5],[5],[0],[0],[0],[0,3],[11,13],[4,5,10,13],[4,10,13],[4,6,10,13],[4],[0],[0],[0],[0,13],[13],[12],[12],[12],[8],[8,9],[9],[9],[1,2,3,5,6,7,9,13],[2,3,6,7,13],[2,3],[2,3],[2,3],[2,3],[2],[0,2],[0],[0,1,3,5,7,8,9,10],[3,5,7,8,9,10],[3,5,7,8,9,10,12],[3,5,7,8,9,10,12],[5,7,8,9,10,12],[5,7,8,9,12],[5,7,8,12],[1,5,8],[1,5,8],[1,5],[1,5],[1,5],[5],[10],[1],[1,13],[2],[2],[2],[2],[5],[8],[0,2,3,5,9,10,11,12],[0,3,5,9,11,12],[0,4,5,7,8,13],[4,13],[4,13],[4,10,13],[4,13],[4,13],[1,6,7,11],[1,6,7,11],[2,5],[2],[2],[11],[4],[6],[6],[3],[3],[3],[5],[5],[5],[5,7],[7],[11],[11],[11],[11],[11],[3],[3],[4],[4],[4],[8],[12],[12],[12],[12],[2,3,5],[3,5],[2,3,4,7],[1,2,3,4,7],[2,3,5,7],[2,3,7,8],[2,3,5,7,8],[2,5,7,8,11],[2,5,8],[2,5,8],[2,5,8],[2,5,8],[2,5],[2],[2,7],[1,2,7],[7],[7],[7],[1],[1],[1],[1],[1],[1,5],[5],[11],[11],[9],[2,9],[1,3,5,10,11,12,13],[1,13],[0,1,2,4,6,8,12],[0,1,2,3,4,8],[0,1,2,3,4,8],[0,1,3,4],[0,3,6],[0,3,5,6],[0,3,6,12],[0,6,12],[7],[7],[9],[9],[8,9],[8,9],[8],[9],[3],[11],[1,2,7,10,12],[1,7,8,10],[1,5,6,7,8,9,11],[1,5,7,8,9,11],[1,7,8,9,11],[1,8,9,11],[1,9,11],[1,9,11],[1,9,11],[1,10,11],[1,11],[1,11,13],[1],[1,3],[1,3,12],[4,5,8,9,12,13],[3,4,5,9,12],[3,4,9,12],[4,12],[4,12],[12],[4],[4],[4,7],[11],[6,11],[6,11],[11],[11],[11],[6],[0],[0],[0],[5],[0,2,3,6,7],[0,2,3,6,7],[2,3,6],[2,3],[3],[3,6],[4],[4,5],[4,5],[0,4,5],[0,1],[0],[0],[1],[3],[3],[3],[9],[9],[9],[9],[3,9],[3,11],[3,11],[6,11],[6],[0,7,9,10,12],[7,9,10],[7],[10],[0],[0,11],[0,8,11],[0,8,11],[4,7,9,13],[4,9,13],[0,2,3,4,6,7,9,12],[0,4,6,12],[0,4,12],[0,4,9,12],[0,4],[4],[4],[4],[4],[0,4],[0,2,4],[0,2],[0,2],[0,9],[5,13],[5],[7],[0,5,6,7,9,10,11,13],[0,5,7,9,10,11,13],[0,9,10,11,13],[0,10,11,13],[0,10,13],[0,10,12,13],[0,10,11,12,13],[10,12],[10],[10,13],[7,10],[7],[1],[11],[11],[7,11],[11],[6],[4],[0,2,3,4,7,8],[0,2,3,7],[0,3,7],[0,7],[0],[0,7],[7],[0],[3],[3],[11],[0],[0],[0,1],[0,1],[0,1,10],[0,1],[0,1,7],[0,7],[2,7],[11],[11],[11],[0,2,5,7,13],[0,5,7],[0,3,5,7],[3,5,7],[3,5,7],[3,7],[3,7],[3,12],[3,5,12],[3,5,12],[12],[9],[9,11],[7,9,11],[7,11],[6,7],[6],[6,8],[1,4,12],[0,1],[0,4],[0],[0],[0],[0],[11],[4],[4],[3,4],[3],[0,2,6,7,11],[0,2,6,7],[2,6,7],[0,7,11,12],[1,3,6,10],[1,3,6,10],[0,3,6],[0,2,4,5,7,8,9,13],[2,5,7,8,9,13],[2,3,5,8],[2,5],[2,5],[0,2,6,8,9,10,12,13],[0,5,8,9,12,13],[0,5,8,9,12],[3,5,8,9],[3,5,8],[2,3,5,8],[2,3,5,8],[0,4,6,8,11,12],[0,4,8,12],[0,3,5,6,7,13],[0,2,6,7,13],[0,2,6,7],[0,2,6],[2,6],[2],[2],[2,6],[6],[6],[6],[2],[2],[5],[7],[0],[3,11,12],[12],[3],[3],[3,6],[6],[6],[8],[0,8],[0,8],[0,1,8],[0,8],[0,1,8],[0,1],[0,1],[1],[1],[1],[1,7],[0,1,12,13],[1,12],[1,12],[1,5,12],[1,5,12],[1,5,12],[1],[1],[1],[1,5],[11],[9],[3,4,8,10,11],[3,4,11],[4,7,11],[7],[5],[4],[0,2,3,4,6,9,11,13],[0,2,3,6,9,13],[3,6,9],[1,3,5,6,10,11],[1,11],[1,11],[1],[2],[2],[7],[8],[8],[13],[2],[2,6],[2,6],[1,5,9,11],[5,9],[5],[2,5],[5],[6],[6,10],[6,10,13],[5,6],[5,6],[5,6,10],[5],[5],[3,5],[5,9],[2,3,4,7,8],[7,8],[7,10],[10],[10],[10],[10],[0,4,5,6,9,13],[5,6,9],[9],[9,12],[5,6,9,10,12,13],[5,6,9,11,12,13],[6,9],[6,9],[9,13],[9,13],[9,10,13],[9,13],[7,13],[11,13],[13],[6],[6],[13],[13],[9,13],[9,13],[9,13],[1,2,4,5],[0,1,2],[0,2,11],[0,11],[0,11],[0],[4],[2,5,6,7,8,9,10,12],[2,6,7,8,10,12],[7,8,12],[0,2,3,7,8,10,12],[0,2,6,7,8,10,12],[0,6,7,8],[0,8],[0,8],[3,8],[3,8,11],[4,5,6,8,9],[4,5,8,9],[5,9,11],[5,6,9],[1,6,9],[1,6,9],[1,6,9],[7,9],[7,9,11],[9,11],[3],[3],[3,13],[0,2,4,11,12,13],[2,4,6,12,13],[4,6,9],[0,1,3,4,6,7,10,13],[0,1,3,4,9,10],[0,6,7,9,10,11,12,13],[0,6,7,9,10,11,13],[1,2,3,5,6,8,9,12],[3,6,12],[2,3,6,12],[3,12],[3,12],[3,12],[3,12],[3,12],[6,12],[12],[13],[7],[7],[7,8],[6],[6],[6,12],[6,12],[11,12],[3,11,12],[3,11,12],[1,2,4,11,12],[1,2,4,5,12],[1,4,5,12],[1,12,13],[1,12,13],[1,13],[1,13],[1,13],[1,9,13],[0,1,2,5,10,12,13],[0,1,2,5,10],[2,5,10],[5,10],[5,10],[9,10],[9,10],[9,10],[9,10,13],[8,9,13],[9],[9],[11],[10],[6],[8],[8],[8,13],[8,11,13],[0,1,5,9],[0,5,9],[0,9,11],[0,9,11],[0],[0],[5],[5],[0,5],[5],[2],[11],[9],[9],[1,2,5,12],[1,2,5],[2,5,7,8,9,10,12,13],[5,7,9,10,12],[3,5,7,12],[3,5],[3,5],[3,5],[1,5],[2,5,6,7,8,10,11,13],[2,5,6,8,10,13],[2,5,6,8,10,13],[2,5,6,13],[2,5,6],[3,4,5,11],[3,5,10],[0,3,5,10],[0,3,5],[0,5],[0,3,5],[4,5,7,9,10,12],[5,7,9,10,12],[9,10,12],[9,12],[12],[12],[9],[6],[13],[13],[8,13],[8,13],[2],[2],[2],[2],[7],[7],[7,13],[7],[12],[12,13],[12],[2,12],[2],[2],[6],[6],[6],[6],[5,6],[5],[5],[5],[5,13],[3,4,5,6,9,10,11,13],[6,10,11,13],[6,10,11],[6,11],[6,11],[6,11],[4,6,11],[3,6,11],[3,11],[3,11],[3,4,11],[4,9,11],[11],[9],[9],[2,3,5,6],[0,2,3,5,6],[5,6],[5,6],[5,6],[5],[5],[8],[8,12],[3,8,10,12],[3,10,12,13],[3,9,10],[1,2,4,6,7,10,12],[2,7,10,11,12],[2,11,12],[1,2,6,10,13],[1,2,6],[1,9,11],[1,9,11],[1,9,10,11],[1,9],[9],[9],[9],[13],[13],[3],[3],[3,8],[3,8],[3],[3],[3,4,5,6,7,11,12,13],[3,4,5,7,12,13],[4,5,7,12,13],[4,5,7,12],[4,5,7,11,12],[5,7,11,12],[7,10,11],[7,10,11],[7,10,11],[7,10,11],[7,10],[7,10],[7,10],[10],[0,1,3,8,11,12],[0,1,3,8,10],[1,5,10],[2,5,10],[2,10],[2,10],[2,10],[7],[1,2,3,4,5,6,8,10],[1,3,5,8,12],[3,5,7,8,12],[5,12],[5,11,12],[0,1,2,5,9,13],[1,2,4],[9,10],[9,10],[0,9,10],[7,9],[7,9,11],[7,9],[7,9],[7],[8],[8,12],[8,12],[8,12],[12,13],[12,13],[12,13],[12,13],[12,13],[13],[6],[6,9],[6],[6,11],[6,10,11],[6],[6],[6,8],[6,8],[6,8],[6,8,10],[6,10],[10],[10],[2,7],[2,11],[2,11],[2,11],[0,2,3,4,5,6,10],[2,3,4,5,6,10],[2,3,5,6,10],[2,3,5,6,10,11],[2,3,5,10],[1,10],[10],[10],[10],[10],[11],[11],[11],[11],[11],[11],[1,11],[1,11],[11],[8,13],[5],[5],[5],[11],[7,11],[3,7],[3],[3],[3],[9],[8,9],[8,9,12],[8,9,12],[8,9,12],[0,4,5,6],[1,4,8,9,10],[1,4,5,6,7,9,11,12],[0,1,6,7,10,11,12,13],[1,6,7,10,11,12,13],[6,7,10,12,13],[6,12,13],[6,11,12],[11],[4,5,8,10,11,13],[4,5,8,10,11,13],[5,8,10,11],[5,10,11],[5],[2,5,6,9,10,11,12],[2,5,6,9,10,12],[2,6,9,12],[6,9,12],[6,9],[6,9],[1,2,10,12],[1,10,12],[1,10,12],[1,7,9],[6,12],[6,12],[6,12,13],[5,6,12],[0,5,6],[0,5,6],[0,5,6,10],[0,5,6,10],[0,6],[0,6,9],[0,6],[0,2,3,6,8,9,10,11],[0,3,6,8,10],[3,6,8,10],[2,3,6,8],[0,1,8,9,12],[0,1,3,8,9,12],[1,6],[1],[2],[2],[9],[5,9],[4,9],[4],[4,5],[4,5],[4,5,13],[1,4,5,13],[5,7],[5,7],[5,7],[5,7],[7],[7,12],[7,12],[7,8],[7,8],[11],[5],[3],[3],[3,13],[13],[9],[9],[9],[9],[9],[3,9,10],[3,9,10],[3,9,10],[5,7],[5,7],[7],[3,4,6,7,8,9,10],[4,6,7,8,9,10],[4,5,7,8,9,10],[4,5,7],[4,5,7],[4,5,7],[4,5,7],[4,5,7],[8],[8],[8],[2,8],[2,4],[2,4],[2,4],[2,4],[0,2],[2,9],[2,9],[2,9],[2,9],[0,3,5,6,8,9,10],[0,3,5,6,8],[3,5,6,8],[3,5,8],[3,8],[3],[0,1,2,4,6,7,12,13],[0,1,7,12],[0,7],[0,6,7],[0,3,6],[0,3,6],[0,3],[0,12],[0],[2],[2,13],[12],[1,12],[2,4,5,7,10,12,13],[2,4,12,13],[2,6,12],[1,4,5,8,11,12],[1,4,5,8,12],[1,4,8,12],[9,10,13],[7,9,13],[13],[13],[13],[13],[13],[10],[3,10],[3,10],[3,10],[3,10],[3],[3],[1,5,9],[1,5,9,13],[1,5,13],[5,13],[5,7,13],[5,13],[13],[9],[9],[3,4],[0,3],[0,3],[3],[3],[3],[3],[3],[3,7],[3],[3],[3,11],[3,11],[3,10,11],[2,11],[2,11],[2,11],[3],[3],[2,3],[2,3],[2,3],[2,3],[2,3],[2,3],[2],[2],[10],[10],[10],[10],[0,1,6,8,9,10,11,12],[0,1,6,9,10,11,12],[2,10],[2],[2],[0,6],[0,5,6],[0,4,5,6],[0,4],[0,11],[0,11],[0,11],[0,8,11],[0],[0],[0],[0],[0],[0,4],[0,4],[0,4],[0,4],[0,4,10],[0,10],[0,1,10],[10],[10],[10],[8,10],[8,10],[13],[0,13],[0,13],[13],[5,13],[12,13],[13],[1],[6],[0,2,3,10,13],[2,3,10,13],[2,3,8,10,13],[2,3,13],[3,13],[2,4,5,6,7,10,12,13],[2,5,7,10,12,13],[0,6,9,13],[0,6,9,13],[0,6,7,9],[0,4,6,7,9],[4,6,7,9],[4,6],[6],[10,13],[10,13],[13],[5],[5],[5,11],[5,11]],"unprintable_filaments":[[]],"unprintable_volumes":{}},"nozzle_info":{"extruder_nozzle_list":{"0":[0,1,2,3,4]},"nozzle_list":[{"diameter":"0.4","extruder_id":0,"group_id":0,"volume_type":0},{"diameter":"0.4","extruder_id":0,"group_id":1,"volume_type":1},{"diameter":"0.4","extruder_id":0,"group_id":2,"volume_type":2},{"diameter":"0.4","extruder_id":0,"group_id":3,"volume_type":3},{"diameter":"0.4","extruder_id":0,"group_id":4,"volume_type":0}],"nozzle_status":{}},"speed_info":{"ams_preload_enabled":[true],"change_time_params":{"selector_load_time":1.0,"selector_unload_time":1.0,"standard_load_time":3.0,"standard_unload_time":2.0},"extruder_change_time":5.0,"filament_change_time":2.0,"filament_print_time":{},"group_with_time":false}},"metadata":{"config_type":"C","id":"C_stress_79","seed":30079}} \ No newline at end of file diff --git a/tests/libnest2d/test_nfp_placer.cpp b/tests/libnest2d/test_nfp_placer.cpp index 8219dda71d..4446333f5d 100644 --- a/tests/libnest2d/test_nfp_placer.cpp +++ b/tests/libnest2d/test_nfp_placer.cpp @@ -56,8 +56,10 @@ struct NfpPlacerFixture { } // namespace TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer places a single item inside the bin", "[Nesting][Placer]") { - NfpPlacer placer = placer_with(); + // The placer only keeps references to the items it packs and re-reads them + // from finalAlign() in its destructor, so the item must outlive the placer. RectangleItem item{100000000, 100000000}; + NfpPlacer placer = placer_with(); REQUIRE(place(placer, item)); REQUIRE(placer.getItems().size() == 1u); @@ -103,12 +105,15 @@ TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer packs many items without overlap", } TEST_CASE_METHOD(NfpPlacerFixture, "NfpPlacer evaluates the rotation candidates", "[Nesting][Placer]") { + // The placer re-reads its packed items from finalAlign() in its destructor, + // so the items must outlive the placer — declare them first. + std::vector<RectangleItem> rects = { + {180000000, 40000000}, {180000000, 40000000}, {180000000, 40000000}}; + Cfg cfg; cfg.rotations = {0.0, Pi / 2.0}; // exercise the rotation search loop NfpPlacer placer = placer_with(cfg); - std::vector<RectangleItem> rects = { - {180000000, 40000000}, {180000000, 40000000}, {180000000, 40000000}}; place_all(placer, rects); require_disjoint_in_bin(rects); } diff --git a/tests/libslic3r/CMakeLists.txt b/tests/libslic3r/CMakeLists.txt index b64c01aca2..4191beacd9 100644 --- a/tests/libslic3r/CMakeLists.txt +++ b/tests/libslic3r/CMakeLists.txt @@ -12,6 +12,8 @@ add_executable(${_TEST_NAME}_tests test_clipper_offset.cpp test_clipper_utils.cpp test_config.cpp + test_config_variant_expansion.cpp + test_toolordering_nozzle_group.cpp test_preset_bundle_loading.cpp test_preset_setting_id.cpp test_elephant_foot_compensation.cpp @@ -20,6 +22,7 @@ add_executable(${_TEST_NAME}_tests test_polygon.cpp test_mutable_polygon.cpp test_mutable_priority_queue.cpp + test_nozzle_volume_type.cpp test_stl.cpp test_meshboolean.cpp test_marchingsquares.cpp diff --git a/tests/libslic3r/test_3mf.cpp b/tests/libslic3r/test_3mf.cpp index 7d7593948e..7a692f949f 100644 --- a/tests/libslic3r/test_3mf.cpp +++ b/tests/libslic3r/test_3mf.cpp @@ -1,7 +1,13 @@ #include "libslic3r/Model.hpp" #include "libslic3r/Format/3mf.hpp" +#include "libslic3r/Format/bbs_3mf.hpp" #include "libslic3r/Format/STL.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/Semver.hpp" +#include "libslic3r/Preset.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" +#include "libslic3r/ProjectTask.hpp" #include <boost/filesystem/operations.hpp> @@ -133,6 +139,376 @@ SCENARIO("Export+Import geometry to/from 3mf file cycle", "[3mf]") { } } +// .3mf multi-nozzle round-trip. +// Locks the load/save handling for the H2C multi-nozzle plate metadata: +// * filament_volume_maps -> plate config "filament_volume_map" (with the >1 -> 0 clamp) +// * nozzle_volume_type -> PlateData::nozzle_volume_types (previously write-only) +// and pins the deliberately-lossy keys (enable_filament_dynamic_map) so a future change has to +// consciously unpin them. Uses a store_bbs_3mf -> load_bbs_3mf cycle (no external fixture needed). +SCENARIO("H2C multi-nozzle .3mf round-trip", "[3mf][MultiNozzle]") { + GIVEN("a plate carrying multi-nozzle filament assignment metadata") { + Model model; + std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl"; + REQUIRE(load_stl(src_file.c_str(), &model)); + model.add_default_instances(); + + // store_bbs_3mf stages Metadata/project_settings.config through the model's backup path; + // point it at a writable temp dir (the default lives under a read-only root in CI). + std::string backup_dir = + (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("orca_mn_%%%%%%%%")).string(); + boost::filesystem::create_directories(backup_dir); + model.set_backup_path(backup_dir); + + // Global (printer) config: give nozzle_volume_type a non-default value so the slice_info + // read-back is a meaningful assertion (High Flow == 1). + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_key_value("nozzle_volume_type", + new ConfigOptionEnumsGeneric({ (int) NozzleVolumeType::nvtHighFlow })); + + PlateData* plate = new PlateData(); + plate->plate_index = 0; + plate->is_sliced_valid = true; // gate for the slice_info.config writer (nozzle_volume_type) + plate->filament_maps = { 1, 2, 1 }; // slice_info uses this; keep it == model_settings' value + plate->config.set_key_value("filament_map_mode", new ConfigOptionEnum<FilamentMapMode>(fmmManual)); + plate->config.set_key_value("filament_map", new ConfigOptionInts({ 1, 2, 1 })); + // Deliberately include out-of-range volume-type ids (2 == Hybrid, 3 == TPU High Flow): + // the loader must clamp them back to Standard (0). + plate->config.set_key_value("filament_volume_map", new ConfigOptionInts({ 0, 2, 1, 3 })); + // Known-lossy: a true value must NOT survive the round-trip (slice_info hardcodes false, + // model_settings never writes it). + plate->config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(true)); + + WHEN("stored to and reloaded from a .3mf") { + std::string test_file = std::string(TEST_DATA_DIR) + "/test_3mf/mn_roundtrip.3mf"; + + StoreParams store_params; + store_params.path = test_file.c_str(); + store_params.model = &model; + store_params.config = &config; + store_params.plate_data_list.push_back(plate); + store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence; + REQUIRE(store_bbs_3mf(store_params)); + + Model dst_model; + DynamicPrintConfig dst_config; + ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Enable }; + PlateDataPtrs dst_plates; + std::vector<Preset*> project_presets; + bool is_bbl_3mf = false, is_orca_3mf = false; + Semver file_version; + // LoadConfig is required for slice_info.config (nozzle_volume_type) to be parsed — + // matches how the app loads projects. + bool loaded = load_bbs_3mf(test_file.c_str(), &dst_config, &ctxt, &dst_model, &dst_plates, + &project_presets, &is_bbl_3mf, &is_orca_3mf, &file_version, nullptr, + LoadStrategy::LoadModel | LoadStrategy::LoadConfig); + boost::filesystem::remove(test_file); + + THEN("every multi-nozzle key round-trips as expected") { + REQUIRE(loaded); + REQUIRE(dst_plates.size() >= 1); + PlateData* rt = dst_plates.front(); + + // filament_map (model_settings + slice_info; already round-tripped) + auto* fmap = rt->config.option<ConfigOptionInts>("filament_map"); + REQUIRE(fmap != nullptr); + REQUIRE(fmap->values == std::vector<int>({ 1, 2, 1 })); + + // filament_volume_map (model_settings) with the >1 -> 0 clamp + auto* fvmap = rt->config.option<ConfigOptionInts>("filament_volume_map"); + REQUIRE(fvmap != nullptr); + REQUIRE(fvmap->values == std::vector<int>({ 0, 0, 1, 0 })); + + // nozzle_volume_type read-back into PlateData::nozzle_volume_types + REQUIRE(rt->nozzle_volume_types == "1"); + + // enable_filament_dynamic_map pinned lossy: model_settings never serializes it and + // slice_info hardcodes false, so the `true` we set is dropped. Pinned here + // (absent or false, never true) so a future change that persists it must update this. + auto* dyn = rt->config.option<ConfigOptionBool>("enable_filament_dynamic_map"); + const bool persisted_true = (dyn != nullptr && dyn->value); + REQUIRE_FALSE(persisted_true); + } + + release_PlateData_list(dst_plates); + } + delete plate; // store_bbs_3mf does not take ownership of the source plate + boost::filesystem::remove_all(backup_dir); + } +} + +// Saved nozzle diameter for a single-nozzle-per-extruder printer with a non-standard nozzle. +// The grouping result rounds every nozzle diameter to the nearest of {0.2,0.4,0.6,0.8} for its +// internal matching key. That rounded value must NOT reach the saved <filament>/<nozzle> metadata on +// a printer whose extruders each carry one nozzle: the exact per-extruder config diameter is written +// instead, so a 0.5 mm nozzle is preserved rather than saved as 0.4. (Only an extruder that carries a +// nozzle cluster, which the per-extruder config cannot express, keeps the grouping result's diameter.) +SCENARIO("Non-standard nozzle diameter survives .3mf save on a single-nozzle printer", "[3mf][MultiNozzle]") { + GIVEN("a single-extruder plate whose nozzle is 0.5 mm and whose stamped diameter was rounded to 0.4") { + Model model; + std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl"; + REQUIRE(load_stl(src_file.c_str(), &model)); + model.add_default_instances(); + + std::string backup_dir = + (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("orca_nd_%%%%%%%%")).string(); + boost::filesystem::create_directories(backup_dir); + model.set_backup_path(backup_dir); + + // Single extruder with a non-standard 0.5 mm nozzle; extruder_max_nozzle_count stays at its + // default (no nozzle cluster), so the writer must emit the exact config diameter. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({ 0.5 })); + + PlateData* plate = new PlateData(); + plate->plate_index = 0; + plate->is_sliced_valid = true; // gate for the slice_info.config writer + plate->filament_maps = { 1 }; + + // Seed the stamped diameter with the grouping result's rounded value (0.5 -> 0.4) so the + // assertion proves the writer ignores it and emits the exact config diameter instead. + FilamentInfo fi; + fi.id = 0; + fi.type = "PLA"; + fi.color = "#FFFFFFFF"; + fi.group_id = { 0 }; + fi.nozzle_diameter = 0.4; // rounded; must NOT be the value written + plate->slice_filaments_info.push_back(fi); + + WHEN("stored to and reloaded from a .3mf") { + std::string test_file = std::string(TEST_DATA_DIR) + "/test_3mf/nd_roundtrip.3mf"; + + StoreParams store_params; + store_params.path = test_file.c_str(); + store_params.model = &model; + store_params.config = &config; + store_params.plate_data_list.push_back(plate); + store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence; + REQUIRE(store_bbs_3mf(store_params)); + + Model dst_model; + DynamicPrintConfig dst_config; + ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Enable }; + PlateDataPtrs dst_plates; + std::vector<Preset*> project_presets; + bool is_bbl_3mf = false, is_orca_3mf = false; + Semver file_version; + bool loaded = load_bbs_3mf(test_file.c_str(), &dst_config, &ctxt, &dst_model, &dst_plates, + &project_presets, &is_bbl_3mf, &is_orca_3mf, &file_version, nullptr, + LoadStrategy::LoadModel | LoadStrategy::LoadConfig); + boost::filesystem::remove(test_file); + + THEN("the saved nozzle diameter is the exact 0.5, not the rounded 0.4") { + REQUIRE(loaded); + REQUIRE(dst_plates.size() >= 1); + PlateData* rt = dst_plates.front(); + + // <nozzle> tag: device-facing per-nozzle diameter string, written verbatim. + REQUIRE(rt->nozzles_info.size() >= 1); + REQUIRE(rt->nozzles_info.front().diameter == "0.5"); + + // <filament> tag: per-filament nozzle_diameter parsed back as 0.5, not 0.4. + REQUIRE(rt->slice_filaments_info.size() >= 1); + REQUIRE_THAT(rt->slice_filaments_info.front().nozzle_diameter, Catch::Matchers::WithinAbs(0.5, 1e-6)); + } + + release_PlateData_list(dst_plates); + } + delete plate; // store_bbs_3mf does not take ownership of the source plate + boost::filesystem::remove_all(backup_dir); + } +} + +// A legacy / foreign project (no multi-nozzle metadata) must load crash-safe through the BBS +// importer and must not fabricate a filament_volume_map. +SCENARIO("Legacy project loads crash-safe via load_bbs_3mf", "[3mf][MultiNozzle]") { + GIVEN("a project without any multi-nozzle metadata") { + std::string path = std::string(TEST_DATA_DIR) + "/test_3mf/Geräte/Büchse.3mf"; + Model model; + DynamicPrintConfig config; + ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Enable }; + PlateDataPtrs plates; + std::vector<Preset*> project_presets; + bool is_bbl_3mf = false, is_orca_3mf = false; + Semver file_version; + + WHEN("loaded through the BBS importer") { + bool loaded = false; + REQUIRE_NOTHROW(loaded = load_bbs_3mf(path.c_str(), &config, &ctxt, &model, &plates, + &project_presets, &is_bbl_3mf, &is_orca_3mf, + &file_version, nullptr, + LoadStrategy::LoadModel | LoadStrategy::LoadConfig)); + THEN("it does not crash and invents no per-filament volume map") { + for (PlateData* p : plates) { + REQUIRE(p->config.option<ConfigOptionInts>("filament_volume_map") == nullptr); + } + } + release_PlateData_list(plates); + } + } +} + +// Device-side nozzle-grouping serialization surface. +// Direct unit coverage for the pure serialize/deserialize + StaticNozzleGroupResult helpers that the +// gcode.3mf writer/reader lean on. +SCENARIO("MultiNozzle serialization helpers", "[3mf][MultiNozzle]") { + using namespace Slic3r::MultiNozzleUtils; + + GIVEN("NozzleInfo / NozzleGroupInfo") { + NozzleInfo n0; n0.group_id = 0; n0.extruder_id = 0; n0.diameter = "0.4"; n0.volume_type = nvtStandard; + NozzleInfo n1; n1.group_id = 1; n1.extruder_id = 1; n1.diameter = "0.4"; n1.volume_type = nvtHighFlow; + + THEN("NozzleInfo::serialize matches the <nozzle> tag attributes (extruder_id 1-based)") { + REQUIRE(n0.serialize() == "id=\"0\" extruder_id=\"1\" nozzle_diameter=\"0.4\" volume_type=\"Standard\""); + REQUIRE(n1.serialize() == "id=\"1\" extruder_id=\"2\" nozzle_diameter=\"0.4\" volume_type=\"High Flow\""); + } + THEN("NozzleGroupInfo serialize/deserialize round-trips and rejects malformed input") { + NozzleGroupInfo g("0.4", nvtHighFlow, 1, 3); + REQUIRE(g.serialize() == "1-0.4-High Flow-3"); + auto rt = NozzleGroupInfo::deserialize(g.serialize()); + REQUIRE(rt.has_value()); + REQUIRE(*rt == g); + REQUIRE_FALSE(NozzleGroupInfo::deserialize("1-0.4-Standard").has_value()); // too few tokens + REQUIRE_FALSE(NozzleGroupInfo::deserialize("x-0.4-Standard-3").has_value()); // non-numeric extruder + } + } + + GIVEN("a StaticNozzleGroupResult built from filament + nozzle infos") { + std::vector<NozzleInfo> nozzles; + { NozzleInfo n; n.group_id = 0; n.extruder_id = 0; n.diameter = "0.4"; n.volume_type = nvtStandard; nozzles.push_back(n); } + { NozzleInfo n; n.group_id = 1; n.extruder_id = 1; n.diameter = "0.4"; n.volume_type = nvtHighFlow; nozzles.push_back(n); } + + std::vector<FilamentInfo> filaments(3); + filaments[0].id = 0; filaments[0].group_id = { 0 }; + filaments[1].id = 1; filaments[1].group_id = { 1 }; + filaments[2].id = 2; filaments[2].group_id = { 0, 1 }; + + auto result = StaticNozzleGroupResult::create(filaments, nozzles, { 0, 1, 2 }, { 0, 1, 0 }, false); + REQUIRE(result.has_value()); + + THEN("filament->nozzle queries resolve to the stored mapping") { + REQUIRE(result->get_extruder_count() == 2); + REQUIRE(result->get_used_extruders() == std::vector<int>({ 0, 1 })); + REQUIRE(result->get_used_filaments() == std::vector<unsigned int>({ 0, 1, 2 })); + REQUIRE(result->get_nozzles_for_filament(0).size() == 1); + REQUIRE(result->get_nozzles_for_filament(2).size() == 2); + // first-use resolves through the (filament,nozzle) change sequences. + auto first = result->get_first_nozzle_for_filament(1); + REQUIRE(first.has_value()); + REQUIRE(first->group_id == 1); + } + THEN("empty inputs yield nullopt") { + REQUIRE_FALSE(StaticNozzleGroupResult::create({}, nozzles, {}, {}, false).has_value()); + REQUIRE_FALSE(StaticNozzleGroupResult::create(filaments, {}, {}, {}, false).has_value()); + } + } + + GIVEN("load_nozzle_infos_with_compatibility fallbacks") { + std::vector<NozzleInfo> new_format; + { NozzleInfo n; n.group_id = 1; n.extruder_id = 1; n.diameter = "0.4"; n.volume_type = nvtHighFlow; new_format.push_back(n); } + { NozzleInfo n; n.group_id = 0; n.extruder_id = 0; n.diameter = "0.4"; n.volume_type = nvtStandard; new_format.push_back(n); } + + THEN("new-format <nozzle> tags are returned sorted by logical id") { + auto out = load_nozzle_infos_with_compatibility(new_format, {}, {}, {}, {}); + REQUIRE(out.size() == 2); + REQUIRE(out[0].group_id == 0); + REQUIRE(out[1].group_id == 1); + } + THEN("oldest single-nozzle 3mf (no tags, no filament group_id) rebuilds from diameters/volume types") { + std::vector<NozzleVolumeType> vt = { nvtStandard, nvtHighFlow }; + std::vector<double> dia = { 0.4, 0.4 }; + auto out = load_nozzle_infos_with_compatibility({}, {}, {}, vt, dia); + REQUIRE(out.size() == 2); + REQUIRE(out[0].extruder_id == 0); + REQUIRE(out[0].volume_type == nvtStandard); + REQUIRE(out[1].volume_type == nvtHighFlow); + } + } +} + +// The layer-aware grouping result must survive the gcode.3mf write/read as +// <nozzle> tags and the enable_filament_dynamic_map flag. Proves the parse_filament_info stamping, +// the NOZZLE_TAG writer, the _handle_config_nozzle reader, and the nozzles_info plate copy. +SCENARIO("Nozzle-group metadata .3mf round-trip", "[3mf][MultiNozzle]") { + GIVEN("a plate carrying a two-nozzle LayeredNozzleGroupResult") { + Model model; + std::string src_file = std::string(TEST_DATA_DIR) + "/test_3mf/Prusa.stl"; + REQUIRE(load_stl(src_file.c_str(), &model)); + model.add_default_instances(); + + std::string backup_dir = + (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("orca_ng_%%%%%%%%")).string(); + boost::filesystem::create_directories(backup_dir); + model.set_backup_path(backup_dir); + + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + + std::vector<MultiNozzleUtils::NozzleInfo> nozzles; + { MultiNozzleUtils::NozzleInfo n; n.group_id = 0; n.extruder_id = 0; n.diameter = "0.4"; n.volume_type = NozzleVolumeType::nvtStandard; nozzles.push_back(n); } + { MultiNozzleUtils::NozzleInfo n; n.group_id = 1; n.extruder_id = 1; n.diameter = "0.4"; n.volume_type = NozzleVolumeType::nvtHighFlow; nozzles.push_back(n); } + auto group = MultiNozzleUtils::LayeredNozzleGroupResult::create( + std::vector<int>{ 0, 1, 0 }, nozzles, std::vector<unsigned int>{ 0, 1, 2 }); + REQUIRE(group.has_value()); + + PlateData* plate = new PlateData(); + plate->plate_index = 0; + plate->is_sliced_valid = true; + plate->filament_maps = { 1, 2, 1 }; + plate->nozzle_group_result = group; + plate->config.set_key_value("filament_map_mode", new ConfigOptionEnum<FilamentMapMode>(fmmManual)); + plate->config.set_key_value("filament_map", new ConfigOptionInts({ 1, 2, 1 })); + + WHEN("stored to and reloaded from a .3mf") { + std::string test_file = std::string(TEST_DATA_DIR) + "/test_3mf/ng_roundtrip.3mf"; + + StoreParams store_params; + store_params.path = test_file.c_str(); + store_params.model = &model; + store_params.config = &config; + store_params.plate_data_list.push_back(plate); + store_params.strategy = SaveStrategy::Zip64 | SaveStrategy::Silence; + REQUIRE(store_bbs_3mf(store_params)); + + Model dst_model; + DynamicPrintConfig dst_config; + ConfigSubstitutionContext ctxt{ ForwardCompatibilitySubstitutionRule::Enable }; + PlateDataPtrs dst_plates; + std::vector<Preset*> project_presets; + bool is_bbl_3mf = false, is_orca_3mf = false; + Semver file_version; + bool loaded = load_bbs_3mf(test_file.c_str(), &dst_config, &ctxt, &dst_model, &dst_plates, + &project_presets, &is_bbl_3mf, &is_orca_3mf, &file_version, nullptr, + LoadStrategy::LoadModel | LoadStrategy::LoadConfig); + boost::filesystem::remove(test_file); + + THEN("the <nozzle> tags round-trip into the loaded plate's nozzles_info") { + REQUIRE(loaded); + REQUIRE(dst_plates.size() >= 1); + PlateData* rt = dst_plates.front(); + + REQUIRE(rt->nozzles_info.size() == 2); + // reader stores extruder_id 0-based (tag is 1-based), diameter/volume_type preserved. + std::sort(rt->nozzles_info.begin(), rt->nozzles_info.end()); + REQUIRE(rt->nozzles_info[0].group_id == 0); + REQUIRE(rt->nozzles_info[0].extruder_id == 0); + REQUIRE(rt->nozzles_info[0].diameter == "0.4"); + REQUIRE(rt->nozzles_info[0].volume_type == NozzleVolumeType::nvtStandard); + REQUIRE(rt->nozzles_info[1].group_id == 1); + REQUIRE(rt->nozzles_info[1].extruder_id == 1); + REQUIRE(rt->nozzles_info[1].volume_type == NozzleVolumeType::nvtHighFlow); + + // A static (non-selector) result must persist enable_filament_dynamic_map = false. + auto* dyn = rt->config.option<ConfigOptionBool>("enable_filament_dynamic_map"); + const bool persisted_true = (dyn != nullptr && dyn->value); + REQUIRE_FALSE(persisted_true); + } + + release_PlateData_list(dst_plates); + } + delete plate; + boost::filesystem::remove_all(backup_dir); + } +} + SCENARIO("2D convex hull of sinking object", "[3mf][.]") { GIVEN("model") { // load a model diff --git a/tests/libslic3r/test_arachne_walls.cpp b/tests/libslic3r/test_arachne_walls.cpp index 2d8ee3bc03..4ca18400af 100644 --- a/tests/libslic3r/test_arachne_walls.cpp +++ b/tests/libslic3r/test_arachne_walls.cpp @@ -18,6 +18,7 @@ #include <catch2/catch_all.hpp> #include "libslic3r/Arachne/WallToolPaths.hpp" +#include "libslic3r/Arachne/SkeletalTrapezoidation.hpp" #include "libslic3r/Arachne/utils/ExtrusionLine.hpp" #include "libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.hpp" #include "libslic3r/Arachne/BeadingStrategy/BeadingStrategy.hpp" @@ -265,3 +266,46 @@ TEST_CASE("Arachne widening keeps two beads in transition band (#14376)", "[Arac for (const coord_t w : beading.bead_widths) CHECK(w <= inner_width); } + +namespace { +// Exposes the protected static interpolate() for a focused unit test. +struct InterpolateProbe : SkeletalTrapezoidation { + using SkeletalTrapezoidation::interpolate; +}; +} // anonymous namespace + +// interpolate() indexes the merged beading with an index derived from `left`. The merged beading +// follows the thicker of left/right, so when the thicker side has fewer insets the index runs past +// its end. +TEST_CASE("Beading interpolation tolerates a thicker side with fewer insets", "[Arachne][Regression]") { + using Beading = BeadingStrategy::Beading; + + // Thicker side (right) has fewer insets, so the merged beading holds only 2 toolpath locations. + const coord_t w = scaled<coord_t>(0.42); + Beading left; + left.total_thickness = scaled<coord_t>(1.0); + left.bead_widths = { w, w, w, w }; + left.toolpath_locations = { scaled<coord_t>(0.1), scaled<coord_t>(0.3), scaled<coord_t>(0.5), scaled<coord_t>(0.7) }; + left.left_over = 0; + + Beading right; + right.total_thickness = scaled<coord_t>(2.0); + right.bead_widths = { w, w }; + right.toolpath_locations = { scaled<coord_t>(0.1), scaled<coord_t>(0.3) }; + right.left_over = 0; + + // Just past left's location [2] (0.5), so the derived index is 2, past the end of the 2-inset merged beading. + const coord_t switching_radius = scaled<coord_t>(0.6); + + Beading result; + REQUIRE_NOTHROW(result = InterpolateProbe::interpolate(left, 0.5, right, switching_radius)); + + // With the guard the adjustment is skipped, so the result is the plain interpolation. + const Beading expected = InterpolateProbe::interpolate(left, 0.5, right); + REQUIRE(result.toolpath_locations.size() == expected.toolpath_locations.size()); + REQUIRE(result.bead_widths.size() == expected.bead_widths.size()); + for (size_t i = 0; i < expected.toolpath_locations.size(); ++i) { + CHECK(result.toolpath_locations[i] == expected.toolpath_locations[i]); + CHECK(result.bead_widths[i] == expected.bead_widths[i]); + } +} diff --git a/tests/libslic3r/test_config.cpp b/tests/libslic3r/test_config.cpp index 8e6915e98f..3a4ff3a44b 100644 --- a/tests/libslic3r/test_config.cpp +++ b/tests/libslic3r/test_config.cpp @@ -401,3 +401,247 @@ SCENARIO("update_diff_values_to_child_config tolerates legacy machine-limit vect // } // } // } + +TEST_CASE("H2C/A2L-era multi-nozzle and pre-heat config keys exist", "[config]") { + // Foundation keys backing H2C 6-nozzle cluster grouping, the pre-heat/pre-cool time + // model, and wipe-tower nozzle-change handling. Defaults must keep existing + // single-nozzle printers behaving identically. + Slic3r::DynamicPrintConfig config = Slic3r::DynamicPrintConfig::full_print_config(); + + // Printer / per-extruder options + REQUIRE(config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count") != nullptr); + REQUIRE(config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count")->values == std::vector<int>{1}); + REQUIRE(config.option<ConfigOptionBool>("enable_pre_heating") != nullptr); + REQUIRE(config.option<ConfigOptionBool>("enable_pre_heating")->value == false); + REQUIRE(config.option<ConfigOptionFloatsNullable>("hotend_cooling_rate") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("hotend_heating_rate") != nullptr); + REQUIRE(config.option<ConfigOptionFloat>("machine_hotend_change_time") != nullptr); + REQUIRE(config.option<ConfigOptionFloat>("machine_prepare_compensation_time") != nullptr); + + // Filament pre-cooling / ramming / nozzle-change (nc) options + REQUIRE(config.option<ConfigOptionIntsNullable>("filament_pre_cooling_temperature") != nullptr); + REQUIRE(config.option<ConfigOptionIntsNullable>("filament_pre_cooling_temperature_nc") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_preheat_temperature_delta") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_retract_length_nc") != nullptr); + REQUIRE(config.option<ConfigOptionFloats>("filament_change_length_nc") != nullptr); + REQUIRE(config.option<ConfigOptionFloats>("filament_prime_volume_nc") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_ramming_travel_time") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_ramming_travel_time_nc") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_ramming_volumetric_speed") != nullptr); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_ramming_volumetric_speed_nc") != nullptr); + + // Spot-check defaults that must not alter existing behavior. + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_retract_length_nc")->values == std::vector<double>{10.}); + REQUIRE(config.option<ConfigOptionFloats>("filament_prime_volume_nc")->values == std::vector<double>{60.}); + REQUIRE(config.option<ConfigOptionIntsNullable>("filament_pre_cooling_temperature_nc")->values == std::vector<int>{0}); + REQUIRE(config.option<ConfigOptionFloatsNullable>("filament_ramming_volumetric_speed")->values == std::vector<double>{-1}); +} + +SCENARIO("ConfigOptionVector::set_to_index with stride=1 copies values correctly", "[Config][set_to_index]") { + GIVEN("A destination vector and a source vector with 3 values") { + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionFloats src({10.0, 20.0, 30.0}); + std::vector<int> variant_index = {0, 1, 2}; + int stride = 1; + + WHEN("set_to_index is called with stride=1") { + dest.set_to_index(&src, variant_index, stride); + + THEN("The destination contains the source values") { + REQUIRE(dest.values.size() == 3); + REQUIRE(dest.values[0] == 10.0); + REQUIRE(dest.values[1] == 20.0); + REQUIRE(dest.values[2] == 30.0); + } + } + } + + GIVEN("A destination vector and a source vector with subset mapping") { + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionFloats src({100.0, 200.0, 300.0}); + std::vector<int> variant_index = {1, 2}; + int stride = 1; + + WHEN("set_to_index maps only indices 1 and 2") { + dest.set_to_index(&src, variant_index, stride); + + THEN("Only the mapped values are copied, default fills the others") { + REQUIRE(dest.values.size() == 2); + REQUIRE(dest.values[0] == 200.0); + REQUIRE(dest.values[1] == 300.0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index with stride=2 copies grouped values correctly", "[Config][set_to_index]") { + GIVEN("A destination vector and a source vector with stride=2 (e.g., nozzle groups)") { + // Source has 4 groups of 2 values each: (10,11), (20,21), (30,31), (40,41) + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionFloats src({10.0, 11.0, 20.0, 21.0, 30.0, 31.0, 40.0, 41.0}); + int stride = 2; + + WHEN("set_to_index maps groups 0, 1, 3") { + std::vector<int> variant_index = {0, 1, 3}; + dest.set_to_index(&src, variant_index, stride); + + THEN("The destination has 3 groups (6 values) mapped correctly") { + REQUIRE(dest.values.size() == 6); + // Group 0: (10, 11) + REQUIRE(dest.values[0] == 10.0); + REQUIRE(dest.values[1] == 11.0); + // Group 1: (20, 21) + REQUIRE(dest.values[2] == 20.0); + REQUIRE(dest.values[3] == 21.0); + // Group 3: (40, 41) + REQUIRE(dest.values[4] == 40.0); + REQUIRE(dest.values[5] == 41.0); + } + } + } + + GIVEN("A destination and a single-group source") { + Slic3r::ConfigOptionFloats dest({0.0}); + // Source has 1 group of 2 values + Slic3r::ConfigOptionFloats src({50.0, 60.0}); + int stride = 2; + + WHEN("set_to_index maps group 0 from a single-group source") { + std::vector<int> variant_index = {0}; + dest.set_to_index(&src, variant_index, stride); + + THEN("The destination contains the single group correctly") { + REQUIRE(dest.values.size() == 2); + REQUIRE(dest.values[0] == 50.0); + REQUIRE(dest.values[1] == 60.0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index handles empty dest_index", "[Config][set_to_index]") { + GIVEN("A destination and source with stride=2") { + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionFloats src({10.0, 11.0, 20.0, 21.0}); + std::vector<int> variant_index = {}; + int stride = 2; + + WHEN("set_to_index is called with an empty index vector") { + dest.set_to_index(&src, variant_index, stride); + + THEN("The destination is resized to 0") { + REQUIRE(dest.values.size() == 0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index handles nil values in source", "[Config][set_to_index]") { + GIVEN("A source with a nil group (stride=2)") { + Slic3r::ConfigOptionFloatsNullable dest({0.0}); + Slic3r::ConfigOptionFloatsNullable src({10.0, 11.0, + Slic3r::ConfigOptionFloatsNullable::nil_value(), Slic3r::ConfigOptionFloatsNullable::nil_value(), + 30.0, 31.0}); + int stride = 2; + + WHEN("set_to_index maps all groups including the nil one") { + std::vector<int> variant_index = {0, 1, 2}; + dest.set_to_index(&src, variant_index, stride); + + THEN("Non-nil groups are copied and the nil group keeps the default") { + REQUIRE(dest.values.size() == 6); + // Group 0: (10, 11) — copied + REQUIRE(dest.values[0] == 10.0); + REQUIRE(dest.values[1] == 11.0); + // Group 1: nil — keeps default (the front value = 10.0) + REQUIRE(dest.values[2] == 10.0); + REQUIRE(dest.values[3] == 10.0); + // Group 2: (30, 31) — copied + REQUIRE(dest.values[4] == 30.0); + REQUIRE(dest.values[5] == 31.0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index handles out-of-bounds dest_index", "[Config][set_to_index]") { + GIVEN("A source with only 2 groups (4 values) but dest_index references group 3") { + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionFloats src({10.0, 11.0, 20.0, 21.0}); // 2 groups of stride 2 + int stride = 2; + + WHEN("set_to_index maps group 3 which is out of bounds") { + std::vector<int> variant_index = {0, 3}; // group 3 is out of range + dest.set_to_index(&src, variant_index, stride); + + THEN("Group 0 is copied, group 3 falls back to default without crashing") { + REQUIRE(dest.values.size() == 4); + // Group 0: (10, 11) — copied + REQUIRE(dest.values[0] == 10.0); + REQUIRE(dest.values[1] == 11.0); + // Group 3: out of bounds — keeps default (10.0 = src.values.front()) + REQUIRE(dest.values[2] == 10.0); + REQUIRE(dest.values[3] == 10.0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index handles negative dest_index values", "[Config][set_to_index]") { + GIVEN("A destination and source with a negative entry in dest_index") { + // The dest is initially empty, so resize fills all slots with src.values.front(). + Slic3r::ConfigOptionFloats dest; + Slic3r::ConfigOptionFloats src({100.0, 101.0, 200.0, 201.0}); + int stride = 2; + + WHEN("set_to_index maps group 0 and a negative index") { + std::vector<int> variant_index = {-1, 0}; + dest.set_to_index(&src, variant_index, stride); + + THEN("The negative index is skipped, the valid group is copied") { + REQUIRE(dest.values.size() == 4); + // Position 0 (variant_index[0] = -1): skipped, keeps default fill + // from resize (src.values.front() = 100.0, applied to all new elements) + REQUIRE(dest.values[0] == 100.0); + REQUIRE(dest.values[1] == 100.0); + // Position 1 (variant_index[1] = 0): copied from group 0 of src + REQUIRE(dest.values[2] == 100.0); + REQUIRE(dest.values[3] == 101.0); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index handles single-element groups with stride=1", "[Config][set_to_index]") { + GIVEN("A destination re-mapping one variant index with a stride=1 source") { + // Simulates the PrintObject.cpp code path: stride=1, variant_index={1} + Slic3r::ConfigOptionFloats dest({99.0, 99.0, 99.0, 99.0}); // pre-sized for 4 extruders + Slic3r::ConfigOptionFloats src({0.5, 0.6, 0.7, 0.8}); // 4 extruder values + std::vector<int> variant_index = {1}; // only extruder 1 is active + int stride = 1; + + WHEN("set_to_index is called") { + dest.set_to_index(&src, variant_index, stride); + + THEN("Only the mapped value is copied, rest are defaulted") { + REQUIRE(dest.values.size() == 1); + REQUIRE(dest.values[0] == 0.6); + } + } + } +} + +SCENARIO("ConfigOptionVector::set_to_index throws on incompatible type", "[Config][set_to_index]") { + GIVEN("A Floats destination and an Ints source") { + Slic3r::ConfigOptionFloats dest({0.0}); + Slic3r::ConfigOptionInts src({1, 2, 3}); + std::vector<int> variant_index = {0}; + int stride = 1; + + WHEN("set_to_index is called with mismatched types") { + THEN("A ConfigurationError is thrown") { + REQUIRE_THROWS_AS(dest.set_to_index(&src, variant_index, stride), Slic3r::ConfigurationError); + } + } + } +} diff --git a/tests/libslic3r/test_config_variant_expansion.cpp b/tests/libslic3r/test_config_variant_expansion.cpp new file mode 100644 index 0000000000..59f311eae5 --- /dev/null +++ b/tests/libslic3r/test_config_variant_expansion.cpp @@ -0,0 +1,336 @@ +#include <catch2/catch_all.hpp> + +#include "libslic3r/PrintConfig.hpp" + +using namespace Slic3r; + +namespace { + +// A 2-extruder printer whose second extruder holds both a Standard and a High Flow nozzle +// (nozzle_volume_type Hybrid), described by extruder_nozzle_stats. The variant lists carry one +// column per (extruder x volume type) as composed from the presets. +DynamicPrintConfig make_hybrid_printer_config() +{ + DynamicPrintConfig config; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#3|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + return config; +} + +void add_print_variant_columns(DynamicPrintConfig &config) +{ + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("outer_wall_speed", true)->values = {30., 200., 50., 500.}; +} + +} // namespace + +TEST_CASE("apply_override fills nil entries from the 0-based default index", "[Config]") +{ + ConfigOptionFloats machine({10., 20., 30.}); + ConfigOptionFloatsNullable filament; + filament.values = {ConfigOptionFloatsNullable::nil_value(), 42.}; + + SECTION("a nil entry picks the slot addressed by its 0-based index") { + std::vector<int> slot_index{2, 0}; + ConfigOptionFloats resolved(machine); + REQUIRE(resolved.apply_override(&filament, slot_index)); + REQUIRE(resolved.values == std::vector<double>({30., 42.})); + } + + SECTION("an index past the machine slots falls back to the first slot") { + std::vector<int> slot_index{5, 0}; + ConfigOptionFloats resolved(machine); + REQUIRE(resolved.apply_override(&filament, slot_index)); + REQUIRE(resolved.values == std::vector<double>({10., 42.})); + } + + SECTION("a negative index (unresolved slot) falls back to the first slot") { + std::vector<int> slot_index{-1, 0}; + ConfigOptionFloats resolved(machine); + REQUIRE(resolved.apply_override(&filament, slot_index)); + REQUIRE(resolved.values == std::vector<double>({10., 42.})); + } +} + +TEST_CASE("get_config_index_base resolves (volume type, extruder type, id) to a slot", "[Config]") +{ + const std::vector<std::string> variant_list = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + const std::vector<int> variant_ids = {1, 1, 2, 2}; + + SECTION("a matching (variant, id) pair yields its slot") { + REQUIRE(get_config_index_base(nvtStandard, etDirectDrive, 1, variant_list, variant_ids) == 0); + REQUIRE(get_config_index_base(nvtHighFlow, etDirectDrive, 1, variant_list, variant_ids) == 1); + REQUIRE(get_config_index_base(nvtStandard, etDirectDrive, 2, variant_list, variant_ids) == 2); + REQUIRE(get_config_index_base(nvtHighFlow, etDirectDrive, 2, variant_list, variant_ids) == 3); + } + + SECTION("no matching column falls back to slot 0") { + REQUIRE(get_config_index_base(nvtStandard, etDirectDrive, 3, variant_list, variant_ids) == 0); + REQUIRE(get_config_index_base(nvtStandard, etBowden, 1, variant_list, variant_ids) == 0); + } + + SECTION("Hybrid is not a preset variant string and falls back to slot 0") { + REQUIRE(get_config_index_base(nvtHybrid, etDirectDrive, 2, variant_list, variant_ids) == 0); + } +} + +TEST_CASE("get_extruder_nozzle_volume_count reads the per-extruder volume-type layout", "[Config]") +{ + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + + SECTION("absent stats fall back to one slot per extruder") { + DynamicPrintConfig config; + REQUIRE(config.get_extruder_nozzle_volume_count(2, nozzle_volume_types) == 2); + REQUIRE(nozzle_volume_types.size() == 2); + REQUIRE(nozzle_volume_types[0].empty()); + REQUIRE(nozzle_volume_types[1].empty()); + } + + SECTION("stats sized differently from the extruder count are ignored") { + DynamicPrintConfig config; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1"}; + REQUIRE(config.get_extruder_nozzle_volume_count(2, nozzle_volume_types) == 2); + REQUIRE(nozzle_volume_types[0].empty()); + REQUIRE(nozzle_volume_types[1].empty()); + } + + SECTION("single volume type per extruder counts one slot each") { + DynamicPrintConfig config; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "High Flow#1"}; + REQUIRE(config.get_extruder_nozzle_volume_count(2, nozzle_volume_types) == 2); + REQUIRE(nozzle_volume_types[0] == std::vector<NozzleVolumeType>{nvtStandard}); + REQUIRE(nozzle_volume_types[1] == std::vector<NozzleVolumeType>{nvtHighFlow}); + } + + SECTION("a mixed-nozzle extruder contributes one slot per volume type, ascending enum order") { + DynamicPrintConfig config; + // list High Flow first in the token string: parsing must still order Standard before High Flow + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#3", "High Flow#3|Standard#3"}; + REQUIRE(config.get_extruder_nozzle_volume_count(2, nozzle_volume_types) == 3); + REQUIRE(nozzle_volume_types[0] == std::vector<NozzleVolumeType>{nvtStandard}); + REQUIRE(nozzle_volume_types[1] == std::vector<NozzleVolumeType>({nvtStandard, nvtHighFlow})); + } +} + +TEST_CASE("update_values_to_printer_extruders expands one slot per (extruder x volume type)", "[Config]") +{ + SECTION("Hybrid extruder yields three slots, extruder-ascending then volume-ascending") { + DynamicPrintConfig config = make_hybrid_printer_config(); + add_print_variant_columns(config); + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + REQUIRE(count == 3); + + std::vector<int> variant_index = config.update_values_to_printer_extruders(config, extruder_count, count, nozzle_volume_types, + print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + + REQUIRE(variant_index == std::vector<int>({0, 2, 3})); + REQUIRE(config.option<ConfigOptionFloats>("outer_wall_speed")->values == std::vector<double>({30., 50., 500.})); + REQUIRE(config.option<ConfigOptionInts>("print_extruder_id")->values == std::vector<int>({1, 2, 2})); + REQUIRE(config.option<ConfigOptionStrings>("print_extruder_variant")->values == + std::vector<std::string>({"Direct Drive Standard", "Direct Drive Standard", "Direct Drive High Flow"})); + } + + SECTION("stride-2 options keep (normal, silent) pairs together per slot") { + DynamicPrintConfig config = make_hybrid_printer_config(); + config.option<ConfigOptionInts>("printer_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("printer_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("machine_max_speed_x", true)->values = {100., 50., 110., 55., 120., 60., 130., 65.}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + std::vector<int> variant_index = config.update_values_to_printer_extruders(config, extruder_count, count, nozzle_volume_types, + printer_options_with_variant_2, "printer_extruder_id", "printer_extruder_variant", 2); + + REQUIRE(variant_index == std::vector<int>({0, 2, 3})); + REQUIRE(config.option<ConfigOptionFloats>("machine_max_speed_x")->values == + std::vector<double>({100., 50., 120., 60., 130., 65.})); + } + + SECTION("single-slot expansion on a Hybrid extruder resolves via the filament volume type") { + DynamicPrintConfig printer_config = make_hybrid_printer_config(); + + DynamicPrintConfig filament_config; + filament_config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow"}; + filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed", true)->values = {12., 20.}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = printer_config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + SECTION("default filament volume type selects the Standard column") { + std::vector<int> variant_index = filament_config.update_values_to_printer_extruders(printer_config, extruder_count, count, + nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, 2); + REQUIRE(variant_index == std::vector<int>({0})); + REQUIRE(filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({12.})); + } + + SECTION("a High Flow filament volume type selects the High Flow column") { + std::vector<int> variant_index = filament_config.update_values_to_printer_extruders(printer_config, extruder_count, count, + nozzle_volume_types, filament_options_with_variant, "", "filament_extruder_variant", 1, 2, nvtHighFlow); + REQUIRE(variant_index == std::vector<int>({1})); + REQUIRE(filament_config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({20.})); + } + } + + SECTION("an extruder without per-type stats does not overrun the slot table when another is Hybrid") { + DynamicPrintConfig config; + // e0 carries no per-type stats (empty entry), so the summed volume-type count (2) does + // not exceed the extruder count even though the Hybrid e1 emits one slot per volume type. + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"", "Standard#3|High Flow#3"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + add_print_variant_columns(config); + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + REQUIRE(count == 2); + REQUIRE(nozzle_volume_types[0].empty()); + + std::vector<int> variant_index = config.update_values_to_printer_extruders(config, extruder_count, count, nozzle_volume_types, + print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + + // e0 resolves by its configured type; the Hybrid e1 emits one slot per stats volume type + REQUIRE(variant_index == std::vector<int>({0, 2, 3})); + REQUIRE(config.option<ConfigOptionFloats>("outer_wall_speed")->values == std::vector<double>({30., 50., 500.})); + } + + SECTION("without Hybrid or extra slots the expansion matches the per-extruder resolution") { + DynamicPrintConfig config; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHighFlow}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + add_print_variant_columns(config); + + // compute what the per-extruder loop resolves directly, before the arrays are rewritten + std::vector<int> expected_index; + for (int e_index = 0; e_index < 2; e_index++) + expected_index.push_back(config.get_index_for_extruder(e_index + 1, "print_extruder_id", etDirectDrive, + e_index == 0 ? nvtStandard : nvtHighFlow, "print_extruder_variant")); + REQUIRE(expected_index == std::vector<int>({0, 3})); + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + REQUIRE(count == 2); + + std::vector<int> variant_index = config.update_values_to_printer_extruders(config, extruder_count, count, nozzle_volume_types, + print_options_with_variant, "print_extruder_id", "print_extruder_variant"); + + REQUIRE(variant_index == expected_index); + REQUIRE(config.option<ConfigOptionFloats>("outer_wall_speed")->values == std::vector<double>({30., 500.})); + } +} + +TEST_CASE("update_values_to_printer_extruders_for_multiple_filaments resolves per-filament slots", "[Config]") +{ + auto make_filament_arrays = [](DynamicPrintConfig &config) { + config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("filament_max_volumetric_speed", true)->values = {12., 20., 13., 21.}; + }; + + std::set<std::string> filament_keys = filament_options_with_variant; + filament_keys.insert("filament_self_index"); + + SECTION("filament_volume_map picks the concrete volume type on a Hybrid extruder") { + DynamicPrintConfig config = make_hybrid_printer_config(); + make_filament_arrays(config); + config.option<ConfigOptionInts>("filament_map", true)->values = {2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {nvtStandard, nvtHighFlow}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + config.update_values_to_printer_extruders_for_multiple_filaments(config, extruder_count, count, filament_keys, + "filament_self_index", "filament_extruder_variant"); + + REQUIRE(config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({12., 21.})); + REQUIRE(config.option<ConfigOptionStrings>("filament_extruder_variant")->values == + std::vector<std::string>({"Direct Drive Standard", "Direct Drive High Flow"})); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>({1, 2})); + } + + SECTION("a volume map not sized to the filament count is ignored") { + DynamicPrintConfig config = make_hybrid_printer_config(); + make_filament_arrays(config); + config.option<ConfigOptionInts>("filament_map", true)->values = {2, 2}; + // the registered default is a single-element vector; it must not override slot resolution + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {nvtStandard}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + config.update_values_to_printer_extruders_for_multiple_filaments(config, extruder_count, count, filament_keys, + "filament_self_index", "filament_extruder_variant"); + + // Hybrid resolves as Standard when no usable per-filament map exists + REQUIRE(config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({12., 13.})); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>({1, 2})); + } + + SECTION("a single-filament explicit assignment on a Hybrid extruder is honored") { + DynamicPrintConfig config = make_hybrid_printer_config(); + config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1}; + config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("filament_max_volumetric_speed", true)->values = {12., 20.}; + config.option<ConfigOptionInts>("filament_map", true)->values = {2}; + // sized to the (single) filament count: the producers guarantee sizing, so a + // single-filament map is as trustworthy as any other and the explicit High Flow + // request must win over the Hybrid->Standard fallback + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {nvtHighFlow}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + + config.update_values_to_printer_extruders_for_multiple_filaments(config, extruder_count, count, filament_keys, + "filament_self_index", "filament_extruder_variant"); + + REQUIRE(config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({20.})); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>({1})); + } + + SECTION("without Hybrid or extra slots the volume map is not consulted") { + DynamicPrintConfig config; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHighFlow}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + make_filament_arrays(config); + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2}; + // sized to the filament count, but inert because no extruder exposes multiple volume types + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {nvtHighFlow, nvtStandard}; + + std::vector<std::vector<NozzleVolumeType>> nozzle_volume_types; + int extruder_count = 2; + int count = config.get_extruder_nozzle_volume_count(extruder_count, nozzle_volume_types); + REQUIRE(count == 2); + + config.update_values_to_printer_extruders_for_multiple_filaments(config, extruder_count, count, filament_keys, + "filament_self_index", "filament_extruder_variant"); + + // filament 1 keeps its extruder's Standard column, filament 2 its extruder's High Flow column + REQUIRE(config.option<ConfigOptionFloats>("filament_max_volumetric_speed")->values == std::vector<double>({12., 21.})); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>({1, 2})); + } +} diff --git a/tests/libslic3r/test_nozzle_volume_type.cpp b/tests/libslic3r/test_nozzle_volume_type.cpp new file mode 100644 index 0000000000..0542bde6af --- /dev/null +++ b/tests/libslic3r/test_nozzle_volume_type.cpp @@ -0,0 +1,31 @@ +#include <catch2/catch_all.hpp> + +#include "libslic3r/PrintConfig.hpp" + +using namespace Slic3r; + +TEST_CASE("convert_to_nvt_type maps extruder variant strings to nozzle volume types", "[Config]") +{ + SECTION("Direct Drive variants") { + REQUIRE(convert_to_nvt_type("Direct Drive Standard") == nvtStandard); + REQUIRE(convert_to_nvt_type("Direct Drive High Flow") == nvtHighFlow); + REQUIRE(convert_to_nvt_type("Direct Drive TPU High Flow") == nvtTPUHighFlow); + } + + SECTION("Bowden variants") { + REQUIRE(convert_to_nvt_type("Bowden Standard") == nvtStandard); + REQUIRE(convert_to_nvt_type("Bowden High Flow") == nvtHighFlow); + } + + SECTION("Unparsable strings fall back to hybrid") { + REQUIRE(convert_to_nvt_type("Unknown Extruder") == nvtHybrid); + REQUIRE(convert_to_nvt_type("") == nvtHybrid); + REQUIRE(convert_to_nvt_type("High Flow") == nvtHybrid); + REQUIRE(convert_to_nvt_type("Direct Drive") == nvtHybrid); + } + + SECTION("Whitespace around the volume-type remainder is trimmed") { + REQUIRE(convert_to_nvt_type("Direct Drive High Flow ") == nvtHighFlow); + REQUIRE(convert_to_nvt_type(" Bowden Standard") == nvtStandard); + } +} diff --git a/tests/libslic3r/test_placeholder_parser.cpp b/tests/libslic3r/test_placeholder_parser.cpp index ec72b72769..14716b0b5e 100644 --- a/tests/libslic3r/test_placeholder_parser.cpp +++ b/tests/libslic3r/test_placeholder_parser.cpp @@ -52,6 +52,11 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { SECTION("math: round(-13.4)") { REQUIRE(parser.process("{round(-13.4)}") == "-13"); } SECTION("math: round(13.6)") { REQUIRE(parser.process("{round(13.6)}") == "14"); } SECTION("math: round(-13.6)") { REQUIRE(parser.process("{round(-13.6)}") == "-14"); } + SECTION("math: round(13.5)") { REQUIRE(parser.process("{round(13.5)}") == "14"); } + SECTION("math: floor(13.9)") { REQUIRE(parser.process("{floor(13.9)}") == "13"); } + SECTION("math: floor(-13.1)") { REQUIRE(parser.process("{floor(-13.1)}") == "-14"); } + SECTION("math: ceil(13.1)") { REQUIRE(parser.process("{ceil(13.1)}") == "14"); } + SECTION("math: ceil(-13.9)") { REQUIRE(parser.process("{ceil(-13.9)}") == "-13"); } SECTION("math: digits(5, 15)") { REQUIRE(parser.process("{digits(5, 15)}") == " 5"); } SECTION("math: digits(5., 15)") { REQUIRE(parser.process("{digits(5., 15)}") == " 5"); } SECTION("math: zdigits(5, 15)") { REQUIRE(parser.process("{zdigits(5, 15)}") == "000000000000005"); } @@ -65,6 +70,8 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") { SECTION("math: interpolate_table(13.84375892476, (0, 0), (20, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13.84375892476, (0, 0), (20, 20))}")) == Catch::Approx(13.84375892476)); } SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(13.)); } SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(20.)); } + // Only the grammar's built-in functions are callable; any other name is an undefined variable and throws. + SECTION("math: a non-built-in function name throws") { REQUIRE_THROWS(parser.process("{sqrt(16)}")); } // regex_replace(subject, /pattern/, replacement): the string-transform primitive. SECTION("regex_replace: strips a file extension") { REQUIRE(parser.process("{regex_replace(\"part.stl\", /\\.[^.]*$/, \"\")}") == "part"); } diff --git a/tests/libslic3r/test_toolordering_nozzle_group.cpp b/tests/libslic3r/test_toolordering_nozzle_group.cpp new file mode 100644 index 0000000000..ae6aac4dbe --- /dev/null +++ b/tests/libslic3r/test_toolordering_nozzle_group.cpp @@ -0,0 +1,936 @@ +#include <catch2/catch_all.hpp> + +#include "libslic3r/FilamentGroupUtils.hpp" +#include "libslic3r/MultiNozzleUtils.hpp" +#include "libslic3r/PrintConfig.hpp" +#include "libslic3r/GCode/ToolOrdering.hpp" +#include "libslic3r/Model.hpp" +#include "libslic3r/Print.hpp" +#include "libslic3r/TriangleMesh.hpp" + +#include <algorithm> +#include <map> +#include <set> +#include <unordered_map> +#include <vector> + +#include <boost/filesystem.hpp> + +// H2C/A2L multi-nozzle filament grouping core. +// +// These tests pin the behaviour of the grouping result type +// (Slic3r::MultiNozzleUtils::LayeredNozzleGroupResult) that GCode consumes via +// group_result->get_nozzle_id(filament, layer) and +// group_result->get_first_nozzle_for_filament(filament)->group_id. +// +// The central requirement is ZERO behaviour change for existing (single-nozzle) +// printers: with extruder_max_nozzle_count == 1 per extruder the result collapses +// to the classic filament->extruder grouping (nozzle id == extruder id). + +using namespace Slic3r; +using namespace Slic3r::MultiNozzleUtils; + +namespace { +// Build a trivial "one logical nozzle per extruder" list, the single-nozzle case +// that every current printer profile produces. +std::vector<NozzleInfo> single_nozzle_per_extruder(int extruder_count) +{ + std::vector<NozzleInfo> nozzle_list; + for (int e = 0; e < extruder_count; ++e) { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; + n.extruder_id = e; + n.group_id = e; // one nozzle per extruder => nozzle id == extruder id + nozzle_list.push_back(n); + } + return nozzle_list; +} +} // namespace + +TEST_CASE("Multi-nozzle gate predicate mirrors BambuStudio", "[ToolOrdering][H2C]") +{ + // The multi-nozzle gate: std::any_of(extruder_max_nozzle_count > 1). + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + + auto *opt = config.option<ConfigOptionIntsNullable>("extruder_max_nozzle_count"); + REQUIRE(opt != nullptr); // extruder_max_nozzle_count must be a real config option + + // extruder_nozzle_stats must be a real config option so printer profiles and + // 3mf projects round-trip the per-extruder nozzle inventory (GUI producers wire it later). + REQUIRE(config.option<ConfigOptionStrings>("extruder_nozzle_stats") != nullptr); + + auto has_multiple_nozzle = [](const std::vector<int> &values) { + return std::any_of(values.begin(), values.end(), [](int v) { return v > 1; }); + }; + + // Default for every existing printer: 1 nozzle per extruder => gate is closed. + REQUIRE_FALSE(has_multiple_nozzle(opt->values)); + + // Synthetic H2C-like machine: extruder 1 is a 6-nozzle cluster => gate opens. + REQUIRE(has_multiple_nozzle(std::vector<int>{1, 6})); +} + +TEST_CASE("Single-nozzle grouping: every filament maps to its extruder nozzle", "[ToolOrdering][H2C]") +{ + SECTION("single extruder => all filaments map to nozzle 0") + { + auto nozzle_list = single_nozzle_per_extruder(1); + // 3 filaments, all assigned to the single extruder 0. + std::vector<int> filament_nozzle_map = {0, 0, 0}; + std::vector<unsigned int> used_filaments = {0, 1, 2}; + + auto group_opt = LayeredNozzleGroupResult::create(filament_nozzle_map, nozzle_list, used_filaments); + REQUIRE(group_opt.has_value()); + auto &group = *group_opt; + + for (int f = 0; f < 3; ++f) { + REQUIRE(group.get_nozzle_id(f) == 0); + REQUIRE(group.get_extruder_id(f) == 0); + auto first = group.get_first_nozzle_for_filament(f); + REQUIRE(first.has_value()); + REQUIRE(first->group_id == 0); + } + REQUIRE_FALSE(group.is_support_dynamic_nozzle_map()); + } + + SECTION("dual extruder => nozzle id equals the classic extruder grouping") + { + auto nozzle_list = single_nozzle_per_extruder(2); + // filament -> extruder map (the map Orca's reorder already computes). + std::vector<int> filament_map = {0, 1, 0, 1}; + std::vector<unsigned int> used_filaments = {0, 1, 2, 3}; + + auto group_opt = LayeredNozzleGroupResult::create(filament_map, nozzle_list, used_filaments); + REQUIRE(group_opt.has_value()); + auto &group = *group_opt; + + REQUIRE(group.get_nozzle_id(0) == 0); + REQUIRE(group.get_nozzle_id(1) == 1); + REQUIRE(group.get_nozzle_id(2) == 0); + REQUIRE(group.get_nozzle_id(3) == 1); + // With one nozzle per extruder, nozzle id and extruder id agree. + for (int f = 0; f < 4; ++f) + REQUIRE(group.get_nozzle_id(f) == group.get_extruder_id(f)); + } +} + +TEST_CASE("H2C multi-nozzle: filaments get distinct nozzles on the 6-nozzle extruder", "[ToolOrdering][H2C]") +{ + // Synthetic H2C-like config: 2 extruders, extruder_max_nozzle_count = {1, 6}, + // 4 filaments all assigned to extruder 1 (0-based). Each filament requests a + // distinct logical nozzle cluster (as the grouping algorithm would emit), so the + // create() overload must resolve them to 4 distinct physical nozzles. + std::vector<unsigned int> used_filaments = {0, 1, 2, 3}; + std::vector<int> filament_map = {1, 1, 1, 1}; // extruder 1 + std::vector<int> filament_volume_map = {0, 0, 0, 0}; // nvtStandard + std::vector<int> filament_nozzle_map = {0, 1, 2, 3}; // distinct clusters + + std::vector<std::map<NozzleVolumeType, int>> nozzle_count(2); + nozzle_count[0] = {}; // extruder 0: 1-nozzle (unused here) + nozzle_count[1] = {{nvtStandard, 6}}; // extruder 1: 6-nozzle cluster + + auto group_opt = LayeredNozzleGroupResult::create( + used_filaments, filament_map, filament_volume_map, filament_nozzle_map, nozzle_count, 0.4f); + REQUIRE(group_opt.has_value()); + auto &group = *group_opt; + + // All four filaments live on extruder 1, on four distinct physical nozzles. + std::set<int> distinct_nozzles; + for (int f = 0; f < 4; ++f) { + REQUIRE(group.get_extruder_id(f) == 1); + int nid = group.get_nozzle_id(f); + REQUIRE(nid >= 0); + distinct_nozzles.insert(nid); + } + REQUIRE(distinct_nozzles.size() == 4); + + // get_nozzle_id must be stable across layers (no per-layer / selector map here). + for (int f = 0; f < 4; ++f) { + int base = group.get_nozzle_id(f, -1); + REQUIRE(group.get_nozzle_id(f, 0) == base); + REQUIRE(group.get_nozzle_id(f, 5) == base); + } + + // first-nozzle lookup agrees with the per-layer lookup for a static map. + for (int f = 0; f < 4; ++f) { + auto first = group.get_first_nozzle_for_filament(f); + REQUIRE(first.has_value()); + REQUIRE(first->extruder_id == 1); + REQUIRE(first->group_id == group.get_nozzle_id(f)); + } +} + +TEST_CASE("H2C dynamic selector: per-layer nozzle ids reach the g-code surface", "[ToolOrdering][H2C][Dynamic]") +{ + // The per-layer regroup engine + // (plan_filament_mapping_and_order_by_combo_ranges -> 4-arg LayeredNozzleGroupResult::create) + // produces a *selector* result whose filament->nozzle map varies across layers. This is exactly + // what GCode reads for H2C dynamic mode: hotend_id_for_gcode_placeholder / + // nozzle_id_for_gcode_placeholder call group->is_support_dynamic_nozzle_map() and, when true, + // group->get_nozzle_id(filament, layer) / get_first_nozzle_for_filament(filament). Here we build + // the selector result directly (the engine's output shape) and assert those accessors return + // per-layer values -- the surface that "goes live" only in dynamic mode. The static path (every + // other test above) keeps is_support_dynamic_nozzle_map() == false and a stable nozzle id, so its + // g-code is unchanged. + + // H2C-like fleet: extruder 0 = 1 nozzle (group 0), extruder 1 = a 3-nozzle rack (groups 1..3). + std::vector<NozzleInfo> nozzle_list; + for (int g = 0; g < 4; ++g) { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; + n.extruder_id = (g == 0) ? 0 : 1; + n.group_id = g; + nozzle_list.push_back(n); + } + + // Three filaments; filament 2 is reassigned from physical nozzle 2 (layers 0-1) to nozzle 3 + // (layers 2-3) by the per-layer selector -- the case that sets support_dynamic_nozzle_map. + std::vector<std::vector<int>> layer_filament_nozzle_maps = { + {0, 1, 2}, // layer 0 + {0, 1, 2}, // layer 1 + {0, 1, 3}, // layer 2: filament 2 moved to nozzle 3 + {0, 1, 3}, // layer 3 + }; + std::vector<std::vector<unsigned int>> layer_filament_sequences = { + {0, 1, 2}, {0, 1, 2}, {0, 1, 2}, {0, 1, 2}, + }; + std::vector<unsigned int> used_filaments = {0, 1, 2}; + + auto group_opt = LayeredNozzleGroupResult::create(layer_filament_nozzle_maps, nozzle_list, used_filaments, layer_filament_sequences); + REQUIRE(group_opt.has_value()); + auto &group = *group_opt; + + // The selector is active: a filament maps to more than one physical nozzle across layers. + REQUIRE(group.is_support_dynamic_nozzle_map()); + + // Per-layer hotend/nozzle ids -- the values the dynamic g-code placeholders emit. + REQUIRE(group.get_nozzle_id(2, 0) == 2); + REQUIRE(group.get_nozzle_id(2, 1) == 2); + REQUIRE(group.get_nozzle_id(2, 2) == 3); // reassigned on layer 2 + REQUIRE(group.get_nozzle_id(2, 3) == 3); + REQUIRE(group.get_extruder_id(2, 0) == 1); + REQUIRE(group.get_extruder_id(2, 2) == 1); + + // Unmoved filaments keep a stable id across layers. + REQUIRE(group.get_nozzle_id(0, 0) == 0); + REQUIRE(group.get_nozzle_id(0, 3) == 0); + REQUIRE(group.get_nozzle_id(1, 0) == 1); + REQUIRE(group.get_nozzle_id(1, 3) == 1); + + // first-nozzle lookup (used by the *_first_* placeholders / start g-code) is the first layer's id. + auto first2 = group.get_first_nozzle_for_filament(2); + REQUIRE(first2.has_value()); + REQUIRE(first2->group_id == 2); + + // every physical nozzle a filament visits is reported (3mf metadata / nozzle_diameters_by_nozzle_id). + std::set<int> fil2_nozzles; + for (const auto &n : group.get_nozzles_for_filament(2)) + fil2_nozzles.insert(n.group_id); + REQUIRE(fil2_nozzles == std::set<int>({2, 3})); +} + +TEST_CASE("Multi-nozzle reorder tolerates a filament with no nozzle (RL-48)", "[ToolOrdering][H2C][Dynamic]") +{ + // The per-layer engine can hand reorder_filaments_for_multi_nozzle_extruder a group result that + // resolves no nozzle for a layer's filament (a degenerate/malformed input where a layer references + // a filament index outside the grouping map). Unguarded, that dereferences std::max_element() on an + // empty extruder set (SIGSEGV). The guard must instead emit each layer's filaments in order and + // return, so a bad input degrades gracefully rather than crashing. + auto nozzle_list = single_nozzle_per_extruder(2); + std::vector<int> filament_nozzle_map = {0}; // map only covers filament 0 + auto group_opt = LayeredNozzleGroupResult::create(filament_nozzle_map, nozzle_list, std::vector<unsigned int>{0}); + REQUIRE(group_opt.has_value()); + + std::vector<unsigned int> filament_lists = {3}; // filament 3 resolves to no nozzle + std::vector<std::vector<unsigned int>> layer_filaments = {{3}, {3}}; + std::vector<std::vector<std::vector<float>>> flush_matrix(2, {{0.f}}); // unused on the guard path + std::vector<std::vector<unsigned int>> sequences; + + REQUIRE_NOTHROW(reorder_filaments_for_multi_nozzle_extruder(filament_lists, *group_opt, layer_filaments, flush_matrix, nullptr, &sequences)); + // Each layer still gets a valid sequence (its own filaments) — no reorder, no crash. + REQUIRE(sequences.size() == layer_filaments.size()); + REQUIRE(sequences[0] == std::vector<unsigned int>{3}); + REQUIRE(sequences[1] == std::vector<unsigned int>{3}); +} + +// The round-robin build_multi_nozzle_group_result adapter was superseded by the +// nozzle-centric FilamentGroup engine (get_recommended_filament_maps now decides nozzle co-location +// by flush cost, not round-robin). The two former pipeline tests are dropped: +// * H2C multi-nozzle physical-nozzle resolution (6-arg create) is covered above by the +// "H2C multi-nozzle: filaments get distinct nozzles" case; +// * the single-nozzle "nozzle id == extruder id" degradation is covered above by the +// "Single-nozzle grouping" case (build_default_nozzle_list + 3-arg create is the exact path the +// gate-closed branch and by-object fallback use); +// * end-to-end H2C/H2D grouping co-location is now pinned by the filament_group golden suite +// (tests/filament_group, config_b/config_c). + +TEST_CASE("extruder_nozzle_stats round-trips through save/parse", "[ToolOrdering][H2C]") +{ + // The per-extruder nozzle inventory must survive save_extruder_nozzle_stats_to_string -> + // get_extruder_nozzle_stats unchanged, so printer presets and 3mf projects persist it. + std::vector<std::map<NozzleVolumeType, int>> stats = { + {{nvtStandard, 1}}, // extruder 0: single standard nozzle + {{nvtStandard, 5}, {nvtHighFlow, 1}}, // extruder 1: 6-nozzle mixed cluster + }; + REQUIRE(get_extruder_nozzle_stats(save_extruder_nozzle_stats_to_string(stats)) == stats); +} + +// The filament-change-time model (MultiNozzleUtils::simulate_filament_change_time) is self-contained +// analytic code with no slicing-pipeline caller yet; these fixtures pin its numeric output so future +// changes and its first consumer (the filament_group golden harness) build on a locked model. Expected +// values are hand-traced through the AMS -> selector -> extruder transport model. +TEST_CASE("Filament-change-time model matches the BBS analytic simulation", "[MultiNozzle][H2C][ChangeTime]") +{ + using Catch::Matchers::WithinAbs; + + // Load/unload constants mirror the golden config_c change_time_params + // (selector 1/1, standard 3/2): a selector move costs 1, a full AMS load 3 / unload 2. + FilamentChangeTimeParams params; + params.selector_load_time = 1.0f; + params.selector_unload_time = 1.0f; + params.standard_load_time = 3.0f; + params.standard_unload_time = 2.0f; + + // One extruder carrying one physical nozzle (nozzle id == extruder id == 0). + std::vector<NozzleInfo> nozzle_list(1); + nozzle_list[0].diameter = "0.4"; + nozzle_list[0].volume_type = nvtStandard; + nozzle_list[0].extruder_id = 0; + nozzle_list[0].group_id = 0; + + // Two filaments in distinct AMS groups, printed in the order A, B, A on nozzle 0. + std::vector<int> logical_filaments = {0, 1}; + std::vector<int> group_of_filament = {0, 1}; + std::vector<int> filament_change_seq = {0, 1, 0}; + std::vector<int> nozzle_change_seq = {0, 0, 0}; + + SECTION("no AMS pre-load: each change is a full AMS<->extruder transport") + { + auto r = simulate_filament_change_time( + logical_filaments, nozzle_list, filament_change_seq, nozzle_change_seq, + group_of_filament, params, /*ams_preload_enabled=*/{}, /*calc_sliced_time=*/true); + // load0(3) + [unload0(2)+load1(3)] + [unload1(2)+load0(3)] = 13 + REQUIRE_THAT(r.actual_time, WithinAbs(13.0, 1e-6)); + // Single nozzle, no selector overlap => slicer estimate equals the actual time. + REQUIRE_THAT(r.sliced_time, WithinAbs(13.0, 1e-6)); + } + + SECTION("AMS pre-load overlaps transport, shrinking the actual time") + { + std::vector<bool> preload = {true, true}; + auto r = simulate_filament_change_time( + logical_filaments, nozzle_list, filament_change_seq, nozzle_change_seq, + group_of_filament, params, preload, /*calc_sliced_time=*/false); + // Pre-loading the next filament into the selector runs in parallel with the current + // extruder move, so the selector<->extruder legs dominate: 3 + (1+1) + (1+1) = 7. + REQUIRE_THAT(r.actual_time, WithinAbs(7.0, 1e-6)); + } + + SECTION("degenerate inputs return zero") + { + auto r = simulate_filament_change_time({}, nozzle_list, filament_change_seq, + nozzle_change_seq, {}, params); + REQUIRE_THAT(r.actual_time, WithinAbs(0.0, 1e-6)); + REQUIRE_THAT(r.sliced_time, WithinAbs(0.0, 1e-6)); + } +} + +TEST_CASE("NozzleStatusRecorder tracks nozzle/extruder occupancy", "[MultiNozzle][H2C][ChangeTime]") +{ + NozzleStatusRecorder rec; + REQUIRE(rec.is_nozzle_empty(0)); + REQUIRE(rec.get_filament_in_nozzle(0) == -1); + REQUIRE(rec.get_nozzle_in_extruder(0) == -1); + + rec.set_nozzle_status(2, 5, 1); // nozzle 2 holds filament 5, mounted on extruder 1 + REQUIRE_FALSE(rec.is_nozzle_empty(2)); + REQUIRE(rec.get_filament_in_nozzle(2) == 5); + REQUIRE(rec.get_nozzle_in_extruder(1) == 2); + + rec.clear_nozzle_status(2); + REQUIRE(rec.is_nozzle_empty(2)); + REQUIRE(rec.get_filament_in_nozzle(2) == -1); + // Clearing a nozzle leaves the extruder->nozzle association intact. + REQUIRE(rec.get_nozzle_in_extruder(1) == 2); +} + +TEST_CASE("Hybrid nozzle stats resolve to concrete volume types", "[ToolOrdering][H2C]") +{ + // Extruder 0 is Standard-only; extruder 1 carries a mixed Standard + High Flow inventory + // (the "Hybrid" flow selection). The write-back pipeline persists get_volume_map(), so the + // result must always carry concrete per-filament volume types, never the Hybrid seed. + auto stats = get_extruder_nozzle_stats({"Standard#1", "Standard#1|High Flow#1"}); + REQUIRE(stats.size() == 2); + REQUIRE(stats[1].size() == 2); + + std::vector<unsigned int> used_filaments = {0, 1, 2}; + std::vector<int> filament_map = {0, 1, 1}; // 0-based extruder ids + std::vector<int> volume_requests = {(int) nvtStandard, (int) nvtHighFlow, (int) nvtStandard}; + std::vector<int> nozzle_requests = {0, 1, 2}; // distinct logical nozzles + + auto group = LayeredNozzleGroupResult::create(used_filaments, filament_map, volume_requests, nozzle_requests, stats, 0.4f); + REQUIRE(group.has_value()); + + auto volume_map = group->get_volume_map(); + REQUIRE(volume_map == volume_requests); + for (auto fid : used_filaments) + REQUIRE(volume_map[fid] != (int) nvtHybrid); + + // The Hybrid seed itself matches no physical nozzle: such a request is unsatisfiable. + std::vector<int> hybrid_requests = {(int) nvtStandard, (int) nvtHybrid, (int) nvtStandard}; + REQUIRE_FALSE(LayeredNozzleGroupResult::create(used_filaments, filament_map, hybrid_requests, nozzle_requests, stats, 0.4f).has_value()); +} + +TEST_CASE("update_used_filament_values merges only used filaments", "[ToolOrdering][H2C]") +{ + // The config write-back merges the engine's per-filament values over the config baseline: + // used filaments adopt the engine value, unused filaments keep their config assignment. + std::vector<int> old_values = {1, 1, 2, 1}; + std::vector<int> new_values = {2, 2, 1, 2}; + std::vector<unsigned int> used = {0, 2}; + + auto merged = FilamentGroupUtils::update_used_filament_values(old_values, new_values, used); + REQUIRE(merged == std::vector<int>{2, 1, 1, 1}); + + // No used filaments => the config baseline is returned untouched. + REQUIRE(FilamentGroupUtils::update_used_filament_values(old_values, new_values, {}) == old_values); +} + +TEST_CASE("Print config-index resolvers pick per-filament Hybrid slots", "[Print][H2C]") +{ + // A 2-extruder printer whose second extruder is Hybrid (Standard + High Flow nozzles). + // The preset-style variant columns carry one column per (extruder x volume type); apply() + // expands them to the 3-slot layout [e1-Std, e2-Std, e2-HF]. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("outer_wall_speed", true)->values = {30., 200., 50., 500.}; + + // Three filaments: 0 -> extruder 1 (Std), 1 -> extruder 2 (Std), 2 -> extruder 2 (High Flow). + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtHighFlow}; + + Model model; + model.add_object("cube", "", make_cube(20, 20, 20))->add_instance(); + + Print print; + print.apply(model, config); + + // Stub grouping result mirroring the maps above: one nozzle per (extruder, volume type). + std::vector<NozzleInfo> nozzle_list; + { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; n.extruder_id = 0; n.group_id = 0; nozzle_list.push_back(n); + n.volume_type = nvtStandard; n.extruder_id = 1; n.group_id = 1; nozzle_list.push_back(n); + n.volume_type = nvtHighFlow; n.extruder_id = 1; n.group_id = 2; nozzle_list.push_back(n); + } + std::vector<unsigned int> used_filaments = {0, 1, 2}; + auto group = LayeredNozzleGroupResult::create(std::vector<int>{0, 1, 2}, nozzle_list, used_filaments); + REQUIRE(group.has_value()); + print.set_nozzle_group_result(std::make_shared<LayeredNozzleGroupResult>(*group)); + + // The write-back re-expands the config and refreshes the resolver caches. + print.update_filament_maps_to_config({1, 2, 2}, {(int) nvtStandard, (int) nvtStandard, (int) nvtHighFlow}, {0, 1, 2}); + + // The expansion must have produced the 3-slot layout the resolvers index into. + const auto ®ion_config = print.default_region_config(); + REQUIRE(region_config.print_extruder_variant.values == + std::vector<std::string>({"Direct Drive Standard", "Direct Drive Standard", "Direct Drive High Flow"})); + REQUIRE(region_config.print_extruder_id.values == std::vector<int>({1, 2, 2})); + + SECTION("each filament resolves to its own (extruder x volume type) slot") { + REQUIRE(print.get_nozzle_config_index(0, 0) == 0); // extruder 1, Standard + REQUIRE(print.get_nozzle_config_index(1, 0) == 1); // extruder 2, Standard + REQUIRE(print.get_nozzle_config_index(2, 0) == 2); // extruder 2, High Flow + } + + SECTION("without a group result the resolver falls back to the filament's extruder slot") { + print.set_nozzle_group_result(nullptr); + REQUIRE(print.get_nozzle_config_index(0, 0) == 0); + REQUIRE(print.get_nozzle_config_index(1, 0) == 1); + REQUIRE(print.get_nozzle_config_index(2, 0) == 1); // extruder slot, not the High Flow slot + } +} + +TEST_CASE("Re-applying an unchanged config after slicing keeps the result valid", "[Print][H2C]") +{ + // apply() rebuilds m_config.filament_map_2 to the real per-filament slot map, while the + // incoming full config only ever carries the ConfigDef default for it. The engine-derived + // key must therefore be kept out of the apply diff: the GUI re-applies right after slicing + // completes, and a phantom filament_map_2 diff would invalidate every freshly sliced result + // on any multi-extruder printer. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtHighFlow}; + + Model model; + ModelObject *object = model.add_object("cube", "", make_cube(20, 20, 20)); + object->add_instance()->set_offset(Vec3d(100., 100., 0.)); + + Print print; + print.apply(model, config); + print.process(); + REQUIRE(print.is_step_done(psSlicingFinished)); + + auto status = print.apply(model, config); + REQUIRE(status != PrintBase::APPLY_STATUS_INVALIDATED); + REQUIRE(print.is_step_done(psSlicingFinished)); +} + +TEST_CASE("normalize_nozzle_map_per_layer makes per-filament assignments gap-free", "[MultiNozzle][H2C][Dynamic]") +{ + SECTION("gaps inherit the last used nozzle, entries on used layers stay untouched") { + // Filament 1 extrudes on layers 0 (nozzle 1) and 3 (nozzle 2); the planner leaves stale + // entries on the layers in between. + std::vector<std::vector<int>> maps = { + {0, 1}, + {0, -1}, // filament 1 idle + {0, -1}, // filament 1 idle + {0, 2}, + }; + std::vector<std::vector<unsigned int>> filaments = {{0, 1}, {0}, {0}, {0, 1}}; + + normalize_nozzle_map_per_layer(maps, filaments); + + REQUIRE(maps[0] == std::vector<int>({0, 1})); + REQUIRE(maps[1] == std::vector<int>({0, 1})); // carried forward + REQUIRE(maps[2] == std::vector<int>({0, 1})); // carried forward + REQUIRE(maps[3] == std::vector<int>({0, 2})); // used layer untouched + } + + SECTION("layers before a filament's first use inherit its first nozzle") { + std::vector<std::vector<int>> maps = { + {0, -1}, + {0, -1}, + {0, 3}, // filament 1 first extrudes here + }; + std::vector<std::vector<unsigned int>> filaments = {{0}, {0}, {0, 1}}; + + normalize_nozzle_map_per_layer(maps, filaments); + + REQUIRE(maps[0] == std::vector<int>({0, 3})); // back-filled + REQUIRE(maps[1] == std::vector<int>({0, 3})); // back-filled + REQUIRE(maps[2] == std::vector<int>({0, 3})); + } + + SECTION("empty and ragged inputs are safe no-ops") { + std::vector<std::vector<int>> empty_maps; + std::vector<std::vector<unsigned int>> no_filaments; + REQUIRE_NOTHROW(normalize_nozzle_map_per_layer(empty_maps, no_filaments)); + REQUIRE(empty_maps.empty()); + + // Rows of different widths and a filament list shorter than the map list. + std::vector<std::vector<int>> ragged = {{0}, {0, 1, 2}}; + std::vector<std::vector<unsigned int>> short_filaments = {{0}}; + REQUIRE_NOTHROW(normalize_nozzle_map_per_layer(ragged, short_filaments)); + REQUIRE(ragged[0] == std::vector<int>({0})); + } + + SECTION("a single layer is left unchanged") { + std::vector<std::vector<int>> maps = {{2, 1, 0}}; + std::vector<std::vector<unsigned int>> filaments = {{0, 1, 2}}; + normalize_nozzle_map_per_layer(maps, filaments); + REQUIRE(maps[0] == std::vector<int>({2, 1, 0})); + } +} + +TEST_CASE("Stitched sequential blocks resolve per-layer after normalization", "[MultiNozzle][H2C][Dynamic]") +{ + // Shape of the sequential (by-object) stitch: two per-object plan blocks concatenated on one + // global layer axis, where the second object's plan moves filament 1 to another physical + // nozzle. After normalization the 4-arg create() must detect the migration (selector result) + // and resolve stable ids inside each object's layer range. + std::vector<NozzleInfo> nozzle_list; + for (int g = 0; g < 3; ++g) { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; + n.extruder_id = (g == 0) ? 0 : 1; + n.group_id = g; + nozzle_list.push_back(n); + } + + // Object A (layers 0-1): filament 1 on nozzle 1, filament 0 idle until layer 1. + // Object B (layers 2-3): filament 1 moved to nozzle 2. + std::vector<std::vector<int>> stitched_maps = { + {-1, 1}, + {0, 1}, + {0, 2}, + {0, 2}, + }; + std::vector<std::vector<unsigned int>> stitched_filaments = {{1}, {0, 1}, {0, 1}, {0, 1}}; + std::vector<unsigned int> used_filaments = {0, 1}; + + normalize_nozzle_map_per_layer(stitched_maps, stitched_filaments); + REQUIRE(stitched_maps[0] == std::vector<int>({0, 1})); // filament 0 back-filled to its first nozzle + + auto group_opt = LayeredNozzleGroupResult::create(stitched_maps, nozzle_list, used_filaments, stitched_filaments); + REQUIRE(group_opt.has_value()); + auto &group = *group_opt; + + // A filament on two physical nozzles across the objects => selector result. + REQUIRE(group.is_support_dynamic_nozzle_map()); + REQUIRE(group.get_nozzle_id(1, 0) == 1); + REQUIRE(group.get_nozzle_id(1, 1) == 1); + REQUIRE(group.get_nozzle_id(1, 2) == 2); // second object's range + REQUIRE(group.get_nozzle_id(1, 3) == 2); + // The default (out-of-range) map is the first layer's normalized row. + REQUIRE(group.get_nozzle_id(0, 999) == 0); + REQUIRE(group.get_nozzle_id(1, 999) == 1); +} + +TEST_CASE("Sequential selector prints publish a stitched result and cache the plans", "[Print][H2C][Dynamic]") +{ + // By-object + smart filament assign: the by-object branch of Print::process must plan each + // object with nozzle-status threading, cache the plans for the g-code export, stitch them + // into the published print-wide result, and write the grouping result back to the config + // once (per-object orderings must not churn the config). + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtStandard}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard}; + config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(true)); + config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode", true)->value = FilamentMapMode::fmmAutoForFlush; + config.option<ConfigOptionEnum<PrintSequence>>("print_sequence", true)->value = PrintSequence::ByObject; + // Export validates flush_volumes_matrix as filaments^2 values per head. + config.option<ConfigOptionFloats>("flush_volumes_matrix", true)->values = std::vector<double>(8, 140.); + config.option<ConfigOptionFloats>("flush_multiplier", true)->values = {1., 1.}; + + Model model; + ModelObject *object_a = model.add_object("cube_a", "", make_cube(20, 20, 20)); + ModelInstance *instance_a = object_a->add_instance(); + instance_a->set_offset(Vec3d(70., 100., 0.)); + ModelObject *object_b = model.add_object("cube_b", "", make_cube(20, 20, 20)); + object_b->config.set_key_value("extruder", new ConfigOptionInt(2)); + ModelInstance *instance_b = object_b->add_instance(); + instance_b->set_offset(Vec3d(150., 100., 0.)); + // The sequential instance ordering keys on arrange_order, which validate() assigns before + // process() in the real pipeline (instances tying at 0 get dropped from the ordering); + // initialize it here since the test drives process() directly. + instance_a->arrange_order = 1; + instance_b->arrange_order = 2; + + Print print; + print.apply(model, config); + REQUIRE(print.objects().size() == 2); + print.process(); + REQUIRE(print.is_step_done(psSlicingFinished)); + + auto result = print.get_layered_nozzle_group_result(); + REQUIRE(result != nullptr); + // One cached plan per unique object, and a stitched layer axis spanning both objects. + REQUIRE(print.sequential_dynamic_orderings().size() == 2); + REQUIRE(result->get_layer_count() > 0); + // The write-back mirrors the stitched result's extruder map. + REQUIRE(print.config().filament_map.values == result->get_extruder_map(false)); + // The per-slot filament arrays stay label-consistent whether or not the stitched plan + // actually migrated a filament (one slot per filament, plus one per extra variant). + REQUIRE(print.config().filament_extruder_variant.values.size() == print.config().filament_self_index.values.size()); + REQUIRE(print.config().filament_self_index.values.size() >= print.config().filament_map.values.size()); + + // Export must consume the cached plans and produce g-code without throwing. + boost::filesystem::path gcode_path = boost::filesystem::temp_directory_path() / "orca_seq_dynamic_publish_test.gcode"; + REQUIRE_NOTHROW(print.export_gcode(gcode_path.string(), nullptr, nullptr)); + REQUIRE(boost::filesystem::exists(gcode_path)); + boost::filesystem::remove(gcode_path); +} + +TEST_CASE("Per-variant expansion gives migrating filaments one slot per variant", "[PrintConfig][H2C][Dynamic]") +{ + // The selector write-back rebuilds the filament arrays from the grouping result: a filament + // that prints through several (extruder x volume type) variants keeps one slot per variant, + // and every key grows in lockstep with the self-index / variant labels. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + // Extruder 1 Standard, extruder 2 Hybrid (Standard + High Flow): 3 nozzle slots, 2 extruders. + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + // Two filaments with superset arrays: one column per (filament x variant). + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtHighFlow}; + config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionInts>("nozzle_temperature", true)->values = {220, 230, 240, 250}; + + std::set<std::string> key_set = {"filament_self_index", "filament_extruder_variant", "nozzle_temperature"}; + + auto make_use = [](ExtruderType et, NozzleVolumeType nvt, int extruder_id) { + FilamentVariantUse use; + use.extruder_type = et; + use.nozzle_volume_type = nvt; + use.extruder_id = extruder_id; + return use; + }; + + SECTION("a migrating filament expands, machine slots track each output slot") { + std::unordered_map<int, std::vector<FilamentVariantUse>> uses; + uses[0] = {make_use(etDirectDrive, nvtStandard, 0), make_use(etDirectDrive, nvtHighFlow, 1)}; + uses[1] = {make_use(etDirectDrive, nvtHighFlow, 1)}; + std::vector<int> slot_machine_indices; + config.update_filament_config_values_for_multiple_extruders(config, uses, 2, 3, key_set, + "filament_self_index", "filament_extruder_variant", + &slot_machine_indices); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>{1, 1, 2}); + REQUIRE(config.option<ConfigOptionStrings>("filament_extruder_variant")->values == + std::vector<std::string>({"Direct Drive Standard", "Direct Drive High Flow", "Direct Drive High Flow"})); + REQUIRE(config.option<ConfigOptionInts>("nozzle_temperature")->values == std::vector<int>{220, 230, 250}); + // Slot 0 backs onto extruder 1 Standard; slots 1-2 onto extruder 2 High Flow. + REQUIRE(slot_machine_indices == std::vector<int>{0, 3, 3}); + } + + SECTION("filaments absent from the uses fall back to their static assignment") { + std::unordered_map<int, std::vector<FilamentVariantUse>> uses; + uses[0] = {make_use(etDirectDrive, nvtStandard, 0)}; + // Filament 1 unrouted: filament_map -> extruder 2 (Hybrid) -> volume map -> High Flow. + config.update_filament_config_values_for_multiple_extruders(config, uses, 2, 3, key_set, + "filament_self_index", "filament_extruder_variant"); + REQUIRE(config.option<ConfigOptionInts>("filament_self_index")->values == std::vector<int>{1, 2}); + REQUIRE(config.option<ConfigOptionInts>("nozzle_temperature")->values == std::vector<int>{220, 250}); + } + + SECTION("a mis-sized filament_volume_map is ignored") { + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtHighFlow}; + std::unordered_map<int, std::vector<FilamentVariantUse>> uses; + uses[0] = {make_use(etDirectDrive, nvtStandard, 0)}; + // Unrouted filament 1 keeps the extruder's own typing (Hybrid folds to Standard). + config.update_filament_config_values_for_multiple_extruders(config, uses, 2, 3, key_set, + "filament_self_index", "filament_extruder_variant"); + REQUIRE(config.option<ConfigOptionInts>("nozzle_temperature")->values == std::vector<int>{220, 240}); + } +} + +TEST_CASE("Selector write-back expands migrating filaments and survives re-apply", "[Print][H2C][Dynamic]") +{ + // A filament the per-layer plan moves between nozzle variants must end up with one config + // slot per variant (so per-layer temperatures/retractions resolve correctly), the extruder + // retract overrides must key each slot to its own variant's machine value, and an unchanged + // re-apply must reproduce the expansion instead of trimming it back to one slot per + // filament — a trim-back would diff the freshly written values and invalidate the result. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + // Three filaments: 0 -> extruder 1 (Std), 1 -> extruder 2 (Std), 2 -> extruder 2, migrating + // Standard -> High Flow between layers. Superset arrays: one column per (filament x variant). + // filament_type must be sized to the filament count: the variant-use collection (like the + // full-config producers) keys the per-filament loop on it. + config.option<ConfigOptionStrings>("filament_type", true)->values = {"PLA", "PLA", "PLA"}; + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtStandard}; + config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1, 2, 2, 3, 3}; + config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionInts>("nozzle_temperature", true)->values = {200, 210, 220, 230, 240, 250}; + // The migrating filament's Standard column is nil, so the override merge must fall back to + // the machine value of the Standard slot (not the High Flow one). + config.option<ConfigOptionFloatsNullable>("filament_retraction_length", true)->values = + {0.5, 0.5, 0.6, 0.6, ConfigOptionFloatsNullable::nil_value(), 1.2}; + config.option<ConfigOptionFloats>("retraction_length", true)->values = {0.8, 0.9, 1.0, 1.1}; + + Model model; + model.add_object("cube", "", make_cube(20, 20, 20))->add_instance(); + + Print print; + print.apply(model, config); + + // Stub grouping result: nozzles as in the resolver test; filament 2 prints on the Standard + // nozzle at layer 0 and on the High Flow nozzle at layer 1. + std::vector<NozzleInfo> nozzle_list; + { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; n.extruder_id = 0; n.group_id = 0; nozzle_list.push_back(n); + n.volume_type = nvtStandard; n.extruder_id = 1; n.group_id = 1; nozzle_list.push_back(n); + n.volume_type = nvtHighFlow; n.extruder_id = 1; n.group_id = 2; nozzle_list.push_back(n); + } + std::vector<std::vector<int>> layer_maps = {{0, 1, 1}, {0, 1, 2}}; + std::vector<std::vector<unsigned int>> layer_seqs = {{0, 1, 2}, {0, 1, 2}}; + auto group = LayeredNozzleGroupResult::create(layer_maps, nozzle_list, {0, 1, 2}, layer_seqs); + REQUIRE(group.has_value()); + REQUIRE(group->is_support_dynamic_nozzle_map()); + print.set_nozzle_group_result(std::make_shared<LayeredNozzleGroupResult>(*group)); + + print.update_to_config_by_nozzle_group_result(*group); + + // Filament 2 holds two slots (Standard + High Flow), everything in lockstep. + REQUIRE(print.config().filament_map.values == group->get_extruder_map(false)); + REQUIRE(print.config().filament_self_index.values == std::vector<int>{1, 2, 3, 3}); + REQUIRE(print.config().nozzle_temperature.values == std::vector<int>{200, 220, 240, 250}); + // The layer-aware resolver picks the slot matching each layer's variant. + REQUIRE(print.get_filament_config_indx(2, 0) == 2); + REQUIRE(print.get_filament_config_indx(2, 1) == 3); + // Retract overrides: non-nil slots take the filament value; the nil Standard slot of the + // migrating filament falls back to its own variant's machine value. + const auto &machine_retract = print.full_print_config().option<ConfigOptionFloats>("retraction_length")->values; + int f2_std_machine_slot = print.full_print_config().get_index_for_extruder(2, "print_extruder_id", etDirectDrive, nvtStandard, + "print_extruder_variant"); + REQUIRE(f2_std_machine_slot >= 0); + const std::vector<double> merged_retract = print.config().retraction_length.values; + REQUIRE(merged_retract.size() == 4); + REQUIRE_THAT(merged_retract[0], Catch::Matchers::WithinAbs(0.5, 1e-9)); + REQUIRE_THAT(merged_retract[1], Catch::Matchers::WithinAbs(0.6, 1e-9)); + REQUIRE_THAT(merged_retract[2], Catch::Matchers::WithinAbs(machine_retract[f2_std_machine_slot], 1e-9)); + REQUIRE_THAT(merged_retract[3], Catch::Matchers::WithinAbs(1.2, 1e-9)); + + // Re-apply the unchanged config: the persisted result must reproduce the exact expansion. + auto status = print.apply(model, config); + REQUIRE(status != PrintBase::APPLY_STATUS_INVALIDATED); + REQUIRE(print.config().filament_self_index.values == std::vector<int>{1, 2, 3, 3}); + REQUIRE(print.config().nozzle_temperature.values == std::vector<int>{200, 220, 240, 250}); + REQUIRE(print.config().retraction_length.values == merged_retract); +} + +TEST_CASE("Filaments ordered after a migrator shift columns and the resolver tracks them", "[Print][H2C][Dynamic]") +{ + // When a mid-list filament expands to two columns, every later filament's values move one + // column to the right — a raw get_at(filament_id) lands in the migrator's second column. + // The layer-aware resolver must return the shifted column for both the expanded filament + // arrays and the merged machine overrides. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + // Three filaments: 0 -> extruder 1 (Std), 1 -> extruder 2, migrating Standard -> High Flow + // between layers, 2 -> extruder 2 (Std) — ordered AFTER the migrator. + config.option<ConfigOptionStrings>("filament_type", true)->values = {"PLA", "PLA", "PLA"}; + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtStandard}; + config.option<ConfigOptionInts>("filament_self_index", true)->values = {1, 1, 2, 2, 3, 3}; + config.option<ConfigOptionStrings>("filament_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionInts>("nozzle_temperature", true)->values = {200, 210, 220, 230, 240, 250}; + config.option<ConfigOptionFloatsNullable>("filament_retraction_length", true)->values = {0.5, 0.5, 0.7, 0.9, 1.4, 1.4}; + config.option<ConfigOptionFloats>("retraction_length", true)->values = {0.8, 0.9, 1.0, 1.1}; + + Model model; + model.add_object("cube", "", make_cube(20, 20, 20))->add_instance(); + + Print print; + print.apply(model, config); + + std::vector<NozzleInfo> nozzle_list; + { + NozzleInfo n; + n.diameter = "0.4"; + n.volume_type = nvtStandard; n.extruder_id = 0; n.group_id = 0; nozzle_list.push_back(n); + n.volume_type = nvtStandard; n.extruder_id = 1; n.group_id = 1; nozzle_list.push_back(n); + n.volume_type = nvtHighFlow; n.extruder_id = 1; n.group_id = 2; nozzle_list.push_back(n); + } + // Filament 1: Standard nozzle on layer 0, High Flow nozzle on layer 1; filament 2 stays Standard. + std::vector<std::vector<int>> layer_maps = {{0, 1, 1}, {0, 2, 1}}; + std::vector<std::vector<unsigned int>> layer_seqs = {{0, 1, 2}, {0, 1, 2}}; + auto group = LayeredNozzleGroupResult::create(layer_maps, nozzle_list, {0, 1, 2}, layer_seqs); + REQUIRE(group.has_value()); + REQUIRE(group->is_support_dynamic_nozzle_map()); + print.set_nozzle_group_result(std::make_shared<LayeredNozzleGroupResult>(*group)); + + print.update_to_config_by_nozzle_group_result(*group); + + // Filament 1 holds columns 1-2; filament 2's values shift to column 3. + REQUIRE(print.config().filament_self_index.values == std::vector<int>{1, 2, 2, 3}); + REQUIRE(print.config().nozzle_temperature.values == std::vector<int>{200, 220, 230, 240}); + // The migrator resolves per layer to its two columns. + REQUIRE(print.get_filament_config_indx(1, 0) == 1); + REQUIRE(print.get_filament_config_indx(1, 1) == 2); + // The filament after it no longer lives at its raw index on any layer. + REQUIRE(print.get_filament_config_indx(2, 0) == 3); + REQUIRE(print.get_filament_config_indx(2, 1) == 3); + // Merged machine override: filament 2's value sits in the shifted column, while a raw + // get_at(2) would read the migrator's High Flow column. + const std::vector<double> merged = print.config().retraction_length.values; + REQUIRE(merged.size() == 4); + REQUIRE_THAT(merged[3], Catch::Matchers::WithinAbs(1.4, 1e-9)); + REQUIRE_THAT(merged[2], Catch::Matchers::WithinAbs(0.9, 1e-9)); +} + +TEST_CASE("Selector slicing keeps the result valid across re-apply", "[Print][H2C][Dynamic]") +{ + // The dynamic counterpart of the static re-apply test above: a full process() run through + // the selector branch (whatever grouping it settles on) must leave the config in a state + // the next apply reproduces without invalidating the freshly sliced result. + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.option<ConfigOptionFloats>("nozzle_diameter", true)->values = {0.4, 0.4}; + config.option<ConfigOptionStrings>("extruder_nozzle_stats", true)->values = {"Standard#1", "Standard#1|High Flow#2"}; + config.option<ConfigOptionEnumsGeneric>("extruder_type", true)->values = {etDirectDrive, etDirectDrive}; + config.option<ConfigOptionEnumsGeneric>("nozzle_volume_type", true)->values = {nvtStandard, nvtHybrid}; + config.option<ConfigOptionStrings>("extruder_variant_list", true)->values = {"Direct Drive Standard,Direct Drive High Flow", + "Direct Drive Standard,Direct Drive High Flow"}; + config.option<ConfigOptionInts>("print_extruder_id", true)->values = {1, 1, 2, 2}; + config.option<ConfigOptionStrings>("print_extruder_variant", true)->values = {"Direct Drive Standard", "Direct Drive High Flow", + "Direct Drive Standard", "Direct Drive High Flow"}; + config.option<ConfigOptionFloats>("filament_diameter", true)->values = {1.75, 1.75, 1.75}; + config.option<ConfigOptionStrings>("filament_colour", true)->values = {"#FF0000", "#00FF00", "#0000FF"}; + config.option<ConfigOptionInts>("filament_map", true)->values = {1, 2, 2}; + config.option<ConfigOptionInts>("filament_volume_map", true)->values = {(int) nvtStandard, (int) nvtStandard, (int) nvtHighFlow}; + config.set_key_value("enable_filament_dynamic_map", new ConfigOptionBool(true)); + config.option<ConfigOptionEnum<FilamentMapMode>>("filament_map_mode", true)->value = FilamentMapMode::fmmAutoForFlush; + + Model model; + ModelObject *object = model.add_object("cube", "", make_cube(20, 20, 20)); + object->add_instance()->set_offset(Vec3d(100., 100., 0.)); + + Print print; + print.apply(model, config); + print.process(); + REQUIRE(print.is_step_done(psSlicingFinished)); + + auto status = print.apply(model, config); + REQUIRE(status != PrintBase::APPLY_STATUS_INVALIDATED); + REQUIRE(print.is_step_done(psSlicingFinished)); +}