diff --git a/.github/workflows/build_all.yml b/.github/workflows/build_all.yml index 10162aa1ff6..636790b6e49 100644 --- a/.github/workflows/build_all.yml +++ b/.github/workflows/build_all.yml @@ -85,16 +85,20 @@ jobs: arch: universal macos-combine-only: true secrets: inherit - # The macOS dSYM is only produced by the universal combine leg above, so it is - # uploaded here rather than from build_deps.yml (which handles the Windows PDB). - upload_symbols_macos: - name: Upload macOS Debug Symbols to Sentry - needs: build_macos_universal - if: ${{ !cancelled() && needs.build_macos_universal.result == 'success' && !vars.SELF_HOSTED }} + # One Sentry upload for every platform: the macOS dSYM from the universal + # combine leg, the Windows PDB from the x64 build leg and the unstripped + # Linux binaries. upload-dif handles all formats from a single runner. + upload_symbols: + name: Upload Debug Symbols to Sentry + needs: [build_macos_universal, build_windows, build_linux] + # Needs the Sentry org secrets; forks without them skip instead of failing. + if: ${{ !cancelled() && !vars.SELF_HOSTED && (needs.build_macos_universal.result == 'success' || needs.build_windows.result == 'success' || needs.build_linux.result == 'success') && (github.repository_owner == 'Snapmaker' || vars.SENTRY_UPLOAD == '1') }} uses: ./.github/workflows/sentry_cli.yml with: - os: macos-14 - dsym-artifact-name: dSYM_Mac_${{ needs.build_macos_universal.outputs.release }} + os: ubuntu-latest + pdb-artifact-name: PDB + dsym-artifact-name: ${{ needs.build_macos_universal.result == 'success' && format('dSYM_Mac_{0}', needs.build_macos_universal.outputs.release) || '' }} + linux-symbols-pattern: Linux_symbols_* release: ${{ needs.build_macos_universal.outputs.release || github.sha }} secrets: inherit # One test job per built arch, on the runner that built it. diff --git a/.github/workflows/build_deps.yml b/.github/workflows/build_deps.yml index 84d86c1da49..a92a7fb025b 100644 --- a/.github/workflows/build_deps.yml +++ b/.github/workflows/build_deps.yml @@ -209,18 +209,3 @@ jobs: os: ${{ inputs.os }} arch: ${{ inputs.arch }} secrets: inherit - - # Only the Windows x64 leg produces a PDB artifact (see build_orca.yml: "Pack - # PDB"/"Upload artifacts Win PDB" skip arm64). The macOS dSYM is produced by the - # universal *combine* leg, which build_all.yml calls directly rather than through - # this workflow -- build_all.yml's upload_symbols_macos job handles that. - upload_symbols: - name: Upload Debug Symbols to Sentry - needs: [build_orca] - if: ${{ !cancelled() && needs.build_orca.result == 'success' && (startsWith(inputs.os, 'windows') || inputs.os == 'orca-win-server') && inputs.arch != 'arm64' }} - uses: ./.github/workflows/sentry_cli.yml - with: - os: ${{ inputs.os }} - pdb-artifact-name: PDB - release: ${{ needs.build_orca.outputs.release || github.sha }} - secrets: inherit diff --git a/.github/workflows/build_orca.yml b/.github/workflows/build_orca.yml index ed67cf8046a..26aac19898f 100644 --- a/.github/workflows/build_orca.yml +++ b/.github/workflows/build_orca.yml @@ -175,7 +175,9 @@ jobs: - 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 + # The test binaries load libsentry.dylib through an rpath into the deps + # prefix; ship it at that path so the unit-test runner can resolve it. + run: tar -cvf build_tests.tar build/arm64/tests deps/build/arm64/OrcaSlicer_dep/usr/local/lib/libsentry.dylib - name: Upload Test Artifact mac if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64' @@ -193,7 +195,7 @@ jobs: shell: bash # The bundle was already packed from resources/, so the caches have to be # installed into it here; the source tree keeps its JSONs for later jobs. - run: ./scripts/build_preset_cache.sh -b build/${{ inputs.arch }} build/${{ inputs.arch }}/OrcaSlicer/OrcaSlicer.app/Contents/Resources/profiles + run: ./scripts/build_preset_cache.sh -b build/${{ inputs.arch }} "build/${{ inputs.arch }}/Snapmaker_Orca/Snapmaker Orca.app/Contents/Resources/profiles" - name: Pack macOS app bundle ${{ inputs.arch }} if: runner.os == 'macOS' && !inputs.macos-combine-only @@ -461,7 +463,7 @@ jobs: shell: cmd # Shipped into both the already-installed tree (portable zip, MSIX) and # the checkout cpack re-installs from when it builds the NSIS installer. - run: scripts\build_preset_cache.bat --prune-source "%BUILD_DIR%" "resources\profiles" "%BUILD_DIR%\OrcaSlicer\resources\profiles" + run: scripts\build_preset_cache.bat --prune-source "%BUILD_DIR%" "resources\profiles" "%BUILD_DIR%\Snapmaker_Orca\resources\profiles" - name: Pack unit tests Win if: runner.os == 'Windows' @@ -513,7 +515,7 @@ jobs: name: Snapmaker_Orca_Windows_${{ env.ver }}${{ env.ARCH_SUFFIX }} path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/Snapmaker_Orca*.exe - # sentry_cli.yml consumes this artifact name (via build_deps.yml). + # sentry_cli.yml consumes this artifact name (via build_all.yml). - name: Upload artifacts Win PDB if: runner.os == 'Windows' && inputs.arch != 'arm64' uses: actions/upload-artifact@v7 @@ -583,6 +585,27 @@ jobs: chmod +x "$appimage" tar -cvf build_tests.tar build/tests + # The unstripped build-tree binary carries the symtab Sentry needs; the + # AppImage ships the same build (same ELF build-id). Arch subdir keeps the + # two Linux legs from colliding in the unified symbol upload. + - name: Pack Linux symbols + if: runner.os == 'Linux' + shell: bash + run: | + arch=${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }} + mkdir -p symbols_linux/$arch + cp build/src/Release/snapmaker-orca symbols_linux/$arch/ + + - name: Upload Linux symbols artifact + if: runner.os == 'Linux' + uses: actions/upload-artifact@v7 + with: + name: Linux_symbols_${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }} + overwrite: true + path: symbols_linux + retention-days: 5 + if-no-files-found: error + # Use tar because upload-artifacts won't always preserve directory structure # and doesn't preserve file permissions - name: Upload Test Artifact @@ -602,7 +625,7 @@ jobs: # Both were packed from resources/ before the caches existed, so the # AppImage is unpacked first and the caches shipped into it and into # the package tree; the source tree keeps its JSONs for later steps. - appimage=$(find build -maxdepth 1 -name "OrcaSlicer_Linux_AppImage*.AppImage" | head -1) + appimage=$(find build -maxdepth 1 -name "Snapmaker_Orca_Linux_AppImage*.AppImage" | head -1) chmod +x "$appimage" "$appimage" --appimage-extract ./scripts/build_preset_cache.sh -b build build/package/resources/profiles squashfs-root/resources/profiles diff --git a/.github/workflows/sentry_cli.yml b/.github/workflows/sentry_cli.yml index b8d2935f4e4..6f2339330e8 100644 --- a/.github/workflows/sentry_cli.yml +++ b/.github/workflows/sentry_cli.yml @@ -1,169 +1,133 @@ name: Upload Debug Symbols to Sentry +# One upload for every platform: sentry-cli's upload-dif is format-agnostic, so +# a single runner ships the Windows PDBs, the macOS dSYMs and the unstripped +# Linux ELF binaries together. Artifact downloads are tolerant - +# whatever symbol artifacts this run produced get uploaded, the rest are +# reported as warnings instead of failing the run. on: workflow_call: inputs: os: required: true type: string - # Steps below gate on `runner.os`, not on this string, so any Windows / - # macOS / Linux runner label (incl. self-hosted orca-*-server) works. - description: "Runner label to run the upload on (e.g. windows-latest, macos-14, ubuntu-24.04)" + description: "Runner label to run the upload on (e.g. ubuntu-24.04)" pdb-artifact-name: required: false type: string - description: "Artifact name for Windows PDB archive (e.g., 'PDB')" + description: "Artifact name for the Windows PDB archive (e.g. 'PDB'); empty skips it" dsym-artifact-name: required: false type: string - description: "Artifact name for macOS dSYM archive (e.g., 'dSYM_Mac_V1.0.0')" + description: "Artifact name for the macOS dSYM archive (e.g. 'dSYM_Mac_V1.0.0'); empty skips it" + linux-symbols-pattern: + required: false + type: string + description: "Artifact name pattern for Linux ELF symbols (e.g. 'Linux_symbols_*'); empty skips it" release: - required: true + required: false type: string - description: "Release version/tag" + description: "Release version/tag (informational; upload-dif auto-associates releases)" jobs: upload_symbols: name: Upload Debug Symbols to Sentry runs-on: ${{ inputs.os }} steps: - # ==================== Windows ==================== - - name: "[Windows] Install sentry-cli via choco" - if: runner.os == 'Windows' && inputs.pdb-artifact-name != '' - shell: pwsh - run: | - choco install sentry-cli -y -y 2>&1 | Out-Null - - - name: "[Windows] Download PDB artifact" - if: runner.os == 'Windows' && inputs.pdb-artifact-name != '' - uses: actions/download-artifact@v8 - with: - name: ${{ inputs.pdb-artifact-name }} - path: ./symbols - - - name: "[Windows] Extract PDB archive" - if: runner.os == 'Windows' && inputs.pdb-artifact-name != '' - shell: pwsh + - name: Install sentry-cli + shell: bash run: | - $archive = Get-ChildItem -Path ./symbols -Filter "*.7z" -File | Select-Object -First 1 - if ($archive) { - Write-Host "Found archive: $($archive.FullName)" - Write-Host "Extracting to ./symbols/extracted ..." - 7z x "$($archive.FullName)" -o"./symbols/extracted" -y - if ($LASTEXITCODE -ne 0) { - Write-Host "::error::Failed to extract archive with exit code $LASTEXITCODE" - exit $LASTEXITCODE - } - Write-Host "Extraction complete. Contents:" - Get-ChildItem -Path ./symbols/extracted -Recurse | ForEach-Object { Write-Host " $($_.FullName)" } - } else { - Write-Host "No .7z archive found, assuming PDB files are already extracted" - Get-ChildItem -Path ./symbols -Recurse | ForEach-Object { Write-Host " Found: $($_.FullName)" } - } - - - name: "[Windows] Upload PDB to Sentry (sentry-cli)" - if: runner.os == 'Windows' && inputs.pdb-artifact-name != '' - shell: pwsh - env: - SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} - SENTRY_LOG_LEVEL: debug - run: | - # Determine upload path - prefer extracted folder if it exists - $uploadPath = "./symbols" - if (Test-Path "./symbols/extracted") { - $uploadPath = "./symbols/extracted" - } - - $pdbFiles = Get-ChildItem -Path $uploadPath -Filter "*.pdb" -File -Recurse - if ($pdbFiles.Count -gt 0) { - Write-Host "Found $($pdbFiles.Count) PDB file(s) to upload from $uploadPath :" - $pdbFiles | ForEach-Object { Write-Host " - $($_.FullName)" } - Write-Host "" - Write-Host "Starting Sentry upload with debug logging..." - sentry-cli.exe --log-level=debug --auth-token $env:SENTRY_AUTH_TOKEN upload-dif --org "${{ secrets.SENTRY_ORG }}" --project "${{ secrets.SENTRY_PROJECT }}" $uploadPath 2>&1 | Out-Host - if ($LASTEXITCODE -ne 0) { - Write-Host "::error::Sentry upload failed with exit code $LASTEXITCODE" - exit $LASTEXITCODE - } - } else { - Write-Host "::error::No PDB files found in $uploadPath" - Get-ChildItem -Path ./symbols -Recurse | ForEach-Object { Write-Host " Found: $($_.FullName)" } - exit 1 - } - - # ==================== macOS ==================== - - name: "[macOS] Install sentry-cli" - if: runner.os == 'macOS' && inputs.dsym-artifact-name != '' - run: | - # Try multiple installation methods for reliability - # Method 1: Official install script (most reliable) if ! command -v sentry-cli &> /dev/null; then echo "Installing sentry-cli via official script..." curl -sL https://sentry.io/get-cli/ | bash || true fi - - # Method 2: npm fallback if ! command -v sentry-cli &> /dev/null; then echo "Official script failed, trying npm..." npm install -g @sentry/cli || true fi - - # Method 3: Direct binary download fallback - if ! command -v sentry-cli &> /dev/null; then - echo "npm failed, downloading binary directly..." - SENTRY_CLI_VERSION=$(curl -s https://api.github.com/repos/getsentry/sentry-cli/releases/latest | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') - curl -sL "https://github.com/getsentry/sentry-cli/releases/download/${SENTRY_CLI_VERSION}/sentry-cli-Darwin-universal" -o /usr/local/bin/sentry-cli - chmod +x /usr/local/bin/sentry-cli - fi - - # Verify installation if command -v sentry-cli &> /dev/null; then - echo "sentry-cli installed successfully:" sentry-cli --version else - echo "::error::Failed to install sentry-cli via all methods" + echo "::error::Failed to install sentry-cli" exit 1 fi - - name: "[macOS] Download dSYM artifact" - if: runner.os == 'macOS' && inputs.dsym-artifact-name != '' + - name: Download Windows PDB artifact + id: dl_pdb + if: inputs.pdb-artifact-name != '' + continue-on-error: true + uses: actions/download-artifact@v8 + with: + name: ${{ inputs.pdb-artifact-name }} + path: ./symbols/windows + + - name: Download macOS dSYM artifact + id: dl_dsym + if: inputs.dsym-artifact-name != '' + continue-on-error: true uses: actions/download-artifact@v8 with: name: ${{ inputs.dsym-artifact-name }} - path: ./symbols + path: ./symbols/macos - - name: "[macOS] Upload dSYM to Sentry (sentry-cli)" - if: runner.os == 'macOS' && inputs.dsym-artifact-name != '' + - name: Download Linux symbols artifacts + id: dl_linux + if: inputs.linux-symbols-pattern != '' + continue-on-error: true + uses: actions/download-artifact@v8 + with: + pattern: ${{ inputs.linux-symbols-pattern }} + merge-multiple: true + path: ./symbols/linux + + - name: Extract archives + if: steps.dl_pdb.outcome == 'success' || steps.dl_dsym.outcome == 'success' || steps.dl_linux.outcome == 'success' + shell: bash + run: | + # The Windows PDBs ship as a .7z inside the artifact. + shopt -s nullglob globstar + for archive in ./symbols/**/*.7z; do + echo "Extracting $archive ..." + dir="$(dirname "$archive")/extracted" + if command -v 7z &> /dev/null; then + 7z x "$archive" -o"$dir" -y + else + 7zz x "$archive" -o"$dir" -y + fi + rm -f "$archive" + done + + - name: Upload debug symbols to Sentry + if: steps.dl_pdb.outcome == 'success' || steps.dl_dsym.outcome == 'success' || steps.dl_linux.outcome == 'success' + shell: bash env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }} SENTRY_LOG_LEVEL: debug run: | - echo "Checking for dSYM files in ./symbols..." - find ./symbols -name "*.dSYM" -type d | while read dsym; do - echo "Found dSYM: $dsym" - done - - dsymCount=$(find ./symbols -name "*.dSYM" -type d | wc -l | tr -d ' ') - if [ "$dsymCount" -gt 0 ]; then - echo "Found $dsymCount dSYM file(s) to upload from ./symbols:" - find ./symbols -name "*.dSYM" -type d | while read dsym; do - echo " - $dsym" - done - echo "" - echo "Starting Sentry upload with debug logging..." - # upload-dif does not support --release flag, it auto-associates with releases - sentry-cli --log-level=debug --auth-token "$SENTRY_AUTH_TOKEN" upload-dif --org "${{ secrets.SENTRY_ORG }}" --project "${{ secrets.SENTRY_PROJECT }}" ./symbols - UPLOAD_EXIT_CODE=$? - if [ $UPLOAD_EXIT_CODE -ne 0 ]; then - echo "::error::Sentry upload failed with exit code $UPLOAD_EXIT_CODE" - exit 1 - fi - else - echo "::error::No dSYM files found in ./symbols" - echo "Contents of ./symbols:" - find ./symbols -type f -o -type d | head -20 + if [ "${{ steps.dl_pdb.outcome }}" = "failure" ]; then + echo "::warning::PDB artifact '${{ inputs.pdb-artifact-name }}' could not be downloaded; uploading without Windows symbols" + fi + if [ "${{ steps.dl_dsym.outcome }}" = "failure" ]; then + echo "::warning::dSYM artifact '${{ inputs.dsym-artifact-name }}' could not be downloaded; uploading without macOS symbols" + fi + if [ "${{ steps.dl_linux.outcome }}" = "failure" ]; then + echo "::warning::Linux symbol artifacts '${{ inputs.linux-symbols-pattern }}' could not be downloaded; uploading without Linux symbols" + fi + pdb_count=$(find ./symbols -name "*.pdb" -type f | wc -l | tr -d ' ') + dsym_count=$(find ./symbols -name "*.dSYM" -type d | wc -l | tr -d ' ') + elf_count=$(find ./symbols/linux -type f 2>/dev/null | wc -l | tr -d ' ') + echo "Found $pdb_count PDB file(s), $dsym_count dSYM bundle(s), $elf_count Linux binary/binaries:" + find ./symbols -name "*.pdb" -type f -o -name "*.dSYM" -type d -o -path "./symbols/linux/*" -type f + if [ "$pdb_count" -eq 0 ] && [ "$dsym_count" -eq 0 ] && [ "$elf_count" -eq 0 ]; then + echo "::error::Symbol artifacts downloaded but contained no PDB, dSYM or ELF files" + find ./symbols | head -40 exit 1 fi + # upload-dif does not support --release; it auto-associates with releases + sentry-cli --log-level=debug --auth-token "$SENTRY_AUTH_TOKEN" upload-dif \ + --org "${{ secrets.SENTRY_ORG }}" --project "${{ secrets.SENTRY_PROJECT }}" ./symbols - # ==================== Linux ==================== - + - name: Nothing to upload + if: steps.dl_pdb.outcome != 'success' && steps.dl_dsym.outcome != 'success' && steps.dl_linux.outcome != 'success' + shell: bash + run: echo "::warning::No symbol artifacts were available in this run; nothing uploaded to Sentry" diff --git a/CMakeLists.txt b/CMakeLists.txt index ada6333ff6c..81765547e87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -148,8 +148,9 @@ option(SLIC3R_MSVC_COMPILE_PARALLEL "Compile on Visual Studio in parallel" 1) option(SLIC3R_MSVC_PDB "Generate PDB files on MSVC in Release mode" 1) option(SLIC3R_ASAN "Enable ASan on Clang and GCC" 0) -# Sentry crash reporting - enabled only on Windows/macOS by default -if (WIN32 OR APPLE) +# Sentry crash reporting - on by default everywhere except the Flatpak build +# (Flathub distribution stays telemetry-free). +if (WIN32 OR APPLE OR (UNIX AND NOT FLATPAK)) set(SLIC3R_SENTRY_DEFAULT ON) else() set(SLIC3R_SENTRY_DEFAULT OFF) diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 4da8a525a94..6f46a0ebfb1 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -112,8 +112,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux") option(DEP_WX_GTK3 "Build wxWidgets against GTK3" ON) endif() -# Sentry crash reporting - enabled only on Windows by default -if (WIN32 OR APPLE) +# Sentry crash reporting - on by default everywhere except the Flatpak build +# (Flathub distribution stays telemetry-free). +if (WIN32 OR APPLE OR (UNIX AND NOT FLATPAK)) set(SLIC3R_SENTRY_DEFAULT ON) else() set(SLIC3R_SENTRY_DEFAULT OFF) diff --git a/deps/Sentry/Sentry.cmake b/deps/Sentry/Sentry.cmake index 7efd4de50c1..aa3e68e37ca 100644 --- a/deps/Sentry/Sentry.cmake +++ b/deps/Sentry/Sentry.cmake @@ -60,6 +60,8 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") ${_sentry_platform_flags} -DSENTRY_TRANSPORT_CURL=ON -DSENTRY_BUILD_SHARED_LIBS=OFF + # breakpad backend: in-process, needs no crashpad_handler shipped in the AppImage + -DSENTRY_BACKEND=breakpad -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo ) set(_sentry_cmake_generator -G "Unix Makefiles") diff --git a/localization/i18n/ca/Snapmaker_Orca_ca.po b/localization/i18n/ca/Snapmaker_Orca_ca.po index c0e86f0e17c..8f210c267aa 100644 --- a/localization/i18n/ca/Snapmaker_Orca_ca.po +++ b/localization/i18n/ca/Snapmaker_Orca_ca.po @@ -19248,6 +19248,550 @@ msgstr "" "augmentar adequadament la temperatura del llit pot reduir la probabilitat de " "deformació?" +msgid "Adjust wall layer height" +msgstr "Ajustar l'alçada de capa dels perímetres" + +msgid "Adjusted walls" +msgstr "Perímetres ajustats" + +msgid "Adjustment direction" +msgstr "Direcció de l'ajust" + +msgid "Consistent" +msgstr "Consistent" + +msgid "Decrease" +msgstr "Disminuir" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir la superfície inferior.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir els perímetres interiors.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir el farciment sòlid intern.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir el farciment poc dens intern.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir els perímetres exteriors.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament per imprimir base del suport i Vora d'Adherència. \"Per defecte\" " +"significa que no s'utilitza cap filament específic per al suport i s'usarà " +"el filament actual" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament per imprimir interfície de suport. \"Per defecte\" vol dir que no " +"hi ha filament específic per a la interfície de suport i s'utilitza el " +"filament actual" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament per imprimir la superfície superior.\n" +"\"Per defecte\" usa el filament actiu de l'objecte/peça." + +msgid "Fixed" +msgstr "Fixa" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Amb quina agressivitat les peces assignades a un extrusor amb una alçada de " +"capa preferida més gruixuda es combinen en capes gruixudes.\n" +"Consistent: les peces s'imprimeixen amb com a màxim dues alçades de capa - " +"l'alçada de capa de l'extrusor on hi caben sèries senceres de capes i " +"l'alçada de capa de l'objecte a la resta. Això dóna els perímetres més " +"uniformes.\n" +"Adaptativa: les sèries també es poden combinar en múltiples intermedis de " +"l'alçada de capa de l'objecte, de manera que més part de la peça s'imprimeix " +"amb capes gruixudes, a canvi de bandes d'alçades de capa variables als " +"contorns corbats.\n" +"Fixa: les peces sempre s'imprimeixen a l'alçada de capa de l'extrusor, fins " +"i tot on la forma canvia a través de les capes combinades o sobresurt; els " +"contorns corbats es converteixen en esglaons i es perd el detall més fi que " +"les capes gruixudes. Només la geometria massa curta per a una capa gruixuda " +"sencera (les parts superiors i la primera capa) s'imprimeix més fina." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Fins on pot desplaçar-se lateralment el contorn d'una peça assignada a un " +"extrusor amb una alçada de capa preferida més gruixuda a través de les capes " +"d'una sèrie gruixuda i encara combinar-se, com a percentatge del diàmetre " +"del broquet d'aquell extrusor. Valors més alts combinen més contorns corbats " +"en capes gruixudes, a canvi de perímetres de contorn més rugosos: les " +"desviacions fins a aquesta fracció del diàmetre del broquet queden " +"absorbides per les extrusions gruixudes." + +msgid "Increase" +msgstr "Augmentar" + +msgid "Inner walls" +msgstr "Perímetres interiors" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Alçada de capa amb què hauria d'imprimir aquest extrusor, per a impressores " +"amb extrusors de mides de broquet diferents. Ha de ser un múltiple enter de " +"l'alçada de capa de l'objecte. Una peça amb totes les característiques " +"seguint aquest extrusor s'imprimeix només cada N capes amb extrusions " +"corresponentment més gruixudes, allà on la seva geometria ho permet; a la " +"resta torna a l'alçada de capa de l'objecte. Quan la resta de la peça no pot " +"seguir-lo, els perímetres assignats a aquest extrusor es combinen igualment " +"pel seu compte a aquesta alçada, les superfícies superiors totalment denses " +"absorbeixen les capes sòlides de sota, i el farciment poc dens o dens al " +"100% es combina de manera independent a aquesta alçada. 0 significa usar " +"l'alçada de capa de l'objecte." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Alçada de capa amb què hauria d'imprimir aquest extrusor: un múltiple enter " +"de l'alçada de capa de l'objecte dins dels límits d'alçada de capa d'aquest " +"extrusor. Per defecte manté l'alçada de capa de l'objecte." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Cap extrusor té un broquet que coincideixi amb el diàmetre del broquet dels " +"suports." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Cap filament carregat coincideix amb el material de la base dels suports/" +"vora d'adherència (i amb el diàmetre del broquet dels suports)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Cap filament carregat coincideix amb el material de la interfície dels " +"suports/vora d'adherència (i amb el diàmetre del broquet dels suports)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Broquet %1%: límits d'alçada de capa fixats a %2%-%3% mm, de \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"En impressores amb extrusors de diàmetres de broquet diferents, només els " +"filaments d'aquest diàmetre de broquet s'usen per imprimir suports, vora " +"d'adherència i interfície dels suports. Això manté els filaments d'altres " +"mides de broquet - amb les seves amplades de línia i límits d'alçada de capa " +"diferents - fora dels suports. Els filaments de suport amb un valor no " +"predeterminat han de coincidir amb aquest diàmetre. El valor 0 permet que " +"qualsevol filament imprimeixi suports." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Els perímetres exteriors i interiors s'imprimeixen automàticament amb les " +"seves pròpies alçades de capa preferides quan una alçada és un múltiple " +"enter de l'altra. Quan les alçades no es divideixen exactament, aquesta " +"opció ajusta l'alçada de capa dels perímetres d'un dels dos filaments de " +"perímetre (triat a sota) al múltiple o divisor més proper de l'altra, perquè " +"els perímetres encara puguin separar-se. L'alçada ajustada només s'aplica " +"als perímetres d'aquell filament; les altres característiques mantenen " +"l'alçada de capa preferida. Els ajustos mai surten dels límits d'alçada de " +"capa del filament: si no hi ha cap alçada permesa en la direcció triada, els " +"perímetres s'imprimeixen junts a l'alçada menor com sempre." + +msgid "Outer walls" +msgstr "Perímetres exteriors" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Les alçades de capa per extrusor no són compatibles amb el mode gerro en " +"espiral." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Les alçades de capa per extrusor no són compatibles amb les carcasses " +"d'interfície." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Les alçades de capa per extrusor no són compatibles amb l'alçada de capa " +"variable." + +msgid "Preferred layer height" +msgstr "Alçada de capa preferida" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Imprimir la base dels suports i la vora d'adherència només amb filaments " +"d'aquest tipus de material; els extrusors carregats amb altres tipus no s'hi " +"usen. Es combina amb la restricció del diàmetre del broquet dels suports. " +"Deixeu-ho buit per no restringir; un filament de base dels suports/vora " +"d'adherència triat explícitament segueix tenint prioritat." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Imprimir la interfície dels suports i de la vora d'adherència només amb " +"filaments d'aquest tipus de material; els extrusors carregats amb altres " +"tipus no s'hi usen. Es combina amb la restricció del diàmetre del broquet " +"dels suports. Deixeu-ho buit per no restringir; un filament d'interfície " +"triat explícitament segueix tenint prioritat." + +msgid "Raft and support base" +msgstr "Vora d'adherència i base dels suports" + +msgid "Show legacy filament selection" +msgstr "Mostra la selecció de filament antiga" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Algunes peces prefereixen capes de %1% mm, però el broquet del filament %2% " +"que imprimeix altres característiques de la peça és massa petit per extrudir " +"aquesta alçada. Aquestes peces s'imprimeixen amb l'alçada de capa de " +"l'objecte." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Algunes peces prefereixen capes de %1% mm, però el broquet del filament de " +"perímetres %2% és massa petit per extrudir aquesta alçada. Els perímetres " +"exteriors i interiors s'imprimeixen junts, així que aquests perímetres " +"mantenen l'alçada de capa de l'objecte. Assigneu ambdues característiques de " +"perímetre a filaments amb broquets prou grans." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Algunes peces imprimeixen capes de %1% mm amb el filament %2%, l'alçada de " +"capa màxima del qual és %3% mm. Assigneu les característiques de la peça als " +"filaments del broquet més gruixut, augmenteu l'alçada de capa màxima del " +"filament o accepteu imprimir per sobre." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Algunes peces imprimeixen capes de %1% mm amb el filament %2%, l'alçada de " +"capa mínima del qual és %3% mm. Augmenteu l'alçada de capa de l'objecte, " +"useu un filament amb un broquet més fi per a aquestes característiques o " +"accepteu imprimir per sota del mínim de l'extrusor." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Algunes peces usen filaments les alçades de capa preferides dels quals no es " +"poden respectar totes: una peça imprimeix les seves característiques amb un " +"sol pas de capa (fixat pels seus filaments de perímetre o, quan cap filament " +"de perímetre té preferència, per l'acord de les altres característiques); " +"els perímetres, les superfícies superiors i el farciment poden combinar-se " +"cadascun a la seva pròpia alçada quan la resta de la peça no els pot seguir, " +"però les característiques restants s'imprimeixen amb el pas de la peça." + +msgid "Support for mixed nozzle sizes" +msgstr "Suports amb mides de broquet mixtes" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Els suports podrien imprimir-se amb extrusors de diàmetres de broquet " +"diferents. Fixeu el diàmetre del broquet dels suports (o filaments explícits " +"de suport i interfície) per mantenir els suports en una sola mida de broquet." + +msgid "Support nozzle diameter" +msgstr "Diàmetre del broquet dels suports" + +msgid "Support nozzle size" +msgstr "Mida del broquet dels suports" + +msgid "Support/raft base material" +msgstr "Material de la base dels suports/vora d'adherència" + +msgid "Support/raft interface material" +msgstr "Material de la interfície dels suports/vora d'adherència" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"L'amplada de línia de farciment de %1% mm és massa petita per a farciment " +"combinat en capes de %2% mm d'alçada. Augmenteu l'amplada de línia o reduïu " +"l'alçada de capa preferida del filament de farciment." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"L'amplada de línia de %1% mm és massa petita per a l'alçada de capa de %2% " +"mm del seu extrusor. Augmenteu l'amplada de línia o reduïu l'alçada de capa " +"de l'extrusor." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"L'alçada de capa de l'extrusor %1% (%2% mm) no pot superar el diàmetre del " +"seu broquet." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"L'alçada de capa de l'extrusor %1% (%2% mm) s'ignora per a algunes peces: ha " +"de ser un múltiple enter de l'alçada de capa de l'objecte (%3% mm), no " +"inferior, i no ha de superar el diàmetre del broquet de l'extrusor." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"L'alçada de capa de l'extrusor %1% (%2% mm) és menor que l'alçada de capa de " +"l'objecte (%3% mm). Reduïu l'alçada de capa de l'objecte a l'alçada de capa " +"d'extrusor més fina." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"L'alçada de capa de l'extrusor %1% (%2% mm) ha de ser un múltiple enter de " +"l'alçada de capa de l'objecte (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"L'alçada de capa imprimible més baixa de l'extrusor. S'usa per limitar " +"l'alçada de capa mínima quan l'alçada de capa adaptativa està activada. Les " +"peces impreses amb una alçada de capa d'extrusor preferida més gruixuda " +"tampoc no baixen mai d'aquesta alçada (excepte la primera capa)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"L'alçada de capa preferida del broquet %1% ja no hi passa i s'ha restablert " +"a Per defecte." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"El filament de la base dels suports/vora d'adherència no és del material de " +"la base dels suports/vora d'adherència." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"El filament de la base dels suports/vora d'adherència imprimeix amb un " +"broquet que no coincideix amb el diàmetre del broquet dels suports." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"El filament de la interfície dels suports/vora d'adherència no és del " +"material de la interfície dels suports/vora d'adherència." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"El filament de la interfície dels suports/vora d'adherència imprimeix amb un " +"broquet que no coincideix amb el diàmetre del broquet dels suports." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Els filaments de perímetre d'algunes peces prefereixen alçades de capa " +"diferents. Els perímetres exteriors i interiors s'imprimeixen junts, així " +"que aquests perímetres mantenen l'alçada de capa de l'objecte. Assigneu " +"ambdues característiques de perímetre a filaments que prefereixin la mateixa " +"alçada per imprimir perímetres més gruixuts." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Els filaments de perímetre d'algunes peces prefereixen alçades de capa " +"diferents. Els perímetres exteriors i interiors s'imprimeixen junts, així " +"que aquests perímetres s'imprimeixen amb l'alçada menor (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"L'alçada de capa dels perímetres del filament %1% s'ha ajustat dels %2% mm " +"preferits a %3% mm perquè els perímetres exteriors i interiors puguin " +"imprimir-se a alçades de capa compatibles (\"Ajustar l'alçada de capa dels " +"perímetres\"). Només els perímetres d'aquest filament imprimeixen l'alçada " +"ajustada; les seves altres característiques mantenen la preferida." + +msgid "Thick layer regions" +msgstr "Regions de capes gruixudes" + +msgid "Thick layer tolerance" +msgstr "Tolerància de capes gruixudes" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Aquesta impressora no té perfil per a un broquet de %1% mm. Reviseu els " +"límits d'alçada de capa del broquet %2% als ajustos de la impressora." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Aquesta impressora usa mides de broquet diferents. Seleccioneu la mida del " +"broquet que imprimeix els suports i els tipus de filament per a la vora " +"d'adherència i la interfície dels suports." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Si l'alçada de capa dels perímetres del filament ajustat es disminueix o " +"s'augmenta per assolir una alçada compatible amb l'altre filament de " +"perímetre. Mai s'usen alçades fora dels límits d'alçada de capa del filament " +"ajustat: si no hi ha cap alçada permesa en aquesta direcció, els perímetres " +"s'imprimeixen junts a l'alçada menor com sempre." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Quin dels dos filaments de perímetre rep l'ajust de la seva alçada de capa " +"dels perímetres quan les alçades de capa preferides no es divideixen " +"exactament." + # AI Translated msgid "Main Extruder" msgstr "Extrusor Principal" @@ -28707,14 +29251,6 @@ msgstr "" "Si s'estableix a 0, s'utilitzarà l'algorisme antic per a la connexió de " "farciment, hauria de crear el mateix resultat que amb 1000 i 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir el farciment poc dens intern.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - msgid "Infill/wall overlap" msgstr "Superposició de farciment/perímetre" @@ -29093,30 +29629,6 @@ msgstr "" "utilitzar una velocitat diferent per imprimir. Per al voladís del 100%%, " "s'utilitza la velocitat de pont." -# AI Translated -msgid "Outer walls" -msgstr "Perímetres exteriors" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir els perímetres exteriors.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - -# AI Translated -msgid "Inner walls" -msgstr "Perímetres interiors" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir els perímetres interiors.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - msgid "This is the speed for inner walls." msgstr "Velocitat del perímetre interior" @@ -29310,30 +29822,6 @@ msgstr "" "L'àrea de farciment poc dens que sigui més petita que el valor del llindar " "serà substituït per un farciment sòlid intern" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir el farciment sòlid intern.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir la superfície superior.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament per imprimir la superfície inferior.\n" -"\"Per defecte\" utilitza el filament actiu de l'objecte/peça." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29501,16 +29989,6 @@ msgstr "" "valor s'ignora i el suport s'imprimeix en contacte directe amb l'objecte " "(sense espai)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament per imprimir base del suport i Vora d'Adherència.\n" -"\"Per defecte\" significa que no s'utilitza cap filament específic per al " -"suport i s'usarà el filament actual" - msgid "Loop pattern interface" msgstr "La interfície usa patró de bucle" @@ -29521,16 +29999,6 @@ msgstr "" "Cobrir la capa de contacte superior dels suports amb bucles. Desactivat per " "defecte." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament per imprimir interfície de suport.\n" -"\"Per defecte\" vol dir que no hi ha filament específic per a la interfície " -"de suport i s'utilitza el filament actual" - # AI Translated msgid "This is the number of top interface layers." msgstr "Nombre de capes d'interfície superiors." diff --git a/localization/i18n/cs/Snapmaker_Orca_cs.po b/localization/i18n/cs/Snapmaker_Orca_cs.po index 193c34a92d4..fbee7f34579 100644 --- a/localization/i18n/cs/Snapmaker_Orca_cs.po +++ b/localization/i18n/cs/Snapmaker_Orca_cs.po @@ -18495,6 +18495,522 @@ msgstr "" "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 "Adjust wall layer height" +msgstr "Upravit výšku vrstvy stěn" + +msgid "Adjusted walls" +msgstr "Upravované stěny" + +msgid "Adjustment direction" +msgstr "Směr úpravy" + +msgid "Consistent" +msgstr "Jednotné" + +msgid "Decrease" +msgstr "Snížit" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk spodního povrchu.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk vnitřních stěn.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk vnitřní plné výplně.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk vnitřní řídké výplně.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk vnějších stěn.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament pro tisk základny podpor a raftu.\n" +"\"Výchozí\" znamená žádný zvláštní filament pro podpory; použije se aktuální " +"filament." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament pro tisk kontaktních vrstev podpor.\n" +"\"Výchozí\" znamená žádný zvláštní filament pro kontaktní vrstvy; použije se " +"aktuální filament." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pro tisk horního povrchu.\n" +"\"Výchozí\" použije aktivní filament objektu/části." + +msgid "Fixed" +msgstr "Pevné" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Jak agresivně se části přiřazené extruderu s tlustší preferovanou výškou " +"vrstvy slučují do tlustých vrstev.\n" +"Jednotné: části se tisknou nejvýše dvěma výškami vrstvy - výškou vrstvy " +"extruderu tam, kde se vejdou celé série vrstev, a výškou vrstvy objektu " +"všude jinde. To dává nejrovnoměrnější stěny.\n" +"Adaptivní: série lze slučovat i na mezilehlých násobcích výšky vrstvy " +"objektu, takže se větší část dílu tiskne tlustšími vrstvami - za cenu pásů " +"proměnlivé výšky vrstvy na zakřivených okrajích.\n" +"Pevné: části se vždy tisknou výškou vrstvy extruderu, i tam, kde se tvar " +"přes sloučené vrstvy mění nebo přesahuje; zakřivené okraje se mění ve schody " +"a detaily jemnější než tlusté vrstvy se ztrácejí. Jen geometrie příliš " +"krátká na celou tlustou vrstvu (vršky dílů a první vrstva) se tiskne tenčeji." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Jak daleko se smí obrys části přiřazené extruderu s tlustší preferovanou " +"výškou vrstvy posunout do strany napříč vrstvami jedné tlusté série a přesto " +"být sloučen, jako procento průměru trysky tohoto extruderu. Vyšší hodnoty " +"sloučí více zakřivených okrajů do tlustých vrstev za cenu hrubších " +"okrajových stěn: odchylky do tohoto zlomku průměru trysky pohltí tlusté " +"extruze." + +msgid "Increase" +msgstr "Zvýšit" + +msgid "Inner walls" +msgstr "Vnitřní stěny" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Výška vrstvy, kterou má tento extruder tisknout; pro tiskárny, jejichž " +"extrudery mají různé velikosti trysek. Musí být celočíselným násobkem výšky " +"vrstvy objektu. Díl, jehož všechny prvky následují tento extruder, se tiskne " +"jen každou N-tou vrstvu odpovídajícím způsobem tlustšími extruzemi tam, kde " +"to jeho geometrie dovolí; jinde se vrací k výšce vrstvy objektu. Když zbytek " +"dílu následovat nemůže, stěny přiřazené tomuto extruderu se přesto " +"samostatně sloučí na tuto výšku, plně husté horní povrchy pohltí plné vrstvy " +"pod sebou a řídká i 100% hustá výplň se na tuto výšku sloučí nezávisle. 0 " +"znamená použít výšku vrstvy objektu." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Výška vrstvy, kterou má tento extruder tisknout: celočíselný násobek výšky " +"vrstvy objektu v mezích omezení výšky vrstvy tohoto extruderu. Výchozí " +"zachovává výšku vrstvy objektu." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Žádný extruder nemá trysku odpovídající průměru trysky podpor." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Žádný nahraný filament neodpovídá materiálu základny podpor/raftu (a průměru " +"trysky podpor)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Žádný nahraný filament neodpovídá materiálu kontaktních vrstev podpor/raftu " +"(a průměru trysky podpor)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Tryska %1%: omezení výšky vrstvy nastavena na %2%-%3% mm, z \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Na tiskárnách, jejichž extrudery mají různé průměry trysek, se k tisku " +"podpor, raftu a kontaktních vrstev používají jen filamenty tohoto průměru " +"trysky. To drží filamenty jiných velikostí trysek - s jejich odlišnými " +"šířkami čar a omezeními výšky vrstvy - mimo podpory. Filamenty podpor " +"nastavené na jinou než výchozí hodnotu musí tomuto průměru odpovídat. " +"Hodnota 0 dovolí tisknout podpory libovolným filamentem." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Vnější a vnitřní stěny se automaticky tisknou vlastními preferovanými " +"výškami vrstvy, když je jedna výška celočíselným násobkem druhé. Když se " +"výšky nedělí beze zbytku, tato volba upraví výšku vrstvy stěn jednoho ze " +"dvou filamentů stěn (zvoleného níže) na nejbližší násobek nebo dělitel " +"druhé, aby se stěny stále mohly rozdělit. Upravená výška platí jen pro stěny " +"tohoto filamentu; ostatní prvky si zachovají preferovanou výšku vrstvy. " +"Úpravy nikdy neopustí omezení výšky vrstvy filamentu: pokud ve zvoleném " +"směru žádná povolená výška neexistuje, stěny se jako obvykle tisknou " +"společně nižší výškou." + +msgid "Outer walls" +msgstr "Vnější stěny" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Výšky vrstev pro jednotlivé extrudery nejsou podporovány v režimu spirálové " +"vázy." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Výšky vrstev pro jednotlivé extrudery nejsou podporovány spolu s kontaktními " +"skořepinami." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Výšky vrstev pro jednotlivé extrudery nejsou podporovány spolu s proměnlivou " +"výškou vrstvy." + +msgid "Preferred layer height" +msgstr "Preferovaná výška vrstvy" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Tisknout podpory a základnu raftu jen filamenty tohoto typu materiálu; " +"extrudery s jinými typy se k tomu nepoužívají. Působí spolu s omezením " +"průměru trysky podpor. Ponechte prázdné pro žádné omezení; výslovně zvolený " +"filament základny podpor/raftu má stále přednost." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Tisknout kontaktní vrstvy podpor a raftu jen filamenty tohoto typu " +"materiálu; extrudery s jinými typy se k tomu nepoužívají. Působí spolu s " +"omezením průměru trysky podpor. Ponechte prázdné pro žádné omezení; výslovně " +"zvolený filament kontaktních vrstev má stále přednost." + +msgid "Raft and support base" +msgstr "Raft a základna podpor" + +msgid "Show legacy filament selection" +msgstr "Zobrazit starý výběr filamentu" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Některé díly preferují vrstvy %1% mm, ale tryska filamentu %2%, který tiskne " +"jiné prvky dílu, je příliš malá na vytlačení této výšky. Tyto díly se místo " +"toho tisknou výškou vrstvy objektu." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Některé díly preferují vrstvy %1% mm, ale tryska filamentu stěn %2% je " +"příliš malá na vytlačení této výšky. Vnější a vnitřní stěny se tisknou " +"společně, takže tyto stěny si zachovají výšku vrstvy objektu. Přiřaďte oba " +"prvky stěn filamentům s dostatečně velkými tryskami." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Některé díly tisknou vrstvy %1% mm filamentem %2%, jehož maximální výška " +"vrstvy je %3% mm. Přiřaďte prvky dílu filamentům hrubší trysky, zvyšte " +"maximální výšku vrstvy filamentu, nebo přijměte tisk nad ní." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Některé díly tisknou vrstvy %1% mm filamentem %2%, jehož minimální výška " +"vrstvy je %3% mm. Zvyšte výšku vrstvy objektu, použijte pro tyto prvky " +"filament s jemnější tryskou, nebo přijměte tisk pod minimem extruderu." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Některé díly používají filamenty, jejichž preferované výšky vrstev nelze " +"všechny dodržet: díl tiskne své prvky jedním krokem vrstvy (určeným jeho " +"filamenty stěn, nebo dohodou ostatních prvků, když žádný filament stěn " +"preferenci nemá); stěny, horní povrchy a výplň se mohou každý sloučit na " +"vlastní výšku, když je zbytek dílu nemůže následovat, ale zbývající prvky se " +"tisknou krokem dílu." + +msgid "Support for mixed nozzle sizes" +msgstr "Podpory při smíšených velikostech trysek" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Podpory se mohou tisknout extrudery s různými průměry trysek. Nastavte " +"průměr trysky podpor (nebo výslovné filamenty podpor a kontaktních vrstev), " +"aby podpory zůstaly na jedné velikosti trysky." + +msgid "Support nozzle diameter" +msgstr "Průměr trysky podpor" + +msgid "Support nozzle size" +msgstr "Velikost trysky podpor" + +msgid "Support/raft base material" +msgstr "Materiál základny podpor/raftu" + +msgid "Support/raft interface material" +msgstr "Materiál kontaktních vrstev podpor/raftu" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Šířka čáry výplně %1% mm je příliš malá pro výplň sloučenou do vrstev " +"vysokých %2% mm. Zvětšete šířku čáry, nebo snižte preferovanou výšku vrstvy " +"filamentu výplně." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Šířka čáry %1% mm je příliš malá pro výšku vrstvy %2% mm jejího extruderu. " +"Zvětšete šířku čáry, nebo snižte výšku vrstvy extruderu." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Výška vrstvy extruderu %1% (%2% mm) nesmí překročit průměr jeho trysky." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Výška vrstvy extruderu %1% (%2% mm) se u některých dílů ignoruje: musí být " +"celočíselným násobkem výšky vrstvy objektu (%3% mm), ne menší, a nesmí " +"překročit průměr trysky extruderu." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Výška vrstvy extruderu %1% (%2% mm) je menší než výška vrstvy objektu (%3% " +"mm). Snižte výšku vrstvy objektu na nejjemnější výšku vrstvy extruderu." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Výška vrstvy extruderu %1% (%2% mm) musí být celočíselným násobkem výšky " +"vrstvy objektu (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Nejnižší tisknutelná výška vrstvy extruderu. Omezuje minimální výšku vrstvy " +"při zapnuté adaptivní výšce vrstvy. Díly tištěné tlustší preferovanou výškou " +"vrstvy extruderu také nikdy neklesnou pod tuto výšku (kromě první vrstvy)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Preferovaná výška vrstvy trysky %1% jí už neprojde a byla obnovena na " +"Výchozí." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "Filament základny podpor/raftu není z materiálu základny podpor/raftu." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Filament základny podpor/raftu tiskne tryskou, která neodpovídá průměru " +"trysky podpor." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Filament kontaktních vrstev podpor/raftu není z materiálu kontaktních vrstev " +"podpor/raftu." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Filament kontaktních vrstev podpor/raftu tiskne tryskou, která neodpovídá " +"průměru trysky podpor." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Filamenty stěn některých dílů preferují různé výšky vrstev. Vnější a vnitřní " +"stěny se tisknou společně, takže tyto stěny si zachovají výšku vrstvy " +"objektu. Pro tisk tlustších stěn přiřaďte oba prvky stěn filamentům " +"preferujícím stejnou výšku." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Filamenty stěn některých dílů preferují různé výšky vrstev. Vnější a vnitřní " +"stěny se tisknou společně, takže se tyto stěny tisknou nižší výškou (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Výška vrstvy stěn filamentu %1% byla upravena z preferovaných %2% mm na %3% " +"mm, aby se vnější a vnitřní stěny mohly tisknout kompatibilními výškami " +"vrstev (\"Upravit výšku vrstvy stěn\"). Upravenou výškou se tisknou jen " +"stěny tohoto filamentu; jeho ostatní prvky si zachovají preferovanou." + +msgid "Thick layer regions" +msgstr "Oblasti tlustých vrstev" + +msgid "Thick layer tolerance" +msgstr "Tolerance tlustých vrstev" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Tato tiskárna nemá profil pro trysku %1% mm. Zkontrolujte prosím omezení " +"výšky vrstvy trysky %2% v nastavení tiskárny." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Tato tiskárna používá různé velikosti trysek. Vyberte velikost trysky, která " +"tiskne podpory, a typy filamentů použité pro raft a kontaktní vrstvy podpor." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Zda se výška vrstvy stěn upravovaného filamentu snižuje, nebo zvyšuje, aby " +"dosáhla výšky kompatibilní s druhým filamentem stěn. Výšky mimo omezení " +"výšky vrstvy upravovaného filamentu se nikdy nepoužijí: pokud v tomto směru " +"žádná povolená výška neexistuje, stěny se jako obvykle tisknou společně " +"nižší výškou." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Kterému ze dvou filamentů stěn se upraví výška vrstvy stěn, když se " +"preferované výšky vrstev nedělí beze zbytku." + # AI Translated msgid "Main Extruder" msgstr "Hlavní extruder" @@ -27624,14 +28140,6 @@ msgstr "" "Pokud je nastaveno na 0, použije se starý algoritmus připojení výplně, což " "by mělo vytvořit stejný výsledek jako s 1000 & 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk vnitřní řídké výplně.\n" -"„Výchozí“ použije filament aktivního objektu/části." - msgid "Infill/wall overlap" msgstr "Překrytí výplně/stěny" @@ -27974,30 +28482,6 @@ msgstr "" "Detekuje procento převisu vzhledem k šířce čáry a použije odlišnou rychlost " "tisku. Pro 100%% převis je použita rychlost mostů." -# AI Translated -msgid "Outer walls" -msgstr "Vnější stěny" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk vnějších stěn.\n" -"„Výchozí“ použije filament aktivního objektu/části." - -# AI Translated -msgid "Inner walls" -msgstr "Vnitřní stěny" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk vnitřních stěn.\n" -"„Výchozí“ použije filament aktivního objektu/části." - msgid "This is the speed for inner walls." msgstr "Rychlost vnitřní stěny." @@ -28179,30 +28663,6 @@ msgstr "" "Oblast řídké výplně menší než prahová hodnota bude nahrazena vnitřní plnou " "výplní." -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk vnitřní plné výplně.\n" -"„Výchozí“ použije filament aktivního objektu/části." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk horního povrchu.\n" -"„Výchozí“ použije filament aktivního objektu/části." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pro tisk spodního povrchu.\n" -"„Výchozí“ použije filament aktivního objektu/části." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28366,16 +28826,6 @@ msgstr "" "vzdálenost podpory 0 a spodek má vrstvy rozhraní, tato hodnota se ignoruje a " "podpora se tiskne v přímém kontaktu s objektem (bez mezery)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament pro tisk základny podpor a raftu.\n" -"„Výchozí“ znamená, že se pro podpory nepoužívá žádný konkrétní filament a " -"použije se aktuální filament." - msgid "Loop pattern interface" msgstr "Rozhraní používá vzor smyčky" @@ -28386,16 +28836,6 @@ msgstr "" "Zakryjte vrchní kontaktní vrstvu podpor smyčkami. Ve výchozím nastavení " "vypnuto." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament pro tisk rozhraní podpor.\n" -"„Výchozí“ znamená, že se pro rozhraní podpor nepoužívá žádný konkrétní " -"filament a použije se aktuální filament." - # AI Translated msgid "This is the number of top interface layers." msgstr "Počet vrstev rozhraní horního povrchu." diff --git a/localization/i18n/de/Snapmaker_Orca_de.po b/localization/i18n/de/Snapmaker_Orca_de.po index d913ac8edb1..31da4a5af54 100644 --- a/localization/i18n/de/Snapmaker_Orca_de.po +++ b/localization/i18n/de/Snapmaker_Orca_de.po @@ -19424,6 +19424,543 @@ msgstr "" "wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die " "Wahrscheinlichkeit von Verwerfungen verringert werden kann?" +msgid "Adjust wall layer height" +msgstr "Wand-Schichthöhe anpassen" + +msgid "Adjusted walls" +msgstr "Angepasste Wände" + +msgid "Adjustment direction" +msgstr "Anpassungsrichtung" + +msgid "Consistent" +msgstr "Konsistent" + +msgid "Decrease" +msgstr "Verringern" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der unteren Oberfläche.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der inneren Wände.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der internen massiven Füllung.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der internen spärlichen Füllung.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der äußeren Wände.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament zum Drucken der Stützstruktur-Basis und des Rafts.\n" +"\"Standard\" bedeutet kein spezifisches Filament für die Stützstruktur und " +"das aktuelle Filament wird verwendet." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament zum Drucken der Stützstruktur-Schnittstelle.\n" +"\"Standard\" bedeutet kein spezifisches Filament für die Stützstruktur-" +"Schnittstelle und das aktuelle Filament wird verwendet." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament zum Drucken der oberen Oberfläche.\n" +"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." + +msgid "Fixed" +msgstr "Fest" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Wie aggressiv Objektteile, die einem Extruder mit dickerer bevorzugter " +"Schichthöhe zugewiesen sind, zu dicken Schichten zusammengefasst werden.\n" +"Konsistent: Teile drucken mit höchstens zwei Schichthöhen - der Extruder-" +"Schichthöhe, wo ganze Schichtfolgen hineinpassen, und der Objekt-Schichthöhe " +"überall sonst. Das ergibt die gleichmäßigsten Wände.\n" +"Adaptiv: Schichtfolgen dürfen auch bei Zwischenvielfachen der Objekt-" +"Schichthöhe zusammengefasst werden, sodass mehr des Teils mit dickeren " +"Schichten druckt - um den Preis von Bändern wechselnder Schichthöhen an " +"gekrümmten Teilgrenzen.\n" +"Fest: Teile drucken immer mit der Extruder-Schichthöhe, auch wo sich die " +"Form über die zusammengefassten Schichten ändert oder überhängt; gekrümmte " +"Grenzen werden zu Stufen, und Details feiner als die dicken Schichten gehen " +"verloren. Nur Geometrie, die für eine ganze dicke Schicht zu kurz ist " +"(Teiloberseiten und die erste Schicht), druckt dünner." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Wie weit die Kontur eines Objektteils, das einem Extruder mit dickerer " +"bevorzugter Schichthöhe zugewiesen ist, über die Schichten einer dicken " +"Folge seitlich wandern darf und trotzdem zusammengefasst wird, als " +"Prozentsatz des Düsendurchmessers dieses Extruders. Höhere Werte fassen mehr " +"der gekrümmten Teilgrenzen zu dicken Schichten zusammen - um den Preis " +"raueren Grenzwänden: Abweichungen bis zu diesem Bruchteil des " +"Düsendurchmessers werden von den dicken Extrusionen geschluckt." + +msgid "Increase" +msgstr "Erhöhen" + +msgid "Inner walls" +msgstr "Innere Wände" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Schichthöhe, mit der dieser Extruder drucken soll; für Drucker, deren " +"Extruder unterschiedliche Düsengrößen haben. Sie muss ein ganzzahliges " +"Vielfaches der Objekt-Schichthöhe sein. Ein Teil, dessen Merkmale alle " +"diesem Extruder folgen, druckt nur auf jeder N-ten Schicht mit entsprechend " +"dickeren Extrusionen, wo seine Geometrie es erlaubt; sonst fällt es auf die " +"Objekt-Schichthöhe zurück. Kann der Rest des Teils nicht folgen, kombinieren " +"sich diesem Extruder zugewiesene Wände trotzdem eigenständig auf diese Höhe, " +"volldichte Deckflächen absorbieren die massiven Schichten darunter, und " +"Füllung (auch 100% dichte) kombiniert sich unabhängig auf diese Höhe. 0 " +"bedeutet, die Objekt-Schichthöhe zu verwenden." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Schichthöhe, mit der dieser Extruder drucken soll: ein ganzzahliges " +"Vielfaches der Objekt-Schichthöhe innerhalb der Schichthöhenbegrenzungen " +"dieses Extruders. Standard behält die Objekt-Schichthöhe bei." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Kein Extruder hat eine Düse, die dem Stützen-Düsendurchmesser entspricht." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Kein geladenes Filament entspricht dem Material für Stütz-/Raft-Basis (und " +"dem Stützen-Düsendurchmesser)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Kein geladenes Filament entspricht dem Material für Stütz-/Raft-" +"Schnittstellen (und dem Stützen-Düsendurchmesser)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Düse %1%: Schichthöhenbegrenzungen auf %2%-%3% mm gesetzt, aus \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Auf Druckern, deren Extruder unterschiedliche Düsendurchmesser haben, werden " +"nur Filamente dieses Düsendurchmessers zum Drucken von Stützen, Raft und " +"Stütz-Schnittstellen verwendet. Das hält Filamente anderer Düsengrößen - mit " +"ihren anderen Linienbreiten und Schichthöhenbegrenzungen - aus den Stützen " +"heraus. Auf einen nicht standardmäßigen Wert gesetzte Stützfilamente müssen " +"diesem Durchmesser entsprechen. Der Wert 0 erlaubt jedem Filament, Stützen " +"zu drucken." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Außen- und Innenwände drucken automatisch mit ihren eigenen bevorzugten " +"Schichthöhen, wenn eine Höhe ein ganzzahliges Vielfaches der anderen ist. " +"Wenn die Höhen nicht glatt teilbar sind, passt diese Option die Wand-" +"Schichthöhe eines der beiden Wandfilamente (unten gewählt) auf das nächste " +"Vielfache oder den nächsten Teiler der anderen an, damit sich die Wände " +"weiterhin aufteilen können. Die angepasste Höhe gilt nur für die Wände " +"dieses Filaments; andere Merkmale behalten die bevorzugte Schichthöhe. " +"Anpassungen verlassen nie die Schichthöhenbegrenzungen des Filaments: " +"Existiert in der gewählten Richtung keine erlaubte Höhe, drucken die Wände " +"wie üblich gemeinsam mit der niedrigeren Höhe." + +msgid "Outer walls" +msgstr "Äußere Wände" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Schichthöhen je Extruder werden im Vasenmodus nicht unterstützt." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Schichthöhen je Extruder werden zusammen mit Schnittstellenhüllen nicht " +"unterstützt." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Schichthöhen je Extruder werden zusammen mit variabler Schichthöhe nicht " +"unterstützt." + +msgid "Preferred layer height" +msgstr "Bevorzugte Schichthöhe" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Stützen und Raft-Basis nur mit Filamenten dieses Materialtyps drucken; " +"Extruder mit anderen Typen werden dafür nicht verwendet. Wirkt zusammen mit " +"der Stützen-Düsendurchmesser-Beschränkung. Leer lassen für keine " +"Beschränkung; ein ausdrücklich gewähltes Stütz-/Raft-Basisfilament hat " +"weiterhin Vorrang." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Stütz- und Raft-Schnittstellen nur mit Filamenten dieses Materialtyps " +"drucken; Extruder mit anderen Typen werden dafür nicht verwendet. Wirkt " +"zusammen mit der Stützen-Düsendurchmesser-Beschränkung. Leer lassen für " +"keine Beschränkung; ein ausdrücklich gewähltes Stütz-/Raft-" +"Schnittstellenfilament hat weiterhin Vorrang." + +msgid "Raft and support base" +msgstr "Raft und Stützbasis" + +msgid "Show legacy filament selection" +msgstr "Alte Filamentauswahl anzeigen" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Einige Objektteile bevorzugen %1% mm Schichten, aber die Düse von Filament " +"%2%, das andere Merkmale des Teils druckt, ist zu klein, um diese Höhe zu " +"extrudieren. Diese Teile drucken stattdessen mit der Objekt-Schichthöhe." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Einige Objektteile bevorzugen %1% mm Schichten, aber die Düse von " +"Wandfilament %2% ist zu klein, um diese Höhe zu extrudieren. Außen- und " +"Innenwände drucken zusammen, daher behalten diese Wände die Objekt-" +"Schichthöhe. Weisen Sie beide Wandmerkmale Filamenten mit ausreichend großen " +"Düsen zu." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Einige Objektteile drucken %1% mm Schichten mit Filament %2%, dessen " +"maximale Schichthöhe %3% mm beträgt. Weisen Sie die Merkmale des Teils " +"Filamenten der gröberen Düse zu, erhöhen Sie die maximale Schichthöhe des " +"Filaments, oder akzeptieren Sie das Drucken darüber." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Einige Objektteile drucken %1% mm Schichten mit Filament %2%, dessen " +"minimale Schichthöhe %3% mm beträgt. Erhöhen Sie die Objekt-Schichthöhe, " +"verwenden Sie für diese Merkmale ein Filament mit feinerer Düse, oder " +"akzeptieren Sie das Drucken unter dem Minimum des Extruders." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Einige Objektteile verwenden Filamente, deren bevorzugte Schichthöhen nicht " +"alle eingehalten werden können: Ein Teil druckt seine Merkmale mit einem " +"Schichtraster (bestimmt durch seine Wandfilamente oder, wenn kein " +"Wandfilament eine Präferenz hat, durch die Einigung der übrigen Merkmale); " +"die Wände, die Deckflächen und die Füllung können sich jeweils eigenständig " +"auf ihre eigene Höhe kombinieren, wenn der Rest des Teils ihnen nicht folgen " +"kann, aber die übrigen Merkmale drucken mit dem Raster des Teils." + +msgid "Support for mixed nozzle sizes" +msgstr "Stützen bei gemischten Düsengrößen" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Stützen könnten mit Extrudern unterschiedlicher Düsendurchmesser drucken. " +"Setzen Sie den Stützen-Düsendurchmesser (oder explizite Stütz- und " +"Schnittstellenfilamente), um die Stützen auf einer Düsengröße zu halten." + +msgid "Support nozzle diameter" +msgstr "Stützen-Düsendurchmesser" + +msgid "Support nozzle size" +msgstr "Stützen-Düsengröße" + +msgid "Support/raft base material" +msgstr "Material für Stütz-/Raft-Basis" + +msgid "Support/raft interface material" +msgstr "Material für Stütz-/Raft-Schnittstellen" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Die Füllungs-Linienbreite von %1% mm ist zu klein für auf %2% mm Höhe " +"kombinierte Füllung. Erhöhen Sie die Linienbreite oder senken Sie die " +"bevorzugte Schichthöhe des Füllfilaments." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Die Linienbreite von %1% mm ist zu klein für die %2% mm Schichthöhe ihres " +"Extruders. Erhöhen Sie die Linienbreite oder senken Sie die Extruder-" +"Schichthöhe." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Die Schichthöhe von Extruder %1% (%2% mm) darf seinen Düsendurchmesser nicht " +"überschreiten." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Die Schichthöhe von Extruder %1% (%2% mm) wird für einige Objektteile " +"ignoriert: Sie muss ein ganzzahliges Vielfaches der Objekt-Schichthöhe (%3% " +"mm) sein, nicht darunter liegen und darf den Düsendurchmesser des Extruders " +"nicht überschreiten." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Die Schichthöhe von Extruder %1% (%2% mm) ist kleiner als die Objekt-" +"Schichthöhe (%3% mm). Senken Sie die Objekt-Schichthöhe auf die feinste " +"Extruder-Schichthöhe." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Die Schichthöhe von Extruder %1% (%2% mm) muss ein ganzzahliges Vielfaches " +"der Objekt-Schichthöhe (%3% mm) sein." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Die niedrigste druckbare Schichthöhe des Extruders. Begrenzt die minimale " +"Schichthöhe bei aktivierter adaptiver Schichthöhe. Teile, die mit einer " +"dickeren bevorzugten Extruder-Schichthöhe drucken, fallen ebenfalls nie " +"unter diese Höhe zurück (außer der ersten Schicht)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Die bevorzugte Schichthöhe von Düse %1% passt nicht mehr durch sie hindurch " +"und wurde auf Standard zurückgesetzt." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Das Stütz-/Raft-Basisfilament ist nicht vom Material der Stütz-/Raft-Basis." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Das Stütz-/Raft-Basisfilament druckt mit einer Düse, die dem Stützen-" +"Düsendurchmesser nicht entspricht." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Das Stütz-/Raft-Schnittstellenfilament ist nicht vom Material der Stütz-/" +"Raft-Schnittstellen." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Das Stütz-/Raft-Schnittstellenfilament druckt mit einer Düse, die dem " +"Stützen-Düsendurchmesser nicht entspricht." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Die Wandfilamente einiger Objektteile bevorzugen unterschiedliche " +"Schichthöhen. Außen- und Innenwände drucken zusammen, daher behalten diese " +"Wände die Objekt-Schichthöhe. Weisen Sie beide Wandmerkmale Filamenten zu, " +"die dieselbe Höhe bevorzugen, um dickere Wände zu drucken." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Die Wandfilamente einiger Objektteile bevorzugen unterschiedliche " +"Schichthöhen. Außen- und Innenwände drucken zusammen, daher drucken diese " +"Wände mit der niedrigeren Höhe (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Die Wand-Schichthöhe von Filament %1% wurde von den bevorzugten %2% mm auf " +"%3% mm angepasst, damit Außen- und Innenwände mit kompatiblen Schichthöhen " +"drucken können (\"Wand-Schichthöhe anpassen\"). Nur die Wände dieses " +"Filaments drucken die angepasste Höhe; seine anderen Merkmale behalten die " +"bevorzugte." + +msgid "Thick layer regions" +msgstr "Bereiche dicker Schichten" + +msgid "Thick layer tolerance" +msgstr "Toleranz dicker Schichten" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Dieser Drucker hat kein Profil für eine %1% mm Düse. Bitte prüfen Sie die " +"Schichthöhenbegrenzungen von Düse %2% in den Druckereinstellungen." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Dieser Drucker verwendet unterschiedliche Düsengrößen. Wählen Sie die " +"Düsengröße, die die Stützen druckt, und die Filamenttypen für das Raft und " +"die Stütz-Schnittstellen." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Ob die Wand-Schichthöhe des angepassten Wandfilaments verringert oder erhöht " +"wird, um eine mit dem anderen Wandfilament kompatible Höhe zu erreichen. " +"Höhen außerhalb der Schichthöhenbegrenzungen des angepassten Filaments " +"werden nie verwendet: Existiert in dieser Richtung keine erlaubte Höhe, " +"drucken die Wände wie üblich gemeinsam mit der niedrigeren Höhe." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Welches der beiden Wandfilamente seine Wand-Schichthöhe angepasst bekommt, " +"wenn die bevorzugten Schichthöhen nicht glatt teilbar sind." + # AI Translated msgid "Main Extruder" msgstr "Hauptextruder" @@ -28690,13 +29227,6 @@ msgstr "" "infill_anchor begrenzt, aber nicht länger als dieser Parameter. Setzen Sie " "diesen Parameter auf Null, um die Verankerung zu deaktivieren." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der internen spärlichen Füllung.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - msgid "Infill/wall overlap" msgstr "Überlappung Füllung/Wand" @@ -29049,26 +29579,6 @@ msgstr "" "verwenden hierfür eine unterschiedliche Druckgeschwindigkeiten. Bei einem " "100%% Überhang wird die Brückengeschwindigkeit verwendet." -msgid "Outer walls" -msgstr "Äußere Wände" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der äußeren Wände.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - -msgid "Inner walls" -msgstr "Innere Wände" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der inneren Wände.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - msgid "This is the speed for inner walls." msgstr "Druckgeschwindigkeit der Innenwand" @@ -29258,27 +29768,6 @@ msgstr "" "Innere Füllbereiche, die kleiner als dieser Wert sind, werden durch massive " "Füllungen ersetzt." -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der internen massiven Füllung.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der oberen Oberfläche.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament zum Drucken der unteren Oberfläche.\n" -"\"Standard\" verwendet das Filament des aktiven Objekts/Teils." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29449,15 +29938,6 @@ msgstr "" "wird dieser Wert ignoriert und die Stützen werden in direktem Kontakt mit " "dem Objekt gedruckt (kein Abstand)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament zum Drucken der Stützstruktur-Basis und des Rafts.\n" -"\"Standard\" bedeutet kein spezifisches Filament für die Stützstruktur und " -"das aktuelle Filament wird verwendet." - msgid "Loop pattern interface" msgstr "Schleifenmuster-Schnittstelle" @@ -29468,15 +29948,6 @@ msgstr "" "Deckt die obere Kontaktschicht der Stützstrukturen mit Schleifen ab. " "Standardmäßig deaktiviert." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament zum Drucken der Stützstruktur-Schnittstelle.\n" -"\"Standard\" bedeutet kein spezifisches Filament für die Stützstruktur-" -"Schnittstelle und das aktuelle Filament wird verwendet." - # AI Translated msgid "This is the number of top interface layers." msgstr "Anzahl der oberen Schnittstellenschichten." diff --git a/localization/i18n/en/Snapmaker_Orca_en.po b/localization/i18n/en/Snapmaker_Orca_en.po index fde219cc543..9f36b0d9886 100644 --- a/localization/i18n/en/Snapmaker_Orca_en.po +++ b/localization/i18n/en/Snapmaker_Orca_en.po @@ -16875,6 +16875,525 @@ msgstr "" "ABS, appropriately increasing the heatbed temperature can reduce the " "probability of warping?" +msgid "Adjust wall layer height" +msgstr "Adjust wall layer height" + +msgid "Adjusted walls" +msgstr "Adjusted walls" + +msgid "Adjustment direction" +msgstr "Adjustment direction" + +msgid "Consistent" +msgstr "Consistent" + +msgid "Decrease" +msgstr "Decrease" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." + +msgid "Fixed" +msgstr "Fixed" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." + +msgid "Increase" +msgstr "Increase" + +msgid "Inner walls" +msgstr "Inner walls" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "No extruder has a nozzle matching the support nozzle diameter." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." + +msgid "Outer walls" +msgstr "Outer walls" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Per-extruder layer heights are not supported in spiral vase mode." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Per-extruder layer heights are not supported together with interface shells." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Per-extruder layer heights are not supported together with variable layer " +"height." + +msgid "Preferred layer height" +msgstr "Preferred layer height" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." + +msgid "Raft and support base" +msgstr "Raft and support base" + +msgid "Show legacy filament selection" +msgstr "Show legacy filament selection" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." + +msgid "Support for mixed nozzle sizes" +msgstr "Support for mixed nozzle sizes" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." + +msgid "Support nozzle diameter" +msgstr "Support nozzle diameter" + +msgid "Support nozzle size" +msgstr "Support nozzle size" + +msgid "Support/raft base material" +msgstr "Support/raft base material" + +msgid "Support/raft interface material" +msgstr "Support/raft interface material" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"The support/raft base filament is not of the support/raft base material." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"The support/raft interface filament is not of the support/raft interface " +"material." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." + +msgid "Thick layer regions" +msgstr "Thick layer regions" + +msgid "Thick layer tolerance" +msgstr "Thick layer tolerance" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." + msgid "Main Extruder" msgstr "" @@ -23919,11 +24438,6 @@ msgid "" "create the same result as with 1000 & 0." msgstr "" -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - msgid "Infill/wall overlap" msgstr "" @@ -24201,22 +24715,6 @@ msgid "" "different speed to print. For 100%% overhang, bridging speed is used." msgstr "" -msgid "Outer walls" -msgstr "" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - -msgid "Inner walls" -msgstr "" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - msgid "This is the speed for inner walls." msgstr "" @@ -24361,21 +24859,6 @@ msgid "" "by internal solid infill." msgstr "" -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -24493,12 +24976,6 @@ msgid "" "support is printed in direct contact with the object (no gap)." msgstr "" -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" - msgid "Loop pattern interface" msgstr "" @@ -24507,12 +24984,6 @@ msgid "" "by default." msgstr "" -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" - msgid "This is the number of top interface layers." msgstr "" diff --git a/localization/i18n/es/Snapmaker_Orca_es.po b/localization/i18n/es/Snapmaker_Orca_es.po index a9d93267d17..7c45d0ea160 100644 --- a/localization/i18n/es/Snapmaker_Orca_es.po +++ b/localization/i18n/es/Snapmaker_Orca_es.po @@ -19210,6 +19210,552 @@ msgstr "" "aumentar adecuadamente la temperatura de la cama térmica puede reducir la " "probabilidad de deformaciones?" +msgid "Adjust wall layer height" +msgstr "Ajustar la altura de capa de los perímetros" + +msgid "Adjusted walls" +msgstr "Perímetros ajustados" + +msgid "Adjustment direction" +msgstr "Dirección del ajuste" + +msgid "Consistent" +msgstr "Consistente" + +msgid "Decrease" +msgstr "Disminuir" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir la superficie inferior.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir las paredes interiores.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir el relleno sólido interno.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir un relleno interno poco denso.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir las paredes exteriores.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filamento para imprimir la base de soporte y la balsa.\n" +"«Predeterminado» significa que no hay un filamento específico para el " +"soporte y se utiliza el filamento actual." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filamento para la interfaz de soporte de impresión.\n" +"«Predeterminado» significa que no hay ningún filamento específico para la " +"interfaz de soporte y se utiliza el filamento actual." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir la superficie superior.\n" +"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." + +msgid "Fixed" +msgstr "Fijo" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Con qué agresividad las piezas asignadas a un extrusor con una altura de " +"capa preferida más gruesa se combinan en capas gruesas.\n" +"Consistente: las piezas se imprimen con como mucho dos alturas de capa: la " +"altura de capa del extrusor donde caben series enteras de capas y la altura " +"de capa del objeto en el resto. Esto da los perímetros más uniformes.\n" +"Adaptativo: las series también pueden combinarse en múltiplos intermedios de " +"la altura de capa del objeto, de modo que más parte de la pieza se imprime " +"con capas gruesas, a costa de bandas de alturas de capa variables en los " +"contornos curvos.\n" +"Fijo: las piezas siempre se imprimen a la altura de capa del extrusor, " +"incluso donde la forma cambia a través de las capas combinadas o hay " +"voladizos; los contornos curvos se convierten en escalones y se pierde el " +"detalle más fino que las capas gruesas. Solo la geometría demasiado corta " +"para una capa gruesa entera (las partes superiores y la primera capa) se " +"imprime más fina." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Cuánto puede desplazarse lateralmente el contorno de una pieza asignada a un " +"extrusor con una altura de capa preferida más gruesa a través de las capas " +"de una serie gruesa y aun así combinarse, como porcentaje del diámetro de " +"boquilla de ese extrusor. Valores más altos combinan más contornos curvos en " +"capas gruesas, a costa de perímetros de contorno más rugosos: las " +"desviaciones hasta esta fracción del diámetro de la boquilla quedan " +"absorbidas por las extrusiones gruesas." + +msgid "Increase" +msgstr "Aumentar" + +msgid "Inner walls" +msgstr "Paredes internas" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Altura de capa con la que debe imprimir este extrusor, para impresoras cuyos " +"extrusores tienen boquillas de distintos tamaños. Debe ser un múltiplo " +"entero de la altura de capa del objeto. Una pieza cuyas características " +"siguen todas a este extrusor se imprime solo en una de cada N capas con " +"extrusiones correspondientemente más gruesas, donde su geometría lo permite; " +"en el resto vuelve a la altura de capa del objeto. Cuando el resto de la " +"pieza no puede seguirlo, los perímetros asignados a este extrusor se " +"combinan igualmente por su cuenta a esta altura, las superficies superiores " +"totalmente densas absorben las capas sólidas inferiores, y el relleno poco " +"denso o denso al 100% se combina de forma independiente a esta altura. 0 " +"significa usar la altura de capa del objeto." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Altura de capa con la que debe imprimir este extrusor: un múltiplo entero de " +"la altura de capa del objeto dentro de los límites de altura de capa de este " +"extrusor. Por defecto mantiene la altura de capa del objeto." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Ningún extrusor tiene una boquilla que coincida con el diámetro de boquilla " +"de soportes." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Ningún filamento cargado coincide con el material de la base de soportes/" +"balsa (y con el diámetro de boquilla de soportes)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Ningún filamento cargado coincide con el material de la interfaz de soportes/" +"balsa (y con el diámetro de boquilla de soportes)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Boquilla %1%: límites de altura de capa fijados en %2%-%3% mm, desde \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"En impresoras cuyos extrusores tienen diámetros de boquilla distintos, solo " +"se usan filamentos de este diámetro de boquilla para imprimir soportes, " +"balsa e interfaz de soportes. Esto mantiene los filamentos de otros tamaños " +"de boquilla - con sus distintos anchos de línea y límites de altura de capa " +"- fuera de los soportes. Los filamentos de soporte con un valor distinto del " +"predeterminado deben coincidir con este diámetro. El valor 0 permite que " +"cualquier filamento imprima soportes." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Los perímetros externos e internos se imprimen automáticamente a sus propias " +"alturas de capa preferidas cuando una altura es un múltiplo entero de la " +"otra. Cuando las alturas no se dividen exactamente, esta opción ajusta la " +"altura de capa de los perímetros de uno de los dos filamentos de perímetro " +"(elegido abajo) al múltiplo o divisor más cercano de la otra, para que los " +"perímetros aún puedan separarse. La altura ajustada solo se aplica a los " +"perímetros de ese filamento; las demás características mantienen la altura " +"de capa preferida. Los ajustes nunca salen de los límites de altura de capa " +"del filamento: si no existe una altura permitida en la dirección elegida, " +"los perímetros se imprimen juntos a la altura menor como de costumbre." + +msgid "Outer walls" +msgstr "Paredes exteriores" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Las alturas de capa por extrusor no son compatibles con el modo vaso en " +"espiral." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Las alturas de capa por extrusor no son compatibles con las carcasas de " +"interfaz." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Las alturas de capa por extrusor no son compatibles con la altura de capa " +"variable." + +msgid "Preferred layer height" +msgstr "Altura de capa preferida" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Imprimir la base de soportes y la balsa solo con filamentos de este tipo de " +"material; los extrusores cargados con otros tipos no se usan para ello. Se " +"combina con la restricción del diámetro de boquilla de soportes. Dejar vacío " +"para no restringir; un filamento de base de soportes/balsa elegido " +"explícitamente sigue teniendo prioridad." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Imprimir la interfaz de soportes y balsa solo con filamentos de este tipo de " +"material; los extrusores cargados con otros tipos no se usan para ello. Se " +"combina con la restricción del diámetro de boquilla de soportes. Dejar vacío " +"para no restringir; un filamento de interfaz de soportes/balsa elegido " +"explícitamente sigue teniendo prioridad." + +msgid "Raft and support base" +msgstr "Balsa y base de soportes" + +msgid "Show legacy filament selection" +msgstr "Mostrar la selección de filamento antigua" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Algunas piezas prefieren capas de %1% mm, pero la boquilla del filamento %2% " +"que imprime otras características de la pieza es demasiado pequeña para " +"extruir esa altura. Estas piezas se imprimen con la altura de capa del " +"objeto en su lugar." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Algunas piezas prefieren capas de %1% mm, pero la boquilla del filamento de " +"perímetros %2% es demasiado pequeña para extruir esa altura. Los perímetros " +"externos e internos se imprimen juntos, así que estos perímetros mantienen " +"la altura de capa del objeto. Asigne ambas características de perímetro a " +"filamentos con boquillas suficientemente grandes." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Algunas piezas imprimen capas de %1% mm con el filamento %2%, cuya altura de " +"capa máxima es %3% mm. Asigne las características de la pieza a filamentos " +"de la boquilla más gruesa, aumente la altura de capa máxima del filamento o " +"acepte imprimir por encima." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Algunas piezas imprimen capas de %1% mm con el filamento %2%, cuya altura de " +"capa mínima es %3% mm. Aumente la altura de capa del objeto, use un " +"filamento con una boquilla más fina para estas características o acepte " +"imprimir por debajo del mínimo del extrusor." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Algunas piezas usan filamentos cuyas alturas de capa preferidas no pueden " +"respetarse todas: una pieza imprime sus características con un solo paso de " +"capa (fijado por sus filamentos de perímetro o, cuando ningún filamento de " +"perímetro tiene preferencia, por el acuerdo de las demás características); " +"los perímetros, las superficies superiores y el relleno pueden combinarse " +"cada uno a su propia altura cuando el resto de la pieza no puede seguirlos, " +"pero las características restantes se imprimen con el paso de la pieza." + +msgid "Support for mixed nozzle sizes" +msgstr "Soportes con tamaños de boquilla mixtos" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Los soportes podrían imprimirse con extrusores de diámetros de boquilla " +"distintos. Fije el diámetro de boquilla de soportes (o filamentos explícitos " +"de soporte e interfaz) para mantener los soportes en un solo tamaño de " +"boquilla." + +msgid "Support nozzle diameter" +msgstr "Diámetro de boquilla de soportes" + +msgid "Support nozzle size" +msgstr "Tamaño de boquilla de soportes" + +msgid "Support/raft base material" +msgstr "Material de la base de soportes/balsa" + +msgid "Support/raft interface material" +msgstr "Material de la interfaz de soportes/balsa" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"El ancho de línea de relleno de %1% mm es demasiado pequeño para relleno " +"combinado en capas de %2% mm de alto. Aumente el ancho de línea o reduzca la " +"altura de capa preferida del filamento de relleno." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"El ancho de línea de %1% mm es demasiado pequeño para la altura de capa de " +"%2% mm de su extrusor. Aumente el ancho de línea o reduzca la altura de capa " +"del extrusor." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"La altura de capa del extrusor %1% (%2% mm) no puede superar su diámetro de " +"boquilla." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"La altura de capa del extrusor %1% (%2% mm) se ignora para algunas piezas: " +"debe ser un múltiplo entero de la altura de capa del objeto (%3% mm), no " +"inferior a ella, y no debe superar el diámetro de boquilla del extrusor." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"La altura de capa del extrusor %1% (%2% mm) es menor que la altura de capa " +"del objeto (%3% mm). Reduzca la altura de capa del objeto a la altura de " +"capa de extrusor más fina." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"La altura de capa del extrusor %1% (%2% mm) debe ser un múltiplo entero de " +"la altura de capa del objeto (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"La altura de capa imprimible más baja del extrusor. Se usa para limitar la " +"altura de capa mínima cuando la altura de capa adaptativa está activada. Las " +"piezas impresas con una altura de capa de extrusor preferida más gruesa " +"tampoco bajan nunca de esta altura (excepto la primera capa)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"La altura de capa preferida de la boquilla %1% ya no cabe por ella y se " +"restableció a Por defecto." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"El filamento de la base de soportes/balsa no es del material de la base de " +"soportes/balsa." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"El filamento de la base de soportes/balsa imprime con una boquilla que no " +"coincide con el diámetro de boquilla de soportes." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"El filamento de la interfaz de soportes/balsa no es del material de la " +"interfaz de soportes/balsa." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"El filamento de la interfaz de soportes/balsa imprime con una boquilla que " +"no coincide con el diámetro de boquilla de soportes." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Los filamentos de perímetro de algunas piezas prefieren alturas de capa " +"distintas. Los perímetros externos e internos se imprimen juntos, así que " +"estos perímetros mantienen la altura de capa del objeto. Asigne ambas " +"características de perímetro a filamentos que prefieran la misma altura para " +"imprimir perímetros más gruesos." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Los filamentos de perímetro de algunas piezas prefieren alturas de capa " +"distintas. Los perímetros externos e internos se imprimen juntos, así que " +"estos perímetros se imprimen con la altura menor (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"La altura de capa de perímetros del filamento %1% se ajustó de los %2% mm " +"preferidos a %3% mm para que los perímetros externos e internos puedan " +"imprimirse a alturas de capa compatibles (\"Ajustar la altura de capa de los " +"perímetros\"). Solo los perímetros de este filamento imprimen la altura " +"ajustada; sus demás características mantienen la preferida." + +msgid "Thick layer regions" +msgstr "Regiones de capas gruesas" + +msgid "Thick layer tolerance" +msgstr "Tolerancia de capas gruesas" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Esta impresora no tiene perfil para una boquilla de %1% mm. Revise los " +"límites de altura de capa de la boquilla %2% en los ajustes de la impresora." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Esta impresora usa tamaños de boquilla distintos. Seleccione el tamaño de " +"boquilla que imprime los soportes y los tipos de filamento usados para la " +"balsa y la interfaz de soportes." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Si la altura de capa de perímetros del filamento ajustado se disminuye o se " +"aumenta para alcanzar una altura compatible con el otro filamento de " +"perímetro. Nunca se usan alturas fuera de los límites de altura de capa del " +"filamento ajustado: si no existe una altura permitida en esta dirección, los " +"perímetros se imprimen juntos a la altura menor como de costumbre." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Cuál de los dos filamentos de perímetro recibe el ajuste de su altura de " +"capa de perímetros cuando las alturas de capa preferidas no se dividen " +"exactamente." + msgid "Main Extruder" msgstr "Extrusor principal" @@ -28121,13 +28667,6 @@ msgstr "" "Si se deja a 0, el algoritmo antiguo para conexión de relleno se usará, esto " "debería drear el mismo resultado que con 1000 y 0." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir un relleno interno poco denso.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - msgid "Infill/wall overlap" msgstr "Solape de relleno/perímetro" @@ -28475,26 +29014,6 @@ msgstr "" "utiliza diferentes velocidades para imprimir. Para el 100%% de voladizo, se " "utiliza la velocidad de puente." -msgid "Outer walls" -msgstr "Paredes exteriores" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir las paredes exteriores.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - -msgid "Inner walls" -msgstr "Paredes internas" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir las paredes interiores.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - msgid "This is the speed for inner walls." msgstr "Velocidad del perímetro interno." @@ -28676,27 +29195,6 @@ msgstr "" "Las áreas de relleno de baja densidad con un tamaño por debajo de este " "umbral se sustituyen por un relleno sólido interno." -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir el relleno sólido interno.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir la superficie superior.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir la superficie inferior.\n" -"La opción «Predeterminado» utiliza el filamento del objeto o pieza activa." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28859,15 +29357,6 @@ msgstr "" "este valor se ignora y el soporte se imprime en contacto directo con el " "objeto (sin separación)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filamento para imprimir la base de soporte y la balsa.\n" -"«Predeterminado» significa que no hay un filamento específico para el " -"soporte y se utiliza el filamento actual." - msgid "Loop pattern interface" msgstr "Uso de la interfaz en forma de bucle" @@ -28878,15 +29367,6 @@ msgstr "" "Cubrir la capa de contacto superior de los soportes con bucles. Desactivado " "por defecto." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filamento para la interfaz de soporte de impresión.\n" -"«Predeterminado» significa que no hay ningún filamento específico para la " -"interfaz de soporte y se utiliza el filamento actual." - msgid "This is the number of top interface layers." msgstr "Este es el número de capas de interfaz superiores." diff --git a/localization/i18n/eu/OrcaSlicer_eu.po b/localization/i18n/eu/Snapmaker_Orca_eu.po similarity index 100% rename from localization/i18n/eu/OrcaSlicer_eu.po rename to localization/i18n/eu/Snapmaker_Orca_eu.po diff --git a/localization/i18n/fr/Snapmaker_Orca_fr.po b/localization/i18n/fr/Snapmaker_Orca_fr.po index 0191355d77b..53fdeac1c8d 100644 --- a/localization/i18n/fr/Snapmaker_Orca_fr.po +++ b/localization/i18n/fr/Snapmaker_Orca_fr.po @@ -19512,6 +19512,559 @@ msgstr "" "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 "Adjust wall layer height" +msgstr "Ajuster la hauteur de couche des parois" + +msgid "Adjusted walls" +msgstr "Parois ajustées" + +msgid "Adjustment direction" +msgstr "Sens de l'ajustement" + +msgid "Consistent" +msgstr "Cohérent" + +msgid "Decrease" +msgstr "Diminuer" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer la surface inférieure.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer les parois internes.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer le remplissage plein interne.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer le remplissage interne.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer les parois externes.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament pour imprimer la base des supports et le radeau.\n" +"\"Défaut\" signifie qu’aucun filament spécifique n’est dédié aux supports : " +"le filament actuel est utilisé." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament pour imprimer l’interface des supports.\n" +"\"Défaut\" signifie qu’aucun filament spécifique n’est dédié à l’interface " +"des supports : le filament actuel est utilisé." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament pour imprimer la surface supérieure.\n" +"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." + +msgid "Fixed" +msgstr "Fixe" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Détermine l'agressivité avec laquelle les pièces affectées à un extrudeur " +"avec une hauteur de couche préférée plus épaisse sont combinées en couches " +"épaisses.\n" +"Cohérent : les pièces s'impriment avec au plus deux hauteurs de couche - la " +"hauteur de couche de l'extrudeur partout où des séries entières de couches " +"tiennent, et la hauteur de couche de l'objet partout ailleurs. Cela donne " +"les parois les plus uniformes.\n" +"Adaptatif : les séries peuvent aussi être combinées à des multiples " +"intermédiaires de la hauteur de couche de l'objet, donc une plus grande " +"partie de la pièce s'imprime en couches épaisses, au prix de bandes de " +"hauteurs de couche variables sur les contours courbes.\n" +"Fixe : les pièces s'impriment toujours à la hauteur de couche de " +"l'extrudeur, même là où la forme change à travers les couches combinées ou " +"surplombe ; les contours courbes deviennent des marches et les détails plus " +"fins que les couches épaisses sont perdus. Seule la géométrie trop courte " +"pour une couche épaisse entière (les sommets des pièces et la première " +"couche) s'imprime plus finement." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Distance de dérive latérale autorisée du contour d'une pièce affectée à un " +"extrudeur avec une hauteur de couche préférée plus épaisse à travers les " +"couches d'une série épaisse, tout en restant combinable, en pourcentage du " +"diamètre de buse de cet extrudeur. Des valeurs plus élevées combinent " +"davantage de contours courbes en couches épaisses, au prix de parois de " +"contour plus rugueuses : les écarts jusqu'à cette fraction du diamètre de la " +"buse sont absorbés par les extrusions épaisses." + +msgid "Increase" +msgstr "Augmenter" + +msgid "Inner walls" +msgstr "Parois internes" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Hauteur de couche avec laquelle cet extrudeur doit imprimer, pour les " +"imprimantes dont les extrudeurs ont des tailles de buse différentes. Elle " +"doit être un multiple entier de la hauteur de couche de l'objet. Une pièce " +"dont toutes les caractéristiques suivent cet extrudeur ne s'imprime que sur " +"une couche sur N avec des extrusions plus épaisses en conséquence, partout " +"où sa géométrie le permet ; ailleurs, elle revient à la hauteur de couche de " +"l'objet. Quand le reste de la pièce ne peut pas suivre, les parois affectées " +"à cet extrudeur se combinent quand même seules à cette hauteur, les surfaces " +"supérieures pleines absorbent les couches solides en dessous, et le " +"remplissage (clairsemé ou dense à 100%) se combine indépendamment à cette " +"hauteur. 0 signifie utiliser la hauteur de couche de l'objet." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Hauteur de couche avec laquelle cet extrudeur doit imprimer : un multiple " +"entier de la hauteur de couche de l'objet dans les limites de hauteur de " +"couche de cet extrudeur. Défaut conserve la hauteur de couche de l'objet." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Aucun extrudeur n'a de buse correspondant au diamètre de buse des supports." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Aucun filament chargé ne correspond au matériau de la base des supports/du " +"radeau (et au diamètre de buse des supports)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Aucun filament chargé ne correspond au matériau de l'interface des supports/" +"du radeau (et au diamètre de buse des supports)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Buse %1% : limites de hauteur de couche réglées sur %2%-%3% mm, depuis \"%4%" +"\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Sur les imprimantes dont les extrudeurs ont des diamètres de buse " +"différents, seuls les filaments de ce diamètre de buse sont utilisés pour " +"imprimer les supports, le radeau et l'interface des supports. Cela tient les " +"filaments d'autres tailles de buse - avec leurs largeurs de ligne et limites " +"de hauteur de couche différentes - à l'écart des supports. Les filaments de " +"support réglés sur une valeur non par défaut doivent correspondre à ce " +"diamètre. La valeur 0 permet à tout filament d'imprimer les supports." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Les parois extérieures et intérieures s'impriment automatiquement à leurs " +"propres hauteurs de couche préférées quand une hauteur est un multiple " +"entier de l'autre. Quand les hauteurs ne se divisent pas exactement, cette " +"option ajuste la hauteur de couche des parois de l'un des deux filaments de " +"paroi (choisi ci-dessous) au multiple ou diviseur le plus proche de l'autre, " +"pour que les parois puissent encore se séparer. La hauteur ajustée ne " +"s'applique qu'aux parois de ce filament ; les autres caractéristiques " +"conservent la hauteur de couche préférée. Les ajustements ne sortent jamais " +"des limites de hauteur de couche du filament : si aucune hauteur autorisée " +"n'existe dans le sens choisi, les parois s'impriment ensemble à la hauteur " +"inférieure comme d'habitude." + +msgid "Outer walls" +msgstr "Parois externes" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Les hauteurs de couche par extrudeur ne sont pas prises en charge en mode " +"vase spirale." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Les hauteurs de couche par extrudeur ne sont pas prises en charge avec les " +"coques d'interface." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Les hauteurs de couche par extrudeur ne sont pas prises en charge avec la " +"hauteur de couche variable." + +msgid "Preferred layer height" +msgstr "Hauteur de couche préférée" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"N'imprimer la base des supports et le radeau qu'avec des filaments de ce " +"type de matériau ; les extrudeurs chargés avec d'autres types ne sont pas " +"utilisés pour cela. Se combine avec la restriction du diamètre de buse des " +"supports. Laisser vide pour aucune restriction ; un filament de base des " +"supports/du radeau choisi explicitement garde la priorité." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"N'imprimer l'interface des supports et du radeau qu'avec des filaments de ce " +"type de matériau ; les extrudeurs chargés avec d'autres types ne sont pas " +"utilisés pour cela. Se combine avec la restriction du diamètre de buse des " +"supports. Laisser vide pour aucune restriction ; un filament d'interface des " +"supports/du radeau choisi explicitement garde la priorité." + +msgid "Raft and support base" +msgstr "Radeau et base des supports" + +msgid "Show legacy filament selection" +msgstr "Afficher l'ancienne sélection de filament" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Certaines pièces préfèrent des couches de %1% mm, mais la buse du filament " +"%2% qui imprime d'autres caractéristiques de la pièce est trop petite pour " +"extruder cette hauteur. Ces pièces s'impriment à la hauteur de couche de " +"l'objet à la place." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Certaines pièces préfèrent des couches de %1% mm, mais la buse du filament " +"de paroi %2% est trop petite pour extruder cette hauteur. Les parois " +"extérieures et intérieures s'impriment ensemble, donc ces parois conservent " +"la hauteur de couche de l'objet. Affectez les deux types de parois à des " +"filaments avec des buses assez grandes." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Certaines pièces impriment des couches de %1% mm avec le filament %2% dont " +"la hauteur de couche maximale est %3% mm. Affectez les caractéristiques de " +"la pièce aux filaments de la buse la plus grosse, augmentez la hauteur de " +"couche maximale du filament, ou acceptez d'imprimer au-dessus." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Certaines pièces impriment des couches de %1% mm avec le filament %2% dont " +"la hauteur de couche minimale est %3% mm. Augmentez la hauteur de couche de " +"l'objet, utilisez un filament avec une buse plus fine pour ces " +"caractéristiques, ou acceptez d'imprimer sous le minimum de l'extrudeur." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Certaines pièces utilisent des filaments dont les hauteurs de couche " +"préférées ne peuvent pas toutes être respectées : une pièce imprime ses " +"caractéristiques avec un seul pas de couche (fixé par ses filaments de " +"paroi, ou par l'accord des autres caractéristiques quand aucun filament de " +"paroi n'a de préférence) ; les parois, les surfaces supérieures et le " +"remplissage peuvent chacun se combiner à leur propre hauteur quand le reste " +"de la pièce ne peut pas les suivre, mais les caractéristiques restantes " +"s'impriment avec le pas de la pièce." + +msgid "Support for mixed nozzle sizes" +msgstr "Supports pour tailles de buse mixtes" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Les supports pourraient s'imprimer avec des extrudeurs de diamètres de buse " +"différents. Réglez le diamètre de buse des supports (ou des filaments de " +"support et d'interface explicites) pour garder les supports sur une seule " +"taille de buse." + +msgid "Support nozzle diameter" +msgstr "Diamètre de buse des supports" + +msgid "Support nozzle size" +msgstr "Taille de buse des supports" + +msgid "Support/raft base material" +msgstr "Matériau de la base des supports/du radeau" + +msgid "Support/raft interface material" +msgstr "Matériau de l'interface des supports/du radeau" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"La largeur de ligne de remplissage de %1% mm est trop petite pour un " +"remplissage combiné en couches de %2% mm de haut. Augmentez la largeur de " +"ligne ou diminuez la hauteur de couche préférée du filament de remplissage." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"La largeur de ligne de %1% mm est trop petite pour la hauteur de couche de " +"%2% mm de son extrudeur. Augmentez la largeur de ligne ou diminuez la " +"hauteur de couche de l'extrudeur." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"La hauteur de couche de l'extrudeur %1% (%2% mm) ne peut pas dépasser son " +"diamètre de buse." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"La hauteur de couche de l'extrudeur %1% (%2% mm) est ignorée pour certaines " +"pièces : elle doit être un multiple entier de la hauteur de couche de " +"l'objet (%3% mm), pas en dessous, et ne doit pas dépasser le diamètre de " +"buse de l'extrudeur." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"La hauteur de couche de l'extrudeur %1% (%2% mm) est plus petite que la " +"hauteur de couche de l'objet (%3% mm). Diminuez la hauteur de couche de " +"l'objet à la hauteur de couche d'extrudeur la plus fine." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"La hauteur de couche de l'extrudeur %1% (%2% mm) doit être un multiple " +"entier de la hauteur de couche de l'objet (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"La hauteur de couche imprimable la plus basse de l'extrudeur. Sert à limiter " +"la hauteur de couche minimale quand la hauteur de couche adaptative est " +"activée. Les pièces imprimées avec une hauteur de couche d'extrudeur " +"préférée plus épaisse ne redescendent jamais non plus sous cette hauteur " +"(première couche exceptée)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"La hauteur de couche préférée de la buse %1% ne passe plus à travers elle et " +"a été réinitialisée sur Défaut." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Le filament de la base des supports/du radeau n'est pas du matériau de la " +"base des supports/du radeau." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Le filament de la base des supports/du radeau s'imprime avec une buse qui ne " +"correspond pas au diamètre de buse des supports." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Le filament de l'interface des supports/du radeau n'est pas du matériau de " +"l'interface des supports/du radeau." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Le filament de l'interface des supports/du radeau s'imprime avec une buse " +"qui ne correspond pas au diamètre de buse des supports." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Les filaments de paroi de certaines pièces préfèrent des hauteurs de couche " +"différentes. Les parois extérieures et intérieures s'impriment ensemble, " +"donc ces parois conservent la hauteur de couche de l'objet. Affectez les " +"deux types de parois à des filaments préférant la même hauteur pour imprimer " +"des parois plus épaisses." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Les filaments de paroi de certaines pièces préfèrent des hauteurs de couche " +"différentes. Les parois extérieures et intérieures s'impriment ensemble, " +"donc ces parois s'impriment à la hauteur inférieure (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"La hauteur de couche des parois du filament %1% a été ajustée de %2% mm " +"(préférée) à %3% mm pour que les parois extérieures et intérieures puissent " +"s'imprimer à des hauteurs de couche compatibles (\"Ajuster la hauteur de " +"couche des parois\"). Seules les parois de ce filament impriment la hauteur " +"ajustée ; ses autres caractéristiques conservent la hauteur préférée." + +msgid "Thick layer regions" +msgstr "Régions à couches épaisses" + +msgid "Thick layer tolerance" +msgstr "Tolérance des couches épaisses" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Cette imprimante n'a pas de profil pour une buse de %1% mm. Veuillez " +"vérifier les limites de hauteur de couche de la buse %2% dans les réglages " +"de l'imprimante." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Cette imprimante utilise des tailles de buse différentes. Sélectionnez la " +"taille de buse qui imprime les supports, et les types de filament utilisés " +"pour le radeau et l'interface des supports." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Détermine si la hauteur de couche des parois du filament ajusté est diminuée " +"ou augmentée pour atteindre une hauteur compatible avec l'autre filament de " +"paroi. Les hauteurs hors des limites de hauteur de couche du filament ajusté " +"ne sont jamais utilisées : si aucune hauteur autorisée n'existe dans ce " +"sens, les parois s'impriment ensemble à la hauteur inférieure comme " +"d'habitude." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Lequel des deux filaments de paroi voit sa hauteur de couche des parois " +"ajustée quand les hauteurs de couche préférées ne se divisent pas exactement." + # AI Translated msgid "Main Extruder" msgstr "Extrudeur principal" @@ -28699,13 +29252,6 @@ msgstr "" "S’il est défini sur 0, l’ancien algorithme de connexion de remplissage sera " "utilisé, il devrait créer le même résultat qu’avec 1000 et 0." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer le remplissage interne.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - msgid "Infill/wall overlap" msgstr "Chevauchement de remplissage/paroi" @@ -29060,26 +29606,6 @@ msgstr "" "utilisez une vitesse différente pour imprimer. Pour un surplomb de 100%% la " "vitesse du pont est utilisée." -msgid "Outer walls" -msgstr "Parois extérieures" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer les parois externes.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - -msgid "Inner walls" -msgstr "Parois intérieures" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer les parois internes.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - msgid "This is the speed for inner walls." msgstr "Vitesse de la paroi intérieure" @@ -29270,27 +29796,6 @@ msgstr "" "Les zones de remplissage plus petites que cette valeur seuil sont remplacées " "par un remplissage solide interne." -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer le remplissage plein interne.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer la surface supérieure.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament pour imprimer la surface inférieure.\n" -"\"Défaut\" utilise le filament actif de l’objet ou de la pièce." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29460,15 +29965,6 @@ msgstr "" "ignorée et le support est imprimé en contact direct avec l'objet (sans " "écart)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament pour imprimer la base des supports et le radeau.\n" -"\"Défaut\" signifie qu’aucun filament spécifique n’est dédié aux supports : " -"le filament actuel est utilisé." - msgid "Loop pattern interface" msgstr "Modèle de boucle d'utilisation d'interface" @@ -29479,15 +29975,6 @@ msgstr "" "Recouvrir la couche de contact supérieure des supports avec des boucles. " "Désactivé par défaut." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament pour imprimer l’interface des supports.\n" -"\"Défaut\" signifie qu’aucun filament spécifique n’est dédié à l’interface " -"des supports : le filament actuel est utilisé." - msgid "This is the number of top interface layers." msgstr "Nombre de couches d’interface supérieures." diff --git a/localization/i18n/hu/Snapmaker_Orca_hu.po b/localization/i18n/hu/Snapmaker_Orca_hu.po index 7b04fcedd7c..3666400f809 100644 --- a/localization/i18n/hu/Snapmaker_Orca_hu.po +++ b/localization/i18n/hu/Snapmaker_Orca_hu.po @@ -18426,6 +18426,540 @@ msgstr "" "Tudtad, hogy a vetemedésre hajlamos anyagok (például ABS) nyomtatásakor a " "tárgyasztal hőmérsékletének növelése csökkentheti a vetemedés valószínűségét?" +msgid "Adjust wall layer height" +msgstr "Fal rétegmagasság igazítása" + +msgid "Adjusted walls" +msgstr "Igazított falak" + +msgid "Adjustment direction" +msgstr "Igazítás iránya" + +msgid "Consistent" +msgstr "Egyenletes" + +msgid "Decrease" +msgstr "Csökkentés" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament az alsó felület nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament a belső falak nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament a belső tömör kitöltés nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament a belső ritkás kitöltés nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament a külső falak nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"A támasz alapjához és a tutaj nyomtatásához használt filament. Az " +"\"Alapértelmezett\" beállítás választásakor a jelenleg használt filament " +"kerül felhasználásra." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament a támasz érintkező felületének nyomtatásához. Az " +"\"Alapértelmezett\" beállítás választásakor a jelenleg használt filament " +"kerül felhasználásra." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament a felső felület nyomtatásához.\n" +"Az \"Alapértelmezett\" a tárgy/alkatrész aktív filamentjét használja." + +msgid "Fixed" +msgstr "Rögzített" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Mennyire agresszíven vonjuk össze vastag rétegekbe azokat az alkatrészeket, " +"amelyek vastagabb preferált rétegmagasságú extruderhez vannak rendelve.\n" +"Egyenletes: az alkatrészek legfeljebb két rétegmagassággal nyomtatódnak - az " +"extruder rétegmagasságával ott, ahová teljes rétegsorozatok beférnek, és a " +"tárgy rétegmagasságával mindenhol máshol. Ez adja a legegyenletesebb " +"falakat.\n" +"Adaptív: a sorozatok a tárgy rétegmagasságának köztes többszörösein is " +"összevonhatók, így az alkatrész nagyobb része nyomtatódik vastagabb " +"rétegekkel - cserébe az íves alkatrészhatárokon váltakozó rétegmagasságú " +"sávok jelennek meg.\n" +"Rögzített: az alkatrészek mindig az extruder rétegmagasságával nyomtatódnak, " +"ott is, ahol az alak az összevont rétegeken át változik vagy túlnyúlik; az " +"íves határok lépcsőkké válnak, és a vastag rétegeknél finomabb részletek " +"elvesznek. Csak az egy teljes vastag réteghez túl rövid geometria (az " +"alkatrészek teteje és az első réteg) nyomtatódik vékonyabban." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Mennyit sodródhat oldalra egy vastagabb preferált rétegmagasságú extruderhez " +"rendelt alkatrész körvonala egy vastag sorozat rétegein át úgy, hogy még " +"összevonható maradjon, az extruder fúvókaátmérőjének százalékában. Nagyobb " +"értékek több íves alkatrészhatárt vonnak össze vastag rétegekbe, cserébe " +"durvább határfalakkal: a fúvókaátmérő ekkora hányadáig terjedő eltéréseket " +"elnyelik a vastag szálak." + +msgid "Increase" +msgstr "Növelés" + +msgid "Inner walls" +msgstr "Belső falak" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"A rétegmagasság, amellyel ennek az extrudernek nyomtatnia kell; olyan " +"nyomtatókhoz, amelyek extruderei különböző fúvókaméretűek. A tárgy " +"rétegmagasságának egész számú többszörösének kell lennie. Az az alkatrész, " +"amelynek minden eleme ezt az extrudert követi, csak minden N-edik rétegen " +"nyomtat ennek megfelelően vastagabb szálakkal, ahol a geometriája engedi; " +"máshol visszaáll a tárgy rétegmagasságára. Ha az alkatrész többi része nem " +"tud követni, az ehhez az extruderhez rendelt falak akkor is önállóan " +"összevonódnak erre a magasságra, a teljes sűrűségű felső felületek elnyelik " +"az alattuk lévő tömör rétegeket, és a ritkás vagy 100% sűrűségű kitöltés " +"függetlenül összevonódik erre a magasságra. A 0 a tárgy rétegmagasságának " +"használatát jelenti." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"A rétegmagasság, amellyel ennek az extrudernek nyomtatnia kell: a tárgy " +"rétegmagasságának egész számú többszöröse az extruder rétegmagasság-" +"korlátain belül. Az Alapértelmezett megtartja a tárgy rétegmagasságát." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Egyik extruder fúvókája sem egyezik a támasz fúvókaátmérőjével." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Egyik betöltött filament sem felel meg a támasz/tutaj alap anyagának (és a " +"támasz fúvókaátmérőjének)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Egyik betöltött filament sem felel meg a támasz/tutaj érintkezőréteg " +"anyagának (és a támasz fúvókaátmérőjének)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"%1%. fúvóka: a rétegmagasság-korlátok %2%-%3% mm-re állítva a(z) \"%4%\" " +"alapján." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Az olyan nyomtatókon, amelyek extruderei különböző fúvókaátmérőjűek, csak az " +"ilyen fúvókaátmérőjű filamentek nyomtatják a támaszt, a tutajt és a támasz-" +"érintkezőréteget. Ez távol tartja a más fúvókaméretű filamenteket - eltérő " +"vonalszélességükkel és rétegmagasság-korlátaikkal - a támasztól. A nem " +"alapértelmezettre állított támaszfilamenteknek egyezniük kell ezzel az " +"átmérővel. A 0 érték bármely filamentnek engedi a támasz nyomtatását." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"A külső és belső falak automatikusan a saját preferált rétegmagasságukkal " +"nyomtatódnak, ha az egyik magasság a másik egész számú többszöröse. Ha a " +"magasságok nem oszthatók maradék nélkül, ez a beállítás a két falfilament " +"egyikének (lent kiválasztott) fal-rétegmagasságát a másik legközelebbi " +"többszörösére vagy osztójára igazítja, hogy a falak továbbra is " +"szétválhassanak. Az igazított magasság csak annak a filamentnek a falaira " +"vonatkozik; a többi elem megtartja a preferált rétegmagasságot. Az igazítás " +"sosem lépi át a filament rétegmagasság-korlátait: ha a választott irányban " +"nincs megengedett magasság, a falak a szokásos módon együtt, az alacsonyabb " +"magassággal nyomtatódnak." + +msgid "Outer walls" +msgstr "Külső falak" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Az extruderenkénti rétegmagasság nem támogatott spirál (váza) módban." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Az extruderenkénti rétegmagasság nem támogatott érintkező héjakkal együtt." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Az extruderenkénti rétegmagasság nem támogatott változó rétegmagassággal " +"együtt." + +msgid "Preferred layer height" +msgstr "Preferált rétegmagasság" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"A támasz és a tutaj alapja csak ilyen anyagtípusú filamentekkel nyomtatódik; " +"a más típussal töltött extruderek ehhez nem lesznek használva. A támasz " +"fúvókaátmérő-korlátozásával együtt érvényesül. Hagyja üresen, ha nem akar " +"korlátozni; a kifejezetten kiválasztott támasz/tutaj alap filament továbbra " +"is elsőbbséget élvez." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"A támasz és a tutaj érintkezőrétege csak ilyen anyagtípusú filamentekkel " +"nyomtatódik; a más típussal töltött extruderek ehhez nem lesznek használva. " +"A támasz fúvókaátmérő-korlátozásával együtt érvényesül. Hagyja üresen, ha " +"nem akar korlátozni; a kifejezetten kiválasztott érintkezőréteg-filament " +"továbbra is elsőbbséget élvez." + +msgid "Raft and support base" +msgstr "Tutaj és támasz alap" + +msgid "Show legacy filament selection" +msgstr "Régi filament-kiválasztás megjelenítése" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Néhány alkatrész %1% mm-es rétegeket preferál, de az alkatrész más elemeit " +"nyomtató %2%. filament fúvókája túl kicsi ekkora magasság extrudálásához. " +"Ezek az alkatrészek helyette a tárgy rétegmagasságával nyomtatódnak." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Néhány alkatrész %1% mm-es rétegeket preferál, de a %2%. falfilament " +"fúvókája túl kicsi ekkora magasság extrudálásához. A külső és belső falak " +"együtt nyomtatódnak, így ezek a falak a tárgy rétegmagasságát tartják. " +"Rendelje mindkét falelemet elég nagy fúvókájú filamentekhez." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Néhány alkatrész %1% mm-es rétegeket nyomtat a %2%. filamenttel, amelynek " +"maximális rétegmagassága %3% mm. Rendelje az alkatrész elemeit a durvább " +"fúvóka filamentjeihez, növelje a filament maximális rétegmagasságát, vagy " +"fogadja el a fölötte nyomtatást." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Néhány alkatrész %1% mm-es rétegeket nyomtat a %2%. filamenttel, amelynek " +"minimális rétegmagassága %3% mm. Növelje a tárgy rétegmagasságát, használjon " +"finomabb fúvókájú filamentet ezekhez az elemekhez, vagy fogadja el az " +"extruder minimuma alatti nyomtatást." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Néhány alkatrész olyan filamenteket használ, amelyek preferált " +"rétegmagasságai nem teljesíthetők mind: egy alkatrész az elemeit egyetlen " +"réteglépéssel nyomtatja (ezt a falfilamentjei határozzák meg, vagy ha egyik " +"falfilamentnek sincs preferenciája, a többi elem megegyezése); a falak, a " +"felső felületek és a kitöltés külön-külön összevonódhatnak a saját " +"magasságukra, ha az alkatrész többi része nem tudja követni őket, de a " +"maradék elemek az alkatrész lépésével nyomtatódnak." + +msgid "Support for mixed nozzle sizes" +msgstr "Támasz vegyes fúvókaméretekhez" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"A támasz különböző fúvókaátmérőjű extruderekkel nyomtatódhat. Állítsa be a " +"támasz fúvókaátmérőjét (vagy kifejezett támasz- és érintkezőréteg-" +"filamenteket), hogy a támasz egy fúvókaméreten maradjon." + +msgid "Support nozzle diameter" +msgstr "Támasz fúvókaátmérő" + +msgid "Support nozzle size" +msgstr "Támasz fúvókaméret" + +msgid "Support/raft base material" +msgstr "Támasz/tutaj alap anyaga" + +msgid "Support/raft interface material" +msgstr "Támasz/tutaj érintkezőréteg anyaga" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"A %1% mm-es kitöltési vonalszélesség túl kicsi a %2% mm magas rétegekbe " +"összevont kitöltéshez. Növelje a vonalszélességet, vagy csökkentse a " +"kitöltőfilament preferált rétegmagasságát." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"A %1% mm-es vonalszélesség túl kicsi az extruder %2% mm-es " +"rétegmagasságához. Növelje a vonalszélességet, vagy csökkentse az extruder " +"rétegmagasságát." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"A(z) %1%. extruder rétegmagassága (%2% mm) nem haladhatja meg a " +"fúvókaátmérőjét." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"A(z) %1%. extruder rétegmagassága (%2% mm) néhány alkatrésznél figyelmen " +"kívül marad: a tárgy rétegmagasságának (%3% mm) egész számú többszörösének " +"kell lennie, nem lehet alatta, és nem haladhatja meg az extruder " +"fúvókaátmérőjét." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"A(z) %1%. extruder rétegmagassága (%2% mm) kisebb a tárgy rétegmagasságánál " +"(%3% mm). Csökkentse a tárgy rétegmagasságát a legfinomabb extruder-" +"rétegmagasságra." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"A(z) %1%. extruder rétegmagasságának (%2% mm) a tárgy rétegmagasságának (%3% " +"mm) egész számú többszörösének kell lennie." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Az extruder legkisebb nyomtatható rétegmagassága. Az adaptív rétegmagasság " +"bekapcsolásakor a minimális rétegmagasság korlátozására szolgál. A vastagabb " +"preferált extruder-rétegmagassággal nyomtatott alkatrészek sem esnek soha ez " +"alá a magasság alá (az első réteg kivételével)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"A(z) %1%. fúvóka preferált rétegmagassága már nem fér át rajta, ezért " +"Alapértelmezettre lett visszaállítva." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "A támasz/tutaj alap filamentje nem a támasz/tutaj alap anyagából való." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"A támasz/tutaj alap filamentje olyan fúvókával nyomtat, amely nem egyezik a " +"támasz fúvókaátmérőjével." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"A támasz/tutaj érintkezőréteg filamentje nem a támasz/tutaj érintkezőréteg " +"anyagából való." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"A támasz/tutaj érintkezőréteg filamentje olyan fúvókával nyomtat, amely nem " +"egyezik a támasz fúvókaátmérőjével." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Néhány alkatrész falfilamentjei eltérő rétegmagasságokat preferálnak. A " +"külső és belső falak együtt nyomtatódnak, így ezek a falak a tárgy " +"rétegmagasságát tartják. Vastagabb falak nyomtatásához rendelje mindkét " +"falelemet azonos magasságot preferáló filamentekhez." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Néhány alkatrész falfilamentjei eltérő rétegmagasságokat preferálnak. A " +"külső és belső falak együtt nyomtatódnak, így ezek a falak az alacsonyabb " +"magassággal (%1% mm) nyomtatódnak." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"A(z) %1%. filament fal-rétegmagassága a preferált %2% mm-ről %3% mm-re lett " +"igazítva, hogy a külső és belső falak összeférő rétegmagasságokkal " +"nyomtatódhassanak (\"Fal rétegmagasság igazítása\"). Az igazított " +"magassággal csak ennek a filamentnek a falai nyomtatódnak; a többi eleme " +"megtartja a preferáltat." + +msgid "Thick layer regions" +msgstr "Vastag rétegű területek" + +msgid "Thick layer tolerance" +msgstr "Vastag réteg tűrése" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Ennek a nyomtatónak nincs profilja %1% mm-es fúvókához. Ellenőrizze a(z) " +"%2%. fúvóka rétegmagasság-korlátait a nyomtató beállításaiban." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Ez a nyomtató különböző fúvókaméreteket használ. Válassza ki a támaszt " +"nyomtató fúvókaméretet, valamint a tutajhoz és a támasz-érintkezőréteghez " +"használt filamenttípusokat." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Az igazított falfilament fal-rétegmagassága csökkenjen vagy nőjön-e, hogy a " +"másik falfilamenttel összeférő magasságot érjen el. Az igazított filament " +"rétegmagasság-korlátain kívüli magasságok sosem lesznek használva: ha ebben " +"az irányban nincs megengedett magasság, a falak a szokásos módon együtt, az " +"alacsonyabb magassággal nyomtatódnak." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"A két falfilament közül melyiknek legyen igazítva a fal-rétegmagassága, ha a " +"preferált rétegmagasságok nem oszthatók maradék nélkül." + # AI Translated msgid "Main Extruder" msgstr "Fő extruder" @@ -27638,14 +28172,6 @@ msgstr "" "Ha 0-ra állítod, a régi kitöltéskapcsolási algoritmus lesz használva, amely " "ugyanazt az eredményt adja, mint az 1000 és 0 értékek kombinációja." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"A belső kitöltés nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - msgid "Infill/wall overlap" msgstr "Kitöltés/fal átfedés" @@ -27985,30 +28511,6 @@ msgstr "" "más sebességet használ. A 100%%-os túlnyúlás esetén az áthidaláshoz " "beállított sebességet használja." -# AI Translated -msgid "Outer walls" -msgstr "Külső falak" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"A külső falak nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - -# AI Translated -msgid "Inner walls" -msgstr "Belső falak" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"A belső falak nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - msgid "This is the speed for inner walls." msgstr "A belső fal nyomtatási sebessége" @@ -28192,30 +28694,6 @@ msgstr "" "Az ennél a küszöbértéknél kisebb kitöltési területeket belső tömör " "kitöltéssel helyettesíti." -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"A belső tömör kitöltés nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"A felső felület nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Az alsó felület nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" az aktív objektum/tárgy filamentjét használja." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28378,16 +28856,6 @@ msgstr "" "alul érintkezőrétegek vannak, a szeletelő figyelmen kívül hagyja ezt az " "értéket, és a támaszt közvetlenül a tárgyra nyomtatja (rés nélkül)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"A támasz alapjához és a tutaj nyomtatásához használt filament.\n" -"Az \"Alapértelmezett\" beállítás választásakor a jelenleg használt filament " -"kerül felhasználásra." - msgid "Loop pattern interface" msgstr "Hurokminta felület" @@ -28398,16 +28866,6 @@ msgstr "" "Lefedi a támasz felső érintkező rétegét körökkel. Alapértelmezés szerint " "letiltva." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament a támasz érintkező felületének nyomtatásához.\n" -"Az \"Alapértelmezett\" beállítás választásakor a jelenleg használt filament " -"kerül felhasználásra." - # AI Translated msgid "This is the number of top interface layers." msgstr "A felső érintkező rétegek száma." diff --git a/localization/i18n/it/Snapmaker_Orca_it.po b/localization/i18n/it/Snapmaker_Orca_it.po index 6352a9b0244..569785df146 100644 --- a/localization/i18n/it/Snapmaker_Orca_it.po +++ b/localization/i18n/it/Snapmaker_Orca_it.po @@ -19409,6 +19409,547 @@ msgstr "" "aumentare in modo appropriato la temperatura del piano riscaldato può " "ridurre la probabilità di deformazione?" +msgid "Adjust wall layer height" +msgstr "Regola l'altezza strato delle pareti" + +msgid "Adjusted walls" +msgstr "Pareti regolate" + +msgid "Adjustment direction" +msgstr "Direzione della regolazione" + +msgid "Consistent" +msgstr "Coerente" + +msgid "Decrease" +msgstr "Diminuisci" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare la superficie inferiore.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare le pareti interne.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare il riempimento solido interno.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare il riempimento sparso interno.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare le pareti esterne.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filamento per stampare basi di supporto e zattere. \"Predefinito\" indica " +"che non verrà utilizzato alcun filamento specifico per il supporto e che " +"sarà utilizzato il filamento corrente." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filamento per la stampa delle interfacce di supporto. \"Predefinito\" indica " +"che non verrà utilizzato alcun filamento specifico per l'interfaccia di " +"supporto e che sarà utilizzato il filamento corrente." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento per stampare la superficie superiore.\n" +"\"Predefinito\" usa il filamento attivo dell'oggetto/parte." + +msgid "Fixed" +msgstr "Fissa" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Quanto aggressivamente le parti assegnate a un estrusore con un'altezza " +"strato preferita più spessa vengono combinate in strati spessi.\n" +"Coerente: le parti stampano con al massimo due altezze strato - l'altezza " +"strato dell'estrusore dove entrano serie intere di strati e l'altezza strato " +"dell'oggetto ovunque altrove. Questo dà le pareti più uniformi.\n" +"Adattiva: le serie possono anche essere combinate a multipli intermedi " +"dell'altezza strato dell'oggetto, così una parte maggiore del pezzo stampa " +"con strati più spessi, al prezzo di fasce di altezze strato variabili sui " +"bordi curvi.\n" +"Fissa: le parti stampano sempre all'altezza strato dell'estrusore, anche " +"dove la forma cambia attraverso gli strati combinati o sporge; i bordi curvi " +"diventano gradini e i dettagli più fini degli strati spessi vanno persi. " +"Solo la geometria troppo corta per un intero strato spesso (le sommità delle " +"parti e il primo strato) stampa più sottile." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Di quanto il profilo di una parte assegnata a un estrusore con un'altezza " +"strato preferita più spessa può spostarsi lateralmente attraverso gli strati " +"di una serie spessa restando comunque combinabile, come percentuale del " +"diametro ugello di quell'estrusore. Valori più alti combinano più bordi " +"curvi in strati spessi, al prezzo di pareti di bordo più ruvide: le " +"deviazioni fino a questa frazione del diametro dell'ugello vengono assorbite " +"dalle estrusioni spesse." + +msgid "Increase" +msgstr "Aumenta" + +msgid "Inner walls" +msgstr "Pareti interne" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Altezza strato con cui questo estrusore dovrebbe stampare, per stampanti i " +"cui estrusori hanno ugelli di dimensioni diverse. Deve essere un multiplo " +"intero dell'altezza strato dell'oggetto. Una parte le cui caratteristiche " +"seguono tutte questo estrusore stampa solo ogni N strati con estrusioni " +"corrispondentemente più spesse, dove la sua geometria lo consente; altrove " +"torna all'altezza strato dell'oggetto. Quando il resto della parte non può " +"seguirla, le pareti assegnate a questo estrusore si combinano comunque da " +"sole a questa altezza, le superfici superiori a piena densità assorbono gli " +"strati solidi sottostanti, e il riempimento sparso o denso al 100% si " +"combina indipendentemente a questa altezza. 0 significa usare l'altezza " +"strato dell'oggetto." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Altezza strato con cui questo estrusore dovrebbe stampare: un multiplo " +"intero dell'altezza strato dell'oggetto entro i limiti di altezza strato di " +"questo estrusore. Predefinito mantiene l'altezza strato dell'oggetto." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Nessun estrusore ha un ugello corrispondente al diametro ugello dei supporti." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Nessun filamento caricato corrisponde al materiale della base supporti/" +"zattera (e al diametro ugello dei supporti)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Nessun filamento caricato corrisponde al materiale dell'interfaccia supporti/" +"zattera (e al diametro ugello dei supporti)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Ugello %1%: limiti altezza strato impostati a %2%-%3% mm, da \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Sulle stampanti i cui estrusori hanno diametri ugello diversi, solo i " +"filamenti di questo diametro ugello vengono usati per stampare supporti, " +"zattera e interfaccia dei supporti. Questo tiene i filamenti di altre " +"dimensioni ugello - con le loro diverse larghezze linea e limiti di altezza " +"strato - fuori dai supporti. I filamenti di supporto impostati su un valore " +"non predefinito devono corrispondere a questo diametro. Il valore 0 consente " +"a qualsiasi filamento di stampare i supporti." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Le pareti esterne e interne stampano automaticamente alle proprie altezze " +"strato preferite quando un'altezza è un multiplo intero dell'altra. Quando " +"le altezze non si dividono esattamente, questa opzione regola l'altezza " +"strato delle pareti di uno dei due filamenti parete (scelto sotto) al " +"multiplo o divisore più vicino dell'altra, così le pareti possono ancora " +"separarsi. L'altezza regolata si applica solo alle pareti di quel filamento; " +"le altre caratteristiche mantengono l'altezza strato preferita. Le " +"regolazioni non escono mai dai limiti di altezza strato del filamento: se " +"nella direzione scelta non esiste un'altezza consentita, le pareti stampano " +"insieme all'altezza inferiore come al solito." + +msgid "Outer walls" +msgstr "Pareti esterne" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Le altezze strato per estrusore non sono supportate in modalità vaso a " +"spirale." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Le altezze strato per estrusore non sono supportate insieme ai gusci di " +"interfaccia." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Le altezze strato per estrusore non sono supportate insieme all'altezza " +"strato variabile." + +msgid "Preferred layer height" +msgstr "Altezza strato preferita" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Stampa la base dei supporti e la zattera solo con filamenti di questo tipo " +"di materiale; gli estrusori caricati con altri tipi non vengono usati per " +"essa. Si combina con la restrizione del diametro ugello dei supporti. " +"Lasciare vuoto per nessuna restrizione; un filamento base supporti/zattera " +"selezionato esplicitamente ha comunque la precedenza." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Stampa l'interfaccia dei supporti e della zattera solo con filamenti di " +"questo tipo di materiale; gli estrusori caricati con altri tipi non vengono " +"usati per essa. Si combina con la restrizione del diametro ugello dei " +"supporti. Lasciare vuoto per nessuna restrizione; un filamento interfaccia " +"supporti/zattera selezionato esplicitamente ha comunque la precedenza." + +msgid "Raft and support base" +msgstr "Zattera e base dei supporti" + +msgid "Show legacy filament selection" +msgstr "Mostra la selezione filamento precedente" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Alcune parti preferiscono strati di %1% mm, ma l'ugello del filamento %2% " +"che stampa altre caratteristiche della parte è troppo piccolo per estrudere " +"quell'altezza. Queste parti stampano invece con l'altezza strato " +"dell'oggetto." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Alcune parti preferiscono strati di %1% mm, ma l'ugello del filamento parete " +"%2% è troppo piccolo per estrudere quell'altezza. Le pareti esterne e " +"interne stampano insieme, quindi queste pareti mantengono l'altezza strato " +"dell'oggetto. Assegnare entrambe le caratteristiche parete a filamenti con " +"ugelli abbastanza grandi." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Alcune parti stampano strati di %1% mm con il filamento %2%, la cui altezza " +"strato massima è %3% mm. Assegnare le caratteristiche della parte ai " +"filamenti dell'ugello più grosso, aumentare l'altezza strato massima del " +"filamento, oppure accettare di stampare oltre." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Alcune parti stampano strati di %1% mm con il filamento %2%, la cui altezza " +"strato minima è %3% mm. Aumentare l'altezza strato dell'oggetto, usare un " +"filamento con un ugello più fine per queste caratteristiche, oppure " +"accettare di stampare sotto il minimo dell'estrusore." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Alcune parti usano filamenti le cui altezze strato preferite non possono " +"essere tutte rispettate: una parte stampa le sue caratteristiche con un solo " +"passo di strato (fissato dai suoi filamenti parete o, quando nessun " +"filamento parete ha una preferenza, dall'accordo delle altre " +"caratteristiche); le pareti, le superfici superiori e il riempimento possono " +"combinarsi ciascuno alla propria altezza quando il resto della parte non può " +"seguirli, ma le caratteristiche rimanenti stampano con il passo della parte." + +msgid "Support for mixed nozzle sizes" +msgstr "Supporti con dimensioni ugello miste" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"I supporti potrebbero stampare con estrusori di diametri ugello diversi. " +"Impostare il diametro ugello dei supporti (o filamenti espliciti di supporto " +"e interfaccia) per mantenere i supporti su una sola dimensione ugello." + +msgid "Support nozzle diameter" +msgstr "Diametro ugello dei supporti" + +msgid "Support nozzle size" +msgstr "Dimensione ugello dei supporti" + +msgid "Support/raft base material" +msgstr "Materiale base supporti/zattera" + +msgid "Support/raft interface material" +msgstr "Materiale interfaccia supporti/zattera" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"La larghezza linea del riempimento di %1% mm è troppo piccola per " +"riempimento combinato in strati alti %2% mm. Aumentare la larghezza linea o " +"abbassare l'altezza strato preferita del filamento di riempimento." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"La larghezza linea di %1% mm è troppo piccola per l'altezza strato di %2% mm " +"del suo estrusore. Aumentare la larghezza linea o abbassare l'altezza strato " +"dell'estrusore." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"L'altezza strato dell'estrusore %1% (%2% mm) non può superare il suo " +"diametro ugello." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"L'altezza strato dell'estrusore %1% (%2% mm) viene ignorata per alcune " +"parti: deve essere un multiplo intero dell'altezza strato dell'oggetto (%3% " +"mm), non inferiore, e non deve superare il diametro ugello dell'estrusore." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"L'altezza strato dell'estrusore %1% (%2% mm) è più piccola dell'altezza " +"strato dell'oggetto (%3% mm). Abbassare l'altezza strato dell'oggetto " +"all'altezza strato di estrusore più fine." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"L'altezza strato dell'estrusore %1% (%2% mm) deve essere un multiplo intero " +"dell'altezza strato dell'oggetto (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"L'altezza strato stampabile più bassa dell'estrusore. Serve a limitare " +"l'altezza strato minima quando l'altezza strato adattiva è attiva. Anche le " +"parti stampate con un'altezza strato di estrusore preferita più spessa non " +"scendono mai sotto questa altezza (eccetto il primo strato)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"L'altezza strato preferita dell'ugello %1% non passa più attraverso di esso " +"ed è stata ripristinata a Predefinito." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Il filamento della base supporti/zattera non è del materiale della base " +"supporti/zattera." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Il filamento della base supporti/zattera stampa con un ugello che non " +"corrisponde al diametro ugello dei supporti." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Il filamento dell'interfaccia supporti/zattera non è del materiale " +"dell'interfaccia supporti/zattera." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Il filamento dell'interfaccia supporti/zattera stampa con un ugello che non " +"corrisponde al diametro ugello dei supporti." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"I filamenti parete di alcune parti preferiscono altezze strato diverse. Le " +"pareti esterne e interne stampano insieme, quindi queste pareti mantengono " +"l'altezza strato dell'oggetto. Assegnare entrambe le caratteristiche parete " +"a filamenti che preferiscono la stessa altezza per stampare pareti più " +"spesse." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"I filamenti parete di alcune parti preferiscono altezze strato diverse. Le " +"pareti esterne e interne stampano insieme, quindi queste pareti stampano con " +"l'altezza inferiore (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"L'altezza strato delle pareti del filamento %1% è stata regolata dai %2% mm " +"preferiti a %3% mm perché le pareti esterne e interne possano stampare ad " +"altezze strato compatibili (\"Regola l'altezza strato delle pareti\"). Solo " +"le pareti di questo filamento stampano l'altezza regolata; le sue altre " +"caratteristiche mantengono quella preferita." + +msgid "Thick layer regions" +msgstr "Regioni a strati spessi" + +msgid "Thick layer tolerance" +msgstr "Tolleranza strati spessi" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Questa stampante non ha un profilo per un ugello da %1% mm. Verificare i " +"limiti di altezza strato dell'ugello %2% nelle impostazioni della stampante." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Questa stampante usa dimensioni ugello diverse. Selezionare la dimensione " +"ugello che stampa i supporti e i tipi di filamento usati per la zattera e " +"l'interfaccia dei supporti." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Se l'altezza strato delle pareti del filamento regolato viene diminuita o " +"aumentata per raggiungere un'altezza compatibile con l'altro filamento " +"parete. Le altezze fuori dai limiti di altezza strato del filamento regolato " +"non vengono mai usate: se in questa direzione non esiste un'altezza " +"consentita, le pareti stampano insieme all'altezza inferiore come al solito." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Quale dei due filamenti parete riceve la regolazione dell'altezza strato " +"delle pareti quando le altezze strato preferite non si dividono esattamente." + # AI Translated msgid "Main Extruder" msgstr "Estrusore principale" @@ -28791,14 +29332,6 @@ msgstr "" "Se impostato a 0, verrà utilizzato il vecchio algoritmo per la connessione " "del riempimento, che dovrebbe creare lo stesso risultato di 1000 e 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare il riempimento sparso interno.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - msgid "Infill/wall overlap" msgstr "Sovrapposizione riempimento/parete" @@ -29159,30 +29692,6 @@ msgstr "" "utilizza un velocità di stampa differente. Per una sporgenza del 100%%, " "viene utilizzata la velocità dei ponti." -# AI Translated -msgid "Outer walls" -msgstr "Pareti esterne" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare le pareti esterne.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - -# AI Translated -msgid "Inner walls" -msgstr "Pareti interne" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare le pareti interne.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - msgid "This is the speed for inner walls." msgstr "Velocità per pareti interne." @@ -29376,30 +29885,6 @@ msgstr "" "Le aree di riempimento sparso di dimensioni inferiori a questa soglia " "vengono sostituite con il riempimento solido interno." -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare il riempimento solido interno.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare la superficie superiore.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento per stampare la superficie inferiore.\n" -"\"Predefinito\" utilizza il filamento dell'oggetto/parte attivo." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29569,16 +30054,6 @@ msgstr "" "ignorato e il supporto viene stampato a contatto diretto con l'oggetto " "(senza spazio)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filamento per stampare basi di supporto e zattere.\n" -"\"Predefinito\" indica che non verrà utilizzato alcun filamento specifico " -"per il supporto e che sarà utilizzato il filamento corrente." - msgid "Loop pattern interface" msgstr "Usa motivo ad anello per interfaccie" @@ -29589,16 +30064,6 @@ msgstr "" "Copre con anelli lo strato di contatto superiore dei supporti. Disabilitato " "per impostazione predefinita." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filamento per la stampa delle interfacce di supporto.\n" -"\"Predefinito\" indica che non verrà utilizzato alcun filamento specifico " -"per l'interfaccia di supporto e che sarà utilizzato il filamento corrente." - # AI Translated msgid "This is the number of top interface layers." msgstr "Numero di strati di interfaccia superiori." diff --git a/localization/i18n/ja/Snapmaker_Orca_ja.po b/localization/i18n/ja/Snapmaker_Orca_ja.po index 998fac01d7d..f614ef0b204 100644 --- a/localization/i18n/ja/Snapmaker_Orca_ja.po +++ b/localization/i18n/ja/Snapmaker_Orca_ja.po @@ -18300,6 +18300,514 @@ msgstr "" "ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げること" "で、反りが発生する確率を下げることができることをご存知ですか?" +msgid "Adjust wall layer height" +msgstr "ウォールの積層ピッチを調整" + +msgid "Adjusted walls" +msgstr "調整されるウォール" + +msgid "Adjustment direction" +msgstr "調整方向" + +msgid "Consistent" +msgstr "一貫" + +msgid "Decrease" +msgstr "下げる" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"底面を印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"内壁を印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"内部ソリッドインフィルを印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"内部スパースインフィルを印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"外壁を印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"サポートとラフトを造形用のフィラメント。「デフォルト」では当時のフィラメント" +"を使用する意味です。" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"サポートの接触面用のフィラメントです。「デフォルト」では指定しなく、当時の" +"フィラメントを使用する意味です。" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"トップ面を印刷するフィラメント。\n" +"\"デフォルト\"はオブジェクト/パーツの現在のフィラメントを使用します。" + +msgid "Fixed" +msgstr "固定" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"太い優先積層ピッチのエクストルーダーに割り当てられたパーツを、どの程度積極的" +"に厚い層へ結合するかを決めます。\n" +"一貫: パーツは最大2種類の積層ピッチで印刷されます。完全な層のまとまりが収まる" +"場所ではエクストルーダーの積層ピッチ、それ以外ではオブジェクトの積層ピッチで" +"す。壁面が最も均一になります。\n" +"アダプティブ: まとまりをオブジェクト積層ピッチの中間の倍数でも結合できるた" +"め、パーツのより多くの部分が厚い層で印刷されますが、曲面の境界に積層ピッチが" +"変化する帯が現れます。\n" +"固定: 結合された層の間で形状が変化したりオーバーハングしていても、パーツは常" +"にエクストルーダーの積層ピッチで印刷されます。曲面の境界は段差になり、厚い層" +"より細かいディテールは失われます。厚い層1つ分に満たない形状(パーツの頂部と最" +"初の層)のみ薄く印刷されます。" + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"太い優先積層ピッチのエクストルーダーに割り当てられたパーツの輪郭が、1つの厚い" +"まとまりの層間で横方向にどこまでずれても結合されるかを、そのエクストルーダー" +"のノズル直径に対する割合で指定します。値を大きくすると曲面の境界がより多く厚" +"い層に結合されますが、境界の壁面は粗くなります。ノズル直径のこの割合までのず" +"れは太い押出に吸収されます。" + +msgid "Increase" +msgstr "上げる" + +msgid "Inner walls" +msgstr "内壁" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"このエクストルーダーが印刷すべき積層ピッチ。ノズルサイズが異なるエクストルー" +"ダーを持つプリンター用です。オブジェクトの積層ピッチの整数倍である必要があり" +"ます。すべての形状がこのエクストルーダーに従うパーツは、ジオメトリが許す場所" +"ではN層ごとにその分厚い押出で印刷され、それ以外ではオブジェクトの積層ピッチに" +"戻ります。パーツの残りが従えない場合でも、このエクストルーダーに割り当てられ" +"たウォールは単独でこの高さに結合され、全密度のトップ面は直下のソリッド層を吸" +"収し、スパースまたは100%密度のインフィルも独立してこの高さに結合されます。0は" +"オブジェクトの積層ピッチを使用します。" + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"このエクストルーダーが印刷すべき積層ピッチ: このエクストルーダーの積層ピッチ" +"制限内で、オブジェクトの積層ピッチの整数倍。デフォルトはオブジェクトの積層" +"ピッチを維持します。" + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "サポートノズル直径に一致するノズルを持つエクストルーダーがありません。" + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"サポート/ラフトベースの材料(およびサポートノズル直径)に一致するフィラメント" +"がロードされていません。" + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"サポート/ラフトインターフェイスの材料(およびサポートノズル直径)に一致する" +"フィラメントがロードされていません。" + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "ノズル%1%: 積層ピッチの制限を%2%-%3% mmに設定しました(\"%4%\"より)。" + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"エクストルーダーのノズル直径が異なるプリンターでは、このノズル直径のフィラメ" +"ントのみがサポート、ラフト、サポートインターフェイスの印刷に使用されます。こ" +"れにより、線幅や積層ピッチ制限が異なる他のノズルサイズのフィラメントがサポー" +"トに使われなくなります。デフォルト以外に設定されたサポートフィラメントは、こ" +"の直径に一致する必要があります。0はどのフィラメントでもサポートを印刷できま" +"す。" + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"一方の高さが他方の整数倍のとき、外壁と内壁は自動的にそれぞれの優先積層ピッチ" +"で印刷されます。高さが割り切れない場合、このオプションは2つのウォールフィラメ" +"ントの一方(下で選択)のウォール積層ピッチを他方の最も近い倍数または約数に調" +"整し、ウォールを分割できるようにします。調整された高さはそのフィラメントの" +"ウォールにのみ適用され、他の形状は優先積層ピッチを維持します。調整がフィラメ" +"ントの積層ピッチ制限を超えることはありません。選んだ方向に許容される高さがな" +"い場合、ウォールは通常どおり低い方の高さで一緒に印刷されます。" + +msgid "Outer walls" +msgstr "外壁" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "エクストルーダーごとの積層ピッチはスパイラルモードでは使用できません。" + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"エクストルーダーごとの積層ピッチはインターフェイスシェルと併用できません。" + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "エクストルーダーごとの積層ピッチは可変積層ピッチと併用できません。" + +msgid "Preferred layer height" +msgstr "優先積層ピッチ" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"サポートとラフトベースをこの材料タイプのフィラメントのみで印刷します。他のタ" +"イプがロードされたエクストルーダーは使用されません。サポートノズル直径の制限" +"と併せて機能します。空欄で制限なし。明示的に選択されたサポート/ラフトベース" +"フィラメントが引き続き優先されます。" + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"サポートとラフトのインターフェイスをこの材料タイプのフィラメントのみで印刷し" +"ます。他のタイプがロードされたエクストルーダーは使用されません。サポートノズ" +"ル直径の制限と併せて機能します。空欄で制限なし。明示的に選択されたサポート/ラ" +"フトインターフェイスフィラメントが引き続き優先されます。" + +msgid "Raft and support base" +msgstr "ラフトとサポートベース" + +msgid "Show legacy filament selection" +msgstr "旧フィラメント選択を表示" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"一部のパーツは%1% mmの層を優先しますが、そのパーツの他の形状を印刷するフィラ" +"メント%2%のノズルが小さすぎてその高さを押し出せません。これらのパーツは代わり" +"にオブジェクトの積層ピッチで印刷されます。" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"一部のパーツは%1% mmの層を優先しますが、ウォールフィラメント%2%のノズルが小さ" +"すぎてその高さを押し出せません。外壁と内壁は一緒に印刷されるため、これらの" +"ウォールはオブジェクトの積層ピッチを維持します。両方のウォールを十分大きいノ" +"ズルのフィラメントに割り当ててください。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"一部のパーツはフィラメント%2%で%1% mmの層を印刷しますが、その最大積層ピッチ" +"は%3% mmです。パーツの形状を太いノズルのフィラメントに割り当てるか、フィラメ" +"ントの最大積層ピッチを上げるか、それを超えて印刷することを受け入れてくださ" +"い。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"一部のパーツはフィラメント%2%で%1% mmの層を印刷しますが、その最小積層ピッチ" +"は%3% mmです。オブジェクトの積層ピッチを上げるか、これらの形状に細いノズルの" +"フィラメントを使うか、エクストルーダーの最小値未満で印刷することを受け入れて" +"ください。" + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"一部のパーツで、フィラメントの優先積層ピッチをすべて満たすことができません。" +"パーツはその形状を1つの層ピッチで印刷します(ウォールフィラメントが決めるか、" +"ウォールフィラメントに優先がない場合は他の形状の合意で決まります)。パーツの" +"残りが従えないとき、ウォール、トップ面、インフィルはそれぞれ独自の高さに結合" +"できますが、残りの形状はパーツのピッチで印刷されます。" + +msgid "Support for mixed nozzle sizes" +msgstr "混合ノズルサイズのサポート" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"サポートが異なるノズル直径のエクストルーダーで印刷される可能性があります。サ" +"ポートノズル直径(または明示的なサポート/インターフェイスフィラメント)を設定" +"して、サポートを1つのノズルサイズに保ってください。" + +msgid "Support nozzle diameter" +msgstr "サポートノズル直径" + +msgid "Support nozzle size" +msgstr "サポートノズルサイズ" + +msgid "Support/raft base material" +msgstr "サポート/ラフトベース材料" + +msgid "Support/raft interface material" +msgstr "サポート/ラフトインターフェイス材料" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mmのインフィル線幅は、%2% mmの高さに結合されたインフィルには小さすぎま" +"す。線幅を増やすか、インフィルフィラメントの優先積層ピッチを下げてください。" + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"%1% mmの線幅は、そのエクストルーダーの%2% mmの積層ピッチには小さすぎます。線" +"幅を増やすか、エクストルーダーの積層ピッチを下げてください。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"エクストルーダー%1%の積層ピッチ(%2% mm)はノズル直径を超えられません。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"エクストルーダー%1%の積層ピッチ(%2% mm)は一部のパーツで無視されます。オブ" +"ジェクトの積層ピッチ(%3% mm)の整数倍かつそれ以上で、エクストルーダーのノズ" +"ル直径を超えてはなりません。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"エクストルーダー%1%の積層ピッチ(%2% mm)がオブジェクトの積層ピッチ(%3% mm)" +"より小さいです。オブジェクトの積層ピッチを最も細かいエクストルーダー積層ピッ" +"チまで下げてください。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"エクストルーダー%1%の積層ピッチ(%2% mm)はオブジェクトの積層ピッチ(%3% mm)" +"の整数倍である必要があります。" + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"このエクストルーダーで印刷可能な最低積層ピッチ。アダプティブ積層ピッチ有効時" +"の最小積層ピッチの制限に使われます。太い優先エクストルーダー積層ピッチで印刷" +"されるパーツも、この高さ未満には決して戻りません(最初の層を除く)。" + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"ノズル%1%の優先積層ピッチがノズルを通らなくなったため、デフォルトにリセットさ" +"れました。" + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"サポート/ラフトベースフィラメントがサポート/ラフトベース材料ではありません。" + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"サポート/ラフトベースフィラメントはサポートノズル直径に一致しないノズルで印刷" +"されます。" + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"サポート/ラフトインターフェイスフィラメントがサポート/ラフトインターフェイス" +"材料ではありません。" + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"サポート/ラフトインターフェイスフィラメントはサポートノズル直径に一致しないノ" +"ズルで印刷されます。" + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"一部のパーツのウォールフィラメントは異なる積層ピッチを優先しています。外壁と" +"内壁は一緒に印刷されるため、これらのウォールはオブジェクトの積層ピッチを維持" +"します。厚いウォールを印刷するには、両方のウォールを同じ高さを優先するフィラ" +"メントに割り当ててください。" + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"一部のパーツのウォールフィラメントは異なる積層ピッチを優先しています。外壁と" +"内壁は一緒に印刷されるため、これらのウォールは低い方の高さ(%1% mm)で印刷さ" +"れます。" + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"フィラメント%1%のウォール積層ピッチが、外壁と内壁が互換性のある積層ピッチで印" +"刷できるよう、優先の%2% mmから%3% mmに調整されました(\"ウォールの積層ピッチ" +"を調整\")。調整された高さで印刷されるのはこのフィラメントのウォールだけで、" +"他の形状は優先積層ピッチを維持します。" + +msgid "Thick layer regions" +msgstr "厚い層の領域" + +msgid "Thick layer tolerance" +msgstr "厚い層の許容差" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"このプリンターには%1% mmノズルのプロファイルがありません。プリンター設定でノ" +"ズル%2%の積層ピッチ制限を確認してください。" + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"このプリンターは異なるノズルサイズを使用しています。サポートを印刷するノズル" +"サイズと、ラフトおよびサポートインターフェイスに使うフィラメントタイプを選択" +"してください。" + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"調整されるウォールフィラメントのウォール積層ピッチを、他方のウォールフィラメ" +"ントと互換性のある高さへ下げるか上げるか。調整されるフィラメントの積層ピッチ" +"制限外の高さは決して使用されません。この方向に許容される高さがない場合、" +"ウォールは通常どおり低い方の高さで一緒に印刷されます。" + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"優先積層ピッチが割り切れないとき、2つのウォールフィラメントのどちらのウォール" +"積層ピッチを調整するか。" + # AI Translated msgid "Main Extruder" msgstr "メイン押出機" @@ -27336,15 +27844,6 @@ msgstr "" "0に設定すると、インフィル接続に旧アルゴリズムが使用されます。1000と0を指定し" "た場合と同じ結果になるはずです。" -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"内部スパース インフィルの印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - msgid "Infill/wall overlap" msgstr "インフィル/壁面 オーバーラップ" @@ -27687,32 +28186,6 @@ msgstr "" "この設定により、線幅に対するオーバーハングの割合を検出し、異なる速度で造形し" "ます。100%%のオーバーハングの場合、ブリッジの速度が使用されます。" -# AI Translated -msgid "Outer walls" -msgstr "外壁" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"外壁の印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - -# AI Translated -msgid "Inner walls" -msgstr "内壁" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"内壁の印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - msgid "This is the speed for inner walls." msgstr "内壁の造形速度です。" @@ -27897,33 +28370,6 @@ msgstr "" "スパース インフィルの面積がこの値以下の場合、ソリッド インフィルに変換されま" "す" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"内部ソリッドインフィルの印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"上面の印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"底面の印刷に使用するフィラメントです。\n" -"「デフォルト」を選ぶと、対象のオブジェクト/パーツのフィラメントが使用されま" -"す。" - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28082,16 +28528,6 @@ msgstr "" "フェース層がある場合、この値は無視され、サポートはオブジェクトに直接接触して" "印刷されます(隙間なし)。" -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"サポートベースとラフトの造形に使用するフィラメント。\n" -"「デフォルト」はサポート専用のフィラメントを指定せず、現在のフィラメントを使" -"用する意味です。" - msgid "Loop pattern interface" msgstr "接触面は同心パターンにする" @@ -28102,16 +28538,6 @@ msgstr "" "これにより、サポートの上部接触層がループで覆われます。デフォルトでは無効に" "なっています。" -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"サポートの接触面の造形に使用するフィラメントです。\n" -"「デフォルト」は接触面専用のフィラメントを指定せず、現在のフィラメントを使用" -"する意味です。" - msgid "This is the number of top interface layers." msgstr "トップ接触面の層数" diff --git a/localization/i18n/ko/Snapmaker_Orca_ko.po b/localization/i18n/ko/Snapmaker_Orca_ko.po index e37e262ef2f..eba578315d2 100644 --- a/localization/i18n/ko/Snapmaker_Orca_ko.po +++ b/localization/i18n/ko/Snapmaker_Orca_ko.po @@ -18436,6 +18436,501 @@ msgstr "" "ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 " "높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?" +msgid "Adjust wall layer height" +msgstr "벽 레이어 높이 조정" + +msgid "Adjusted walls" +msgstr "조정되는 벽" + +msgid "Adjustment direction" +msgstr "조정 방향" + +msgid "Consistent" +msgstr "일관" + +msgid "Decrease" +msgstr "낮추기" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"하단 표면을 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"내벽을 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"내부 솔리드 채우기를 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"내부 드문 채우기를 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"외벽을 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"기본 서포트 및 라프트를 출력하기 위한 필라멘트. \"기본값\"은 지원을 위한 특" +"정 필라멘트가 없으며 현재 필라멘트가 사용됨을 의미합니다" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"서포트 및 라프트 접점을 출력하기 위한 필라멘트. \"기본값\"은 지원을 위한 특" +"정 필라멘트가 없으며 현재 필라멘트가 사용됨을 의미합니다" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"상단 표면을 출력할 필라멘트.\n" +"\"기본값\"은 개체/부품의 현재 필라멘트를 사용합니다." + +msgid "Fixed" +msgstr "고정" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"더 두꺼운 선호 레이어 높이의 압출기에 할당된 부품을 얼마나 적극적으로 두꺼운 " +"레이어로 결합할지 정합니다.\n" +"일관: 부품은 최대 두 가지 레이어 높이로 출력됩니다. 완전한 레이어 묶음이 들어" +"가는 곳은 압출기 레이어 높이, 그 외에는 개체 레이어 높이입니다. 벽이 가장 균" +"일해집니다.\n" +"적응형: 묶음을 개체 레이어 높이의 중간 배수로도 결합할 수 있어 부품의 더 많" +"은 부분이 두꺼운 레이어로 출력되지만, 곡면 경계에 레이어 높이가 변하는 띠가 " +"생깁니다.\n" +"고정: 결합된 레이어 사이에서 형상이 변하거나 오버행이 있어도 부품은 항상 압출" +"기 레이어 높이로 출력됩니다. 곡면 경계는 계단이 되고 두꺼운 레이어보다 미세" +"한 디테일은 사라집니다. 두꺼운 레이어 하나에 못 미치는 형상(부품 상단과 첫 레" +"이어)만 더 얇게 출력됩니다." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"더 두꺼운 선호 레이어 높이의 압출기에 할당된 부품의 윤곽이 하나의 두꺼운 묶음" +"의 레이어들 사이에서 옆으로 얼마나 이동해도 결합될 수 있는지를 해당 압출기 노" +"즐 직경의 백분율로 지정합니다. 값이 클수록 곡면 경계가 더 많이 두꺼운 레이어" +"로 결합되지만 경계 벽은 거칠어집니다. 노즐 직경의 이 비율까지의 편차는 두꺼" +"운 압출선에 흡수됩니다." + +msgid "Increase" +msgstr "높이기" + +msgid "Inner walls" +msgstr "내벽" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"이 압출기가 출력해야 하는 레이어 높이로, 압출기마다 노즐 크기가 다른 프린터용" +"입니다. 개체 레이어 높이의 정수배여야 합니다. 모든 피처가 이 압출기를 따르는 " +"부품은 형상이 허용하는 곳에서 N번째 레이어마다 그만큼 두꺼운 압출로 출력되" +"며, 그 외에는 개체 레이어 높이로 돌아갑니다. 부품의 나머지가 따라갈 수 없으" +"면 이 압출기에 할당된 벽은 그래도 스스로 이 높이로 결합되고, 전체 밀도의 상" +"단 표면은 그 아래 솔리드 레이어를 흡수하며, 드문 채우기나 100% 밀도 채우기도 " +"독립적으로 이 높이로 결합됩니다. 0은 개체 레이어 높이를 사용합니다." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"이 압출기가 출력해야 하는 레이어 높이: 이 압출기의 레이어 높이 한도 내에서 개" +"체 레이어 높이의 정수배. 기본값은 개체 레이어 높이를 유지합니다." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "서포트 노즐 직경과 일치하는 노즐을 가진 압출기가 없습니다." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"로드된 필라멘트 중 서포트/라프트 베이스 재료(및 서포트 노즐 직경)와 일치하는 " +"것이 없습니다." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"로드된 필라멘트 중 서포트/라프트 인터페이스 재료(및 서포트 노즐 직경)와 일치" +"하는 것이 없습니다." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "노즐 %1%: 레이어 높이 한도가 \"%4%\"에서 %2%-%3% mm로 설정되었습니다." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"압출기마다 노즐 직경이 다른 프린터에서는 이 노즐 직경의 필라멘트만 서포트, 라" +"프트, 서포트 인터페이스 출력에 사용됩니다. 선 너비와 레이어 높이 한도가 다른 " +"다른 노즐 크기의 필라멘트를 서포트에서 배제합니다. 기본값이 아닌 값으로 설정" +"된 서포트 필라멘트는 이 직경과 일치해야 합니다. 0이면 모든 필라멘트가 서포트" +"를 출력할 수 있습니다." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"한쪽 높이가 다른 쪽의 정수배이면 외벽과 내벽은 자동으로 각자의 선호 레이어 높" +"이로 출력됩니다. 높이가 나누어떨어지지 않으면 이 옵션이 두 벽 필라멘트 중 하" +"나(아래에서 선택)의 벽 레이어 높이를 다른 쪽의 가장 가까운 배수나 약수로 조정" +"하여 벽이 여전히 분리될 수 있게 합니다. 조정된 높이는 그 필라멘트의 벽에만 적" +"용되며, 다른 피처는 선호 레이어 높이를 유지합니다. 조정은 필라멘트의 레이어 " +"높이 한도를 절대 벗어나지 않습니다. 선택한 방향에 허용되는 높이가 없으면 벽" +"은 평소처럼 더 낮은 높이로 함께 출력됩니다." + +msgid "Outer walls" +msgstr "외벽" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "압출기별 레이어 높이는 나선형 꽃병 모드에서 지원되지 않습니다." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "압출기별 레이어 높이는 인터페이스 셸과 함께 지원되지 않습니다." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "압출기별 레이어 높이는 가변 레이어 높이와 함께 지원되지 않습니다." + +msgid "Preferred layer height" +msgstr "선호 레이어 높이" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"서포트와 라프트 베이스를 이 재료 유형의 필라멘트로만 출력합니다. 다른 유형이 " +"로드된 압출기는 사용되지 않습니다. 서포트 노즐 직경 제한과 함께 작동합니다. " +"비워 두면 제한이 없습니다. 명시적으로 선택한 서포트/라프트 베이스 필라멘트가 " +"여전히 우선합니다." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"서포트와 라프트 인터페이스를 이 재료 유형의 필라멘트로만 출력합니다. 다른 유" +"형이 로드된 압출기는 사용되지 않습니다. 서포트 노즐 직경 제한과 함께 작동합니" +"다. 비워 두면 제한이 없습니다. 명시적으로 선택한 서포트/라프트 인터페이스 필" +"라멘트가 여전히 우선합니다." + +msgid "Raft and support base" +msgstr "라프트 및 서포트 베이스" + +msgid "Show legacy filament selection" +msgstr "이전 필라멘트 선택 표시" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"일부 부품은 %1% mm 레이어를 선호하지만, 그 부품의 다른 피처를 출력하는 필라멘" +"트 %2%의 노즐이 너무 작아 그 높이를 압출할 수 없습니다. 이 부품들은 대신 개" +"체 레이어 높이로 출력됩니다." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"일부 부품은 %1% mm 레이어를 선호하지만, 벽 필라멘트 %2%의 노즐이 너무 작아 " +"그 높이를 압출할 수 없습니다. 외벽과 내벽은 함께 출력되므로 이 벽들은 개체 레" +"이어 높이를 유지합니다. 두 벽 피처 모두 충분히 큰 노즐의 필라멘트에 할당하세" +"요." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"일부 부품이 최대 레이어 높이가 %3% mm인 필라멘트 %2%로 %1% mm 레이어를 출력합" +"니다. 부품 피처를 더 굵은 노즐의 필라멘트에 할당하거나, 필라멘트의 최대 레이" +"어 높이를 올리거나, 초과 출력을 감수하세요." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"일부 부품이 최소 레이어 높이가 %3% mm인 필라멘트 %2%로 %1% mm 레이어를 출력합" +"니다. 개체 레이어 높이를 올리거나, 이 피처들에 더 가는 노즐의 필라멘트를 쓰거" +"나, 압출기 최소값 아래 출력을 감수하세요." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"일부 부품이 사용하는 필라멘트들의 선호 레이어 높이를 모두 만족할 수 없습니" +"다. 부품은 하나의 레이어 피치로 피처를 출력합니다(벽 필라멘트가 정하며, 벽 필" +"라멘트에 선호가 없으면 나머지 피처의 합의로 정해집니다). 부품의 나머지가 따라" +"갈 수 없을 때 벽, 상단 표면, 채우기는 각자 자기 높이로 결합할 수 있지만, 나머" +"지 피처는 부품의 피치로 출력됩니다." + +msgid "Support for mixed nozzle sizes" +msgstr "혼합 노즐 크기의 서포트" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"서포트가 서로 다른 노즐 직경의 압출기로 출력될 수 있습니다. 서포트 노즐 직경" +"(또는 명시적인 서포트 및 인터페이스 필라멘트)을 설정해 서포트를 하나의 노즐 " +"크기로 유지하세요." + +msgid "Support nozzle diameter" +msgstr "서포트 노즐 직경" + +msgid "Support nozzle size" +msgstr "서포트 노즐 크기" + +msgid "Support/raft base material" +msgstr "서포트/라프트 베이스 재료" + +msgid "Support/raft interface material" +msgstr "서포트/라프트 인터페이스 재료" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mm의 채우기 선 너비는 %2% mm 높이로 결합된 채우기에 너무 작습니다. 선 너" +"비를 늘리거나 채우기 필라멘트의 선호 레이어 높이를 낮추세요." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"%1% mm의 선 너비는 해당 압출기의 %2% mm 레이어 높이에 너무 작습니다. 선 너비" +"를 늘리거나 압출기 레이어 높이를 낮추세요." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "압출기 %1%의 레이어 높이(%2% mm)는 노즐 직경을 초과할 수 없습니다." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"압출기 %1%의 레이어 높이(%2% mm)는 일부 부품에서 무시됩니다. 개체 레이어 높이" +"(%3% mm)의 정수배이면서 그보다 작지 않아야 하고, 압출기의 노즐 직경을 초과해" +"서는 안 됩니다." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"압출기 %1%의 레이어 높이(%2% mm)가 개체 레이어 높이(%3% mm)보다 작습니다. 개" +"체 레이어 높이를 가장 가는 압출기 레이어 높이로 낮추세요." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"압출기 %1%의 레이어 높이(%2% mm)는 개체 레이어 높이(%3% mm)의 정수배여야 합니" +"다." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"이 압출기로 출력할 수 있는 최저 레이어 높이. 적응형 레이어 높이 사용 시 최소 " +"레이어 높이를 제한하는 데 쓰입니다. 더 두꺼운 선호 압출기 레이어 높이로 출력" +"되는 부품도 이 높이 아래로는 절대 내려가지 않습니다(첫 레이어 제외)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"노즐 %1%의 선호 레이어 높이가 더 이상 노즐을 통과하지 못해 기본값으로 재설정" +"되었습니다." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "서포트/라프트 베이스 필라멘트가 서포트/라프트 베이스 재료가 아닙니다." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"서포트/라프트 베이스 필라멘트가 서포트 노즐 직경과 일치하지 않는 노즐로 출력" +"됩니다." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"서포트/라프트 인터페이스 필라멘트가 서포트/라프트 인터페이스 재료가 아닙니다." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"서포트/라프트 인터페이스 필라멘트가 서포트 노즐 직경과 일치하지 않는 노즐로 " +"출력됩니다." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"일부 부품의 벽 필라멘트가 서로 다른 레이어 높이를 선호합니다. 외벽과 내벽은 " +"함께 출력되므로 이 벽들은 개체 레이어 높이를 유지합니다. 더 두꺼운 벽을 출력" +"하려면 두 벽 피처를 같은 높이를 선호하는 필라멘트에 할당하세요." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"일부 부품의 벽 필라멘트가 서로 다른 레이어 높이를 선호합니다. 외벽과 내벽은 " +"함께 출력되므로 이 벽들은 더 낮은 높이(%1% mm)로 출력됩니다." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"필라멘트 %1%의 벽 레이어 높이가 외벽과 내벽이 호환되는 레이어 높이로 출력될 " +"수 있도록 선호값 %2% mm에서 %3% mm로 조정되었습니다(\"벽 레이어 높이 조정" +"\"). 이 필라멘트의 벽만 조정된 높이로 출력되며, 다른 피처는 선호값을 유지합니" +"다." + +msgid "Thick layer regions" +msgstr "두꺼운 레이어 영역" + +msgid "Thick layer tolerance" +msgstr "두꺼운 레이어 허용 오차" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"이 프린터에는 %1% mm 노즐용 프로파일이 없습니다. 프린터 설정에서 노즐 %2%의 " +"레이어 높이 한도를 확인하세요." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"이 프린터는 서로 다른 노즐 크기를 사용합니다. 서포트를 출력할 노즐 크기와 라" +"프트 및 서포트 인터페이스에 사용할 필라멘트 유형을 선택하세요." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"조정되는 벽 필라멘트의 벽 레이어 높이를 낮출지 높일지를 정해 다른 벽 필라멘트" +"와 호환되는 높이에 도달합니다. 조정되는 필라멘트의 레이어 높이 한도를 벗어나" +"는 높이는 절대 사용되지 않습니다. 이 방향에 허용되는 높이가 없으면 벽은 평소" +"처럼 더 낮은 높이로 함께 출력됩니다." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"선호 레이어 높이가 나누어떨어지지 않을 때 두 벽 필라멘트 중 어느 쪽의 벽 레이" +"어 높이를 조정할지 정합니다." + # AI Translated msgid "Main Extruder" msgstr "메인 압출기" @@ -27464,14 +27959,6 @@ msgstr "" "0으로 설정하면 채우기 연결에 대한 이전 알고리즘이 사용되며 1000 & 0과 동일한 " "결과를 생성해야 합니다." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"드문 내부 채우기를 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - msgid "Infill/wall overlap" msgstr "채우기/벽 겹치기" @@ -27823,30 +28310,6 @@ msgstr "" "선 너비에 비례하여 오버행 백분율을 감지하고 다른 속도를 사용하여 출력합니다. " "100%% 오버행의 경우 브릿지 속도가 사용됩니다." -# AI Translated -msgid "Outer walls" -msgstr "외벽" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"외벽을 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - -# AI Translated -msgid "Inner walls" -msgstr "내벽" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"내벽을 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - msgid "This is the speed for inner walls." msgstr "내벽 속도" @@ -28028,30 +28491,6 @@ msgid "" "by internal solid infill." msgstr "임계값보다 작은 드문 채우기 영역은 꽉찬 내부 채우기로 대체됩니다" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"꽉찬 내부 채우기를 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"상단 표면을 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"하단 표면을 출력할 필라멘트입니다.\n" -"\"기본값\"은 활성 객체/부품의 필라멘트를 사용합니다." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28212,16 +28651,6 @@ msgstr "" "스 레이어가 있으면 이 값은 무시되고 서포트가 객체에 직접 접촉하여 출력됩니다" "(간격 없음)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"서포트 베이스 및 라프트를 출력하기 위한 필라멘트.\n" -"\"기본값\"은 서포트 전용 필라멘트가 없으며 현재 필라멘트가 사용됨을 의미합니" -"다." - msgid "Loop pattern interface" msgstr "접점에서 루프 패턴 사용" @@ -28231,16 +28660,6 @@ msgid "" msgstr "" "서포트 상단 접촉 레이어를 루프로 덮습니다. 기본적으로 비활성화되어 있습니다." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"서포트 인터페이스를 출력하기 위한 필라멘트.\n" -"\"기본값\"은 서포트 인터페이스 전용 필라멘트가 없으며 현재 필라멘트가 사용됨" -"을 의미합니다." - # AI Translated msgid "This is the number of top interface layers." msgstr "상단 인터페이스 레이어의 수입니다." diff --git a/localization/i18n/lt/Snapmaker_Orca_lt.po b/localization/i18n/lt/Snapmaker_Orca_lt.po index a9d3f323cf0..e94cc1d468f 100644 --- a/localization/i18n/lt/Snapmaker_Orca_lt.po +++ b/localization/i18n/lt/Snapmaker_Orca_lt.po @@ -18981,6 +18981,532 @@ msgstr "" "riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas " "gali sumažinti deformacijų (warping) tikimybę?" +msgid "Adjust wall layer height" +msgstr "Koreguoti sienų sluoksnio aukštį" + +msgid "Adjusted walls" +msgstr "Koreguojamos sienos" + +msgid "Adjustment direction" +msgstr "Koregavimo kryptis" + +msgid "Consistent" +msgstr "Vientisas" + +msgid "Decrease" +msgstr "Mažinti" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija apatiniam paviršiui spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija vidinėms sienoms spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija vidiniam vientisam užpildymui spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija vidiniam retam užpildymui spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija išorinėms sienoms spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Gija, skirta spausdinti atraminį pagrindą ir platformą. \"Numatytoji\" " +"reiškia, kad nėra konkrečios gijos atramai ir naudojama dabartinė gija." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Gija skirta spausdinti atramos sąsają. \"Numatytoji\" reiškia, kad atramos " +"sąsajai nėra konkrečios gijos ir naudojama dabartinė gija." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Gija viršutiniam paviršiui spausdinti.\n" +"\"Numatytas\" naudoja aktyvią objekto/dalies giją." + +msgid "Fixed" +msgstr "Fiksuotas" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Kaip agresyviai dalys, priskirtos ekstruderiui su storesniu pageidaujamu " +"sluoksnio aukščiu, jungiamos į storus sluoksnius.\n" +"Vientisas: dalys spausdinamos daugiausiai dviem sluoksnio aukščiais - " +"ekstruderio sluoksnio aukščiu ten, kur telpa ištisos sluoksnių serijos, ir " +"objekto sluoksnio aukščiu visur kitur. Tai duoda lygiausias sienas.\n" +"Prisitaikantis: serijos gali būti jungiamos ir tarpiniais objekto sluoksnio " +"aukščio kartotiniais, todėl didesnė dalies dalis spausdinama storesniais " +"sluoksniais - kreivose dalių ribose atsiranda kintamo sluoksnio aukščio " +"juostos.\n" +"Fiksuotas: dalys visada spausdinamos ekstruderio sluoksnio aukščiu, net kur " +"forma keičiasi per sujungtus sluoksnius ar kabo; kreivos ribos virsta " +"laipteliais, o smulkesnės nei stori sluoksniai detalės prarandamos. Tik " +"geometrija, per trumpa visam storam sluoksniui (dalių viršūnės ir pirmas " +"sluoksnis), spausdinama ploniau." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Kiek dalies, priskirtos ekstruderiui su storesniu pageidaujamu sluoksnio " +"aukščiu, kontūras gali pasislinkti į šoną per vienos storos serijos " +"sluoksnius ir vis tiek būti sujungtas, procentais nuo to ekstruderio " +"purkštuko skersmens. Didesnės reikšmės sujungia daugiau kreivų ribų į storus " +"sluoksnius, bet ribų sienos tampa grubesnės: nuokrypius iki šios purkštuko " +"skersmens dalies praryja storos linijos." + +msgid "Increase" +msgstr "Didinti" + +msgid "Inner walls" +msgstr "Vidinės sienos" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Sluoksnio aukštis, kuriuo turėtų spausdinti šis ekstruderis; spausdintuvams, " +"kurių ekstruderių purkštukų dydžiai skiriasi. Jis turi būti sveikasis " +"objekto sluoksnio aukščio kartotinis. Dalis, kurios visi elementai seka šį " +"ekstruderį, spausdinama tik kas N-tą sluoksnį atitinkamai storesnėmis " +"linijomis ten, kur leidžia geometrija; kitur grįžtama prie objekto sluoksnio " +"aukščio. Kai likusi dalies dalis negali sekti, šiam ekstruderiui priskirtos " +"sienos vis tiek savarankiškai susijungia iki šio aukščio, visiško tankio " +"viršutiniai paviršiai sugeria po jais esančius vientisus sluoksnius, o retas " +"ar 100% tankio užpildymas susijungia iki šio aukščio nepriklausomai. 0 " +"reiškia naudoti objekto sluoksnio aukštį." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Sluoksnio aukštis, kuriuo turėtų spausdinti šis ekstruderis: sveikasis " +"objekto sluoksnio aukščio kartotinis šio ekstruderio sluoksnio aukščio " +"ribose. Numatytas išlaiko objekto sluoksnio aukštį." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Nė vienas ekstruderis neturi purkštuko, atitinkančio atramų purkštuko " +"skersmenį." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Nė viena įdėta gija neatitinka atramų/platformos pagrindo medžiagos (ir " +"atramų purkštuko skersmens)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Nė viena įdėta gija neatitinka atramų/platformos sąsajos medžiagos (ir " +"atramų purkštuko skersmens)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Purkštukas %1%: sluoksnio aukščio ribos nustatytos į %2%-%3% mm iš \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Spausdintuvuose, kurių ekstruderių purkštukų skersmenys skiriasi, atramoms, " +"platformai ir atramų sąsajai spausdinti naudojamos tik šio purkštuko " +"skersmens gijos. Tai neleidžia kitų purkštukų dydžių gijoms - su kitokiais " +"linijų pločiais ir sluoksnio aukščio ribomis - patekti į atramas. Atramų " +"gijos, nustatytos ne į numatytą reikšmę, turi atitikti šį skersmenį. Reikšmė " +"0 leidžia atramas spausdinti bet kuria gija." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Išorinės ir vidinės sienos automatiškai spausdinamos savo pageidaujamais " +"sluoksnių aukščiais, kai vienas aukštis yra sveikasis kito kartotinis. Kai " +"aukščiai nesidalija lygiai, ši parinktis koreguoja vienos iš dviejų sienų " +"gijų (pasirenkamos žemiau) sienų sluoksnio aukštį iki artimiausio kito " +"kartotinio ar daliklio, kad sienos vis tiek galėtų atsiskirti. Koreguotas " +"aukštis taikomas tik tos gijos sienoms; kiti elementai išlaiko pageidaujamą " +"sluoksnio aukštį. Koregavimai niekada neperžengia gijos sluoksnio aukščio " +"ribų: jei pasirinkta kryptimi leidžiamo aukščio nėra, sienos kaip įprasta " +"spausdinamos kartu žemesniu aukščiu." + +msgid "Outer walls" +msgstr "Išorinės sienos" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Sluoksnių aukščiai atskiriems ekstruderiams nepalaikomi spiralinės vazos " +"režime." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Sluoksnių aukščiai atskiriems ekstruderiams nepalaikomi kartu su sąsajos " +"apvalkalais." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Sluoksnių aukščiai atskiriems ekstruderiams nepalaikomi kartu su kintamu " +"sluoksnio aukščiu." + +msgid "Preferred layer height" +msgstr "Pageidaujamas sluoksnio aukštis" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Atramas ir platformos pagrindą spausdinti tik šio tipo medžiagos gijomis; " +"ekstruderiai su kitų tipų gijomis tam nenaudojami. Veikia kartu su atramų " +"purkštuko skersmens apribojimu. Palikite tuščią, jei riboti nereikia; " +"aiškiai pasirinkta atramų/platformos pagrindo gija vis tiek turi pirmenybę." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Atramų ir platformos sąsają spausdinti tik šio tipo medžiagos gijomis; " +"ekstruderiai su kitų tipų gijomis tam nenaudojami. Veikia kartu su atramų " +"purkštuko skersmens apribojimu. Palikite tuščią, jei riboti nereikia; " +"aiškiai pasirinkta atramų/platformos sąsajos gija vis tiek turi pirmenybę." + +msgid "Raft and support base" +msgstr "Platforma ir atramų pagrindas" + +msgid "Show legacy filament selection" +msgstr "Rodyti seną gijos pasirinkimą" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Kai kurios dalys pageidauja %1% mm sluoksnių, bet gijos %2%, spausdinančios " +"kitus dalies elementus, purkštukas per mažas tokiam aukščiui išspausti. Šios " +"dalys spausdinamos objekto sluoksnio aukščiu." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Kai kurios dalys pageidauja %1% mm sluoksnių, bet sienų gijos %2% purkštukas " +"per mažas tokiam aukščiui išspausti. Išorinės ir vidinės sienos spausdinamos " +"kartu, todėl šios sienos išlaiko objekto sluoksnio aukštį. Priskirkite abu " +"sienų elementus gijoms su pakankamai dideliais purkštukais." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Kai kurios dalys spausdina %1% mm sluoksnius gija %2%, kurios didžiausias " +"sluoksnio aukštis yra %3% mm. Priskirkite dalies elementus storesnio " +"purkštuko gijoms, padidinkite gijos didžiausią sluoksnio aukštį arba " +"sutikite spausdinti virš jo." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Kai kurios dalys spausdina %1% mm sluoksnius gija %2%, kurios mažiausias " +"sluoksnio aukštis yra %3% mm. Padidinkite objekto sluoksnio aukštį, šiems " +"elementams naudokite giją su plonesniu purkštuku arba sutikite spausdinti " +"žemiau ekstruderio minimumo." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Kai kurios dalys naudoja gijas, kurių pageidaujamų sluoksnių aukščių " +"neįmanoma patenkinti visų: dalis savo elementus spausdina vienu sluoksnio " +"žingsniu (jį nustato sienų gijos, o kai nė viena sienų gija neturi " +"pageidavimo - kitų elementų sutarimas); sienos, viršutiniai paviršiai ir " +"užpildymas gali kiekvienas susijungti iki savo aukščio, kai likusi dalies " +"dalis negali jų sekti, bet likę elementai spausdinami dalies žingsniu." + +msgid "Support for mixed nozzle sizes" +msgstr "Atramos mišriems purkštukų dydžiams" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Atramos gali būti spausdinamos skirtingų purkštukų skersmenų ekstruderiais. " +"Nustatykite atramų purkštuko skersmenį (arba aiškias atramų ir sąsajos " +"gijas), kad atramos liktų vieno purkštuko dydžio." + +msgid "Support nozzle diameter" +msgstr "Atramų purkštuko skersmuo" + +msgid "Support nozzle size" +msgstr "Atramų purkštuko dydis" + +msgid "Support/raft base material" +msgstr "Atramų/platformos pagrindo medžiaga" + +msgid "Support/raft interface material" +msgstr "Atramų/platformos sąsajos medžiaga" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mm užpildymo linijos plotis per mažas užpildymui, sujungtam į %2% mm " +"aukščio sluoksnius. Padidinkite linijos plotį arba sumažinkite užpildymo " +"gijos pageidaujamą sluoksnio aukštį." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"%1% mm linijos plotis per mažas jo ekstruderio %2% mm sluoksnio aukščiui. " +"Padidinkite linijos plotį arba sumažinkite ekstruderio sluoksnio aukštį." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Ekstruderio %1% sluoksnio aukštis (%2% mm) negali viršyti jo purkštuko " +"skersmens." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Ekstruderio %1% sluoksnio aukštis (%2% mm) kai kurioms dalims ignoruojamas: " +"jis turi būti sveikasis objekto sluoksnio aukščio (%3% mm) kartotinis, ne " +"mažesnis už jį ir neviršyti ekstruderio purkštuko skersmens." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Ekstruderio %1% sluoksnio aukštis (%2% mm) mažesnis už objekto sluoksnio " +"aukštį (%3% mm). Sumažinkite objekto sluoksnio aukštį iki ploniausio " +"ekstruderio sluoksnio aukščio." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Ekstruderio %1% sluoksnio aukštis (%2% mm) turi būti sveikasis objekto " +"sluoksnio aukščio (%3% mm) kartotinis." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Žemiausias ekstruderio spausdinamas sluoksnio aukštis. Riboja mažiausią " +"sluoksnio aukštį, kai įjungtas prisitaikantis sluoksnio aukštis. Dalys, " +"spausdinamos storesniu pageidaujamu ekstruderio sluoksnio aukščiu, taip pat " +"niekada nenusileidžia žemiau šio aukščio (išskyrus pirmą sluoksnį)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Purkštuko %1% pageidaujamas sluoksnio aukštis nebepraeina pro jį ir buvo " +"atstatytas į Numatytą." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Atramų/platformos pagrindo gija nėra atramų/platformos pagrindo medžiagos." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Atramų/platformos pagrindo gija spausdina purkštuku, neatitinkančiu atramų " +"purkštuko skersmens." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Atramų/platformos sąsajos gija nėra atramų/platformos sąsajos medžiagos." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Atramų/platformos sąsajos gija spausdina purkštuku, neatitinkančiu atramų " +"purkštuko skersmens." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Kai kurių dalių sienų gijos pageidauja skirtingų sluoksnių aukščių. Išorinės " +"ir vidinės sienos spausdinamos kartu, todėl šios sienos išlaiko objekto " +"sluoksnio aukštį. Norėdami spausdinti storesnes sienas, priskirkite abu " +"sienų elementus gijoms, pageidaujančioms to paties aukščio." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Kai kurių dalių sienų gijos pageidauja skirtingų sluoksnių aukščių. Išorinės " +"ir vidinės sienos spausdinamos kartu, todėl šios sienos spausdinamos " +"žemesniu aukščiu (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Gijos %1% sienų sluoksnio aukštis pakoreguotas iš pageidaujamų %2% mm į %3% " +"mm, kad išorinės ir vidinės sienos galėtų spausdintis suderinamais sluoksnių " +"aukščiais (\"Koreguoti sienų sluoksnio aukštį\"). Koreguotu aukščiu " +"spausdinamos tik šios gijos sienos; kiti jos elementai išlaiko pageidaujamą." + +msgid "Thick layer regions" +msgstr "Storų sluoksnių sritys" + +msgid "Thick layer tolerance" +msgstr "Storų sluoksnių tolerancija" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Šis spausdintuvas neturi profilio %1% mm purkštukui. Patikrinkite purkštuko " +"%2% sluoksnio aukščio ribas spausdintuvo nustatymuose." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Šis spausdintuvas naudoja skirtingus purkštukų dydžius. Pasirinkite " +"purkštuko dydį atramoms spausdinti ir gijų tipus platformai bei atramų " +"sąsajai." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Ar koreguojamos sienų gijos sienų sluoksnio aukštis mažinamas, ar didinamas, " +"kad pasiektų su kita sienų gija suderinamą aukštį. Aukščiai už koreguojamos " +"gijos sluoksnio aukščio ribų niekada nenaudojami: jei šia kryptimi leidžiamo " +"aukščio nėra, sienos kaip įprasta spausdinamos kartu žemesniu aukščiu." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Kurios iš dviejų sienų gijų sienų sluoksnio aukštis koreguojamas, kai " +"pageidaujami sluoksnių aukščiai nesidalija lygiai." + # AI Translated msgid "Main Extruder" msgstr "Pagrindinis ekstruderis" @@ -28091,13 +28617,6 @@ msgstr "" "Jei nustatyta 0, bus naudojamas senasis užpildo sujungimo algoritmas, kuris " "turėtų sukurti tokį patį rezultatą kaip ir nustačius 1000 ir 0." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama vidiniam retam užpildui spausdinti.\n" -"Pasirinkus „Default“ (numatytasis), naudojama aktyvaus objekto / dalies gija." - msgid "Infill/wall overlap" msgstr "Užpildo ir sienelės persidengimas" @@ -28452,26 +28971,6 @@ msgstr "" "naudokite skirtingą spausdinimo greitį. Jei iškyša 100%%, naudojamas tilto " "greitis." -msgid "Outer walls" -msgstr "Išorinės sienelės" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama išorinėms sienelėms spausdinti. Pasirinkus „Numatytasis“, " -"naudojama aktyvaus objekto / dalies gija." - -msgid "Inner walls" -msgstr "Vidinės sienelės" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama vidinėms sienelėms spausdinti. Pasirinkus „Numatytasis“, " -"naudojama aktyvaus objekto / dalies gija." - msgid "This is the speed for inner walls." msgstr "Vidinių sienelių greitis." @@ -28663,27 +29162,6 @@ msgstr "" "Reto užpildo sritys, kurios yra mažesnės už šią ribinę vertę, yra " "pakeičiamos vidiniu vientisu užpildu." -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama vidiniam vientisam užpildui spausdinti.\n" -"Pasirinkus „Numatytoji“, naudojama aktyvaus objekto / dalies gija." - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama viršutiniam paviršiui spausdinti.\n" -"Pasirinkus „Numatytoji“, naudojama aktyvaus objekto / dalies gija." - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Gija, naudojama apatiniam paviršiui spausdinti.\n" -"Pasirinkus „Numatytoji“, naudojama aktyvaus objekto / dalies gija." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28854,15 +29332,6 @@ msgstr "" "yra 0 ir apačioje yra sąsajos sluoksniai, ši reikšmė ignoruojama ir atrama " "spausdinama tiesiogiai kontaktuojant su objektu (be tarpo)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Gija, naudojama atramų pagrindui ir padui (raft) spausdinti.\n" -"Pasirinkus „Numatytoji“, speciali gija atramoms nenaudojama ir imama šiuo " -"metu aktyvi gija." - msgid "Loop pattern interface" msgstr "Kilpos modelio sąsaja." @@ -28873,15 +29342,6 @@ msgstr "" "Tai uždengia viršutinį atramų kontaktinį sluoksnį kilpomis. Pagal " "numatytuosius nustatymus ši funkcija yra išjungta." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Gija, naudojama atramų sąsajai spausdinti.\n" -"Pasirinkus „Numatytoji“, speciali gija atramų sąsajai nenaudojama ir imama " -"šiuo metu aktyvi gija." - msgid "This is the number of top interface layers." msgstr "Tai viršutinių sąsajos sluoksnių skaičius." diff --git a/localization/i18n/nl/Snapmaker_Orca_nl.po b/localization/i18n/nl/Snapmaker_Orca_nl.po index cf9762af2b5..cb464ee75f8 100644 --- a/localization/i18n/nl/Snapmaker_Orca_nl.po +++ b/localization/i18n/nl/Snapmaker_Orca_nl.po @@ -19840,6 +19840,542 @@ msgstr "" "kromtrekken, zoals ABS, een juiste verhoging van de temperatuur van het " "warmtebed de kans op kromtrekken kan verkleinen?" +msgid "Adjust wall layer height" +msgstr "Laaghoogte van wanden aanpassen" + +msgid "Adjusted walls" +msgstr "Aangepaste wanden" + +msgid "Adjustment direction" +msgstr "Aanpassingsrichting" + +msgid "Consistent" +msgstr "Consistent" + +msgid "Decrease" +msgstr "Verlagen" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor het bodemoppervlak.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor de binnenste wanden.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor de interne massieve vulling.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor de interne dunne vulling.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor de buitenste wanden.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament voor het printen van ondersteuning (support) en raft. \"Standaard\" " +"betekent geen specifiek filament voor ondersteuning (support) en het " +"huidige filament wordt gebruikt." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament om ondersteuning (support) te printen. \"Standaard\" betekent geen " +"specifiek filament voor ondersteuning (support), en het huidige filament " +"wordt gebruikt." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament voor het bovenvlak.\n" +"\"Standaard\" gebruikt het actieve filament van het object/onderdeel." + +msgid "Fixed" +msgstr "Vast" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Hoe agressief onderdelen die zijn toegewezen aan een extruder met een " +"dikkere voorkeurslaaghoogte worden gecombineerd tot dikke lagen.\n" +"Consistent: onderdelen printen met hoogstens twee laaghoogtes - de " +"extruderlaaghoogte waar hele reeksen lagen passen en de objectlaaghoogte " +"overal elders. Dit geeft de meest gelijkmatige wanden.\n" +"Adaptief: reeksen mogen ook worden gecombineerd op tussenliggende veelvouden " +"van de objectlaaghoogte, zodat meer van het onderdeel met dikkere lagen " +"print, ten koste van banden met wisselende laaghoogtes op gebogen randen.\n" +"Vast: onderdelen printen altijd op de extruderlaaghoogte, ook waar de vorm " +"over de gecombineerde lagen verandert of overhangt; gebogen randen worden " +"trappen en details fijner dan de dikke lagen gaan verloren. Alleen geometrie " +"die te kort is voor een hele dikke laag (bovenkanten van onderdelen en de " +"eerste laag) print dunner." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Hoe ver de omtrek van een onderdeel dat is toegewezen aan een extruder met " +"een dikkere voorkeurslaaghoogte zijwaarts mag verschuiven over de lagen van " +"één dikke reeks en toch gecombineerd wordt, als percentage van de " +"mondstukdiameter van die extruder. Hogere waarden combineren meer gebogen " +"randen tot dikke lagen, ten koste van ruwere randwanden: afwijkingen tot dit " +"deel van de mondstukdiameter worden opgeslokt door de dikke extrusies." + +msgid "Increase" +msgstr "Verhogen" + +msgid "Inner walls" +msgstr "Binnenste wanden" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Laaghoogte waarmee deze extruder moet printen, voor printers waarvan de " +"extruders verschillende mondstukmaten hebben. Moet een geheel veelvoud van " +"de objectlaaghoogte zijn. Een onderdeel waarvan alle kenmerken deze extruder " +"volgen, print alleen op elke N-de laag met dienovereenkomstig dikkere " +"extrusies, waar de geometrie het toelaat; elders valt het terug op de " +"objectlaaghoogte. Als de rest van het onderdeel niet kan volgen, combineren " +"wanden die aan deze extruder zijn toegewezen zich toch zelfstandig tot deze " +"hoogte, absorberen volledig dichte bovenvlakken de massieve lagen eronder, " +"en combineert dunne of 100% dichte vulling zich onafhankelijk tot deze " +"hoogte. 0 betekent de objectlaaghoogte gebruiken." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Laaghoogte waarmee deze extruder moet printen: een geheel veelvoud van de " +"objectlaaghoogte binnen de laaghoogtelimieten van deze extruder. Standaard " +"behoudt de objectlaaghoogte." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Geen enkele extruder heeft een mondstuk dat overeenkomt met de " +"mondstukdiameter voor ondersteuning." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Geen geladen filament komt overeen met het materiaal van de ondersteunings-/" +"vlotbasis (en de mondstukdiameter voor ondersteuning)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Geen geladen filament komt overeen met het materiaal van de ondersteunings-/" +"vlotinterface (en de mondstukdiameter voor ondersteuning)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Mondstuk %1%: laaghoogtelimieten ingesteld op %2%-%3% mm, uit \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Op printers waarvan de extruders verschillende mondstukdiameters hebben, " +"worden alleen filamenten van deze mondstukdiameter gebruikt om " +"ondersteuning, vlot en ondersteuningsinterface te printen. Dit houdt " +"filamenten van andere mondstukmaten - met hun andere lijnbreedtes en " +"laaghoogtelimieten - uit de ondersteuning. Ondersteuningsfilamenten met een " +"niet-standaardwaarde moeten met deze diameter overeenkomen. Waarde 0 laat " +"elk filament ondersteuning printen." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Buitenste en binnenste wanden printen automatisch op hun eigen " +"voorkeurslaaghoogtes wanneer de ene hoogte een geheel veelvoud van de andere " +"is. Wanneer de hoogtes niet gelijk deelbaar zijn, past deze optie de " +"wandlaaghoogte van één van de twee wandfilamenten (hieronder gekozen) aan " +"naar het dichtstbijzijnde veelvoud of de dichtstbijzijnde deler van de " +"andere, zodat de wanden zich toch kunnen splitsen. De aangepaste hoogte " +"geldt alleen voor de wanden van dat filament; andere kenmerken behouden de " +"voorkeurslaaghoogte. Aanpassingen verlaten nooit de laaghoogtelimieten van " +"het filament: bestaat er in de gekozen richting geen toegestane hoogte, dan " +"printen de wanden zoals gebruikelijk samen op de lagere hoogte." + +msgid "Outer walls" +msgstr "Buitenste wanden" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Laaghoogtes per extruder worden niet ondersteund in de spiraalvaasmodus." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Laaghoogtes per extruder worden niet ondersteund samen met interfaceschillen." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Laaghoogtes per extruder worden niet ondersteund samen met variabele " +"laaghoogte." + +msgid "Preferred layer height" +msgstr "Voorkeurslaaghoogte" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Print de ondersteuning en vlotbasis alleen met filamenten van dit " +"materiaaltype; extruders met andere types worden hiervoor niet gebruikt. " +"Werkt samen met de mondstukdiameterbeperking voor ondersteuning. Leeg laten " +"voor geen beperking; een expliciet gekozen ondersteunings-/vlotbasisfilament " +"heeft nog steeds voorrang." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Print de ondersteunings- en vlotinterface alleen met filamenten van dit " +"materiaaltype; extruders met andere types worden hiervoor niet gebruikt. " +"Werkt samen met de mondstukdiameterbeperking voor ondersteuning. Leeg laten " +"voor geen beperking; een expliciet gekozen ondersteunings-/" +"vlotinterfacefilament heeft nog steeds voorrang." + +msgid "Raft and support base" +msgstr "Vlot en ondersteuningsbasis" + +msgid "Show legacy filament selection" +msgstr "Oude filamentselectie tonen" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Sommige onderdelen prefereren lagen van %1% mm, maar het mondstuk van " +"filament %2% dat andere kenmerken van het onderdeel print is te klein om die " +"hoogte te extruderen. Deze onderdelen printen in plaats daarvan met de " +"objectlaaghoogte." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Sommige onderdelen prefereren lagen van %1% mm, maar het mondstuk van " +"wandfilament %2% is te klein om die hoogte te extruderen. Buitenste en " +"binnenste wanden printen samen, dus deze wanden behouden de " +"objectlaaghoogte. Wijs beide wandkenmerken toe aan filamenten met voldoende " +"grote mondstukken." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Sommige onderdelen printen lagen van %1% mm met filament %2%, waarvan de " +"maximale laaghoogte %3% mm is. Wijs de kenmerken van het onderdeel toe aan " +"filamenten van het grovere mondstuk, verhoog de maximale laaghoogte van het " +"filament, of accepteer erboven te printen." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Sommige onderdelen printen lagen van %1% mm met filament %2%, waarvan de " +"minimale laaghoogte %3% mm is. Verhoog de objectlaaghoogte, gebruik voor " +"deze kenmerken een filament met een fijner mondstuk, of accepteer onder het " +"minimum van de extruder te printen." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Sommige onderdelen gebruiken filamenten waarvan de voorkeurslaaghoogtes niet " +"allemaal kunnen worden gehonoreerd: een onderdeel print zijn kenmerken met " +"één laagstap (bepaald door zijn wandfilamenten, of door de overeenstemming " +"van de andere kenmerken als geen wandfilament een voorkeur heeft); de " +"wanden, de bovenvlakken en de vulling kunnen zich elk tot hun eigen hoogte " +"combineren wanneer de rest van het onderdeel ze niet kan volgen, maar de " +"overige kenmerken printen met de stap van het onderdeel." + +msgid "Support for mixed nozzle sizes" +msgstr "Ondersteuning bij gemengde mondstukmaten" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Ondersteuning kan printen met extruders van verschillende mondstukdiameters. " +"Stel de mondstukdiameter voor ondersteuning in (of expliciete " +"ondersteunings- en interfacefilamenten) om de ondersteuning op één " +"mondstukmaat te houden." + +msgid "Support nozzle diameter" +msgstr "Mondstukdiameter voor ondersteuning" + +msgid "Support nozzle size" +msgstr "Mondstukmaat voor ondersteuning" + +msgid "Support/raft base material" +msgstr "Materiaal ondersteunings-/vlotbasis" + +msgid "Support/raft interface material" +msgstr "Materiaal ondersteunings-/vlotinterface" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"De vullijnbreedte van %1% mm is te klein voor vulling gecombineerd tot lagen " +"van %2% mm hoog. Vergroot de lijnbreedte of verlaag de voorkeurslaaghoogte " +"van het vulfilament." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"De lijnbreedte van %1% mm is te klein voor de laaghoogte van %2% mm van zijn " +"extruder. Vergroot de lijnbreedte of verlaag de extruderlaaghoogte." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"De laaghoogte van extruder %1% (%2% mm) kan de mondstukdiameter niet " +"overschrijden." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"De laaghoogte van extruder %1% (%2% mm) wordt voor sommige onderdelen " +"genegeerd: ze moet een geheel veelvoud van de objectlaaghoogte (%3% mm) " +"zijn, niet eronder liggen, en mag de mondstukdiameter van de extruder niet " +"overschrijden." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"De laaghoogte van extruder %1% (%2% mm) is kleiner dan de objectlaaghoogte " +"(%3% mm). Verlaag de objectlaaghoogte tot de fijnste extruderlaaghoogte." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"De laaghoogte van extruder %1% (%2% mm) moet een geheel veelvoud van de " +"objectlaaghoogte (%3% mm) zijn." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"De laagste printbare laaghoogte van de extruder. Beperkt de minimale " +"laaghoogte wanneer adaptieve laaghoogte is ingeschakeld. Onderdelen die met " +"een dikkere voorkeursextruderlaaghoogte printen, vallen ook nooit onder deze " +"hoogte terug (behalve de eerste laag)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"De voorkeurslaaghoogte van mondstuk %1% past er niet meer doorheen en is " +"teruggezet op Standaard." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Het ondersteunings-/vlotbasisfilament is niet van het materiaal van de " +"ondersteunings-/vlotbasis." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Het ondersteunings-/vlotbasisfilament print met een mondstuk dat niet " +"overeenkomt met de mondstukdiameter voor ondersteuning." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Het ondersteunings-/vlotinterfacefilament is niet van het materiaal van de " +"ondersteunings-/vlotinterface." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Het ondersteunings-/vlotinterfacefilament print met een mondstuk dat niet " +"overeenkomt met de mondstukdiameter voor ondersteuning." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"De wandfilamenten van sommige onderdelen prefereren verschillende " +"laaghoogtes. Buitenste en binnenste wanden printen samen, dus deze wanden " +"behouden de objectlaaghoogte. Wijs beide wandkenmerken toe aan filamenten " +"met dezelfde voorkeurshoogte om dikkere wanden te printen." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"De wandfilamenten van sommige onderdelen prefereren verschillende " +"laaghoogtes. Buitenste en binnenste wanden printen samen, dus deze wanden " +"printen met de lagere hoogte (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"De wandlaaghoogte van filament %1% is aangepast van de voorkeur van %2% mm " +"naar %3% mm zodat de buitenste en binnenste wanden op compatibele " +"laaghoogtes kunnen printen (\"Laaghoogte van wanden aanpassen\"). Alleen de " +"wanden van dit filament printen de aangepaste hoogte; zijn andere kenmerken " +"behouden de voorkeurshoogte." + +msgid "Thick layer regions" +msgstr "Regio's met dikke lagen" + +msgid "Thick layer tolerance" +msgstr "Tolerantie voor dikke lagen" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Deze printer heeft geen profiel voor een mondstuk van %1% mm. Controleer de " +"laaghoogtelimieten van mondstuk %2% in de printerinstellingen." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Deze printer gebruikt verschillende mondstukmaten. Selecteer de mondstukmaat " +"die de ondersteuning print, en de filamenttypes voor het vlot en de " +"ondersteuningsinterface." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Of de wandlaaghoogte van het aangepaste wandfilament wordt verlaagd of " +"verhoogd om een hoogte te bereiken die compatibel is met het andere " +"wandfilament. Hoogtes buiten de laaghoogtelimieten van het aangepaste " +"filament worden nooit gebruikt: bestaat er in deze richting geen toegestane " +"hoogte, dan printen de wanden zoals gebruikelijk samen op de lagere hoogte." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Welk van de twee wandfilamenten zijn wandlaaghoogte aangepast krijgt wanneer " +"de voorkeurslaaghoogtes niet gelijk deelbaar zijn." + # AI Translated msgid "Main Extruder" msgstr "Hoofdextruder" @@ -29948,14 +30484,6 @@ msgstr "" "Bij 0 wordt het oude algoritme voor het verbinden van de vulling gebruikt; " "dat zou hetzelfde resultaat moeten geven als met 1000 & 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om de interne dunne vulling (infill) te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - msgid "Infill/wall overlap" msgstr "Vulling (infill)/wand overlap" @@ -30335,30 +30863,6 @@ msgstr "" "lijnbreedte te detecteren en gebruikt verschillende snelheden om af te " "drukken. Voor 100%% overhang wordt de brugsnelheid gebruikt." -# AI Translated -msgid "Outer walls" -msgstr "Buitenste wanden" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om de buitenste wanden te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - -# AI Translated -msgid "Inner walls" -msgstr "Binnenste wanden" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om de binnenste wanden te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - msgid "This is the speed for inner walls." msgstr "Dit is de snelheid voor de binnenste wanden" @@ -30560,30 +31064,6 @@ msgstr "" "Dunne opvullingen (infill) die kleiner zijn dan deze drempelwaarde worden " "vervangen door solide interne vulling (infill)." -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om de interne solide vulling te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om het bovenoppervlak te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament om het onderoppervlak te printen.\n" -"\"Standaard\" gebruikt het filament van het actieve object/onderdeel." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -30758,17 +31238,6 @@ msgstr "" "heeft, wordt deze waarde genegeerd en wordt de ondersteuning direct in " "contact met het object geprint (geen gap)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament voor het printen van de basis van de ondersteuning (support) en de " -"raft.\n" -"\"Standaard\" betekent dat er geen specifiek filament voor de ondersteuning " -"is en dat het huidige filament wordt gebruikt." - msgid "Loop pattern interface" msgstr "Luspatroon interface" @@ -30779,17 +31248,6 @@ msgstr "" "Dit bedekt de bovenste laag van de support met lussen. Het is standaard " "uitgeschakeld." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament voor het printen van de ondersteuningsinterface (support " -"interface).\n" -"\"Standaard\" betekent dat er geen specifiek filament voor de " -"ondersteuningsinterface is en dat het huidige filament wordt gebruikt." - # AI Translated msgid "This is the number of top interface layers." msgstr "Dit is het aantal bovenste interfacelagen." diff --git a/localization/i18n/pl/Snapmaker_Orca_pl.po b/localization/i18n/pl/Snapmaker_Orca_pl.po index 6a43220f36e..89761bcc4d9 100644 --- a/localization/i18n/pl/Snapmaker_Orca_pl.po +++ b/localization/i18n/pl/Snapmaker_Orca_pl.po @@ -19240,6 +19240,532 @@ msgstr "" "takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może " "zmniejszyć prawdopodobieństwo odkształceń?" +msgid "Adjust wall layer height" +msgstr "Dostosuj wysokość warstwy ścian" + +msgid "Adjusted walls" +msgstr "Dostosowywane ściany" + +msgid "Adjustment direction" +msgstr "Kierunek dostosowania" + +msgid "Consistent" +msgstr "Spójnie" + +msgid "Decrease" +msgstr "Zmniejsz" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku dolnej powierzchni.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku wewnętrznych ścian.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku wewnętrznego wypełnienia pełnego.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku wewnętrznego wypełnienia rzadkiego.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku zewnętrznych ścian.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament do drukowania podstawy podpory i raftu. „Domyślnie” oznacza brak " +"wyboru konkretnego filamentu dla ich podstawy. Zostanie użyty obecny filament" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament do drukowania warstw łączących podpory z modelem. „Domyślnie” " +"oznacza brak konkretnego filamentu dla podpory i używanie obecnego filamentu" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament do druku górnej powierzchni.\n" +"\"Domyślny\" używa aktywnego filamentu obiektu/części." + +msgid "Fixed" +msgstr "Stale" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Jak agresywnie części przypisane do ekstrudera z grubszą preferowaną " +"wysokością warstwy są łączone w grube warstwy.\n" +"Spójnie: części drukują się najwyżej dwiema wysokościami warstwy - " +"wysokością warstwy ekstrudera tam, gdzie mieszczą się całe serie warstw, i " +"wysokością warstwy obiektu wszędzie indziej. Daje to najrówniejsze ściany.\n" +"Adaptacyjnie: serie mogą być łączone także na pośrednich wielokrotnościach " +"wysokości warstwy obiektu, więc większa część elementu drukuje się grubszymi " +"warstwami - kosztem pasm zmiennej wysokości warstwy na zakrzywionych " +"granicach.\n" +"Stale: części zawsze drukują się wysokością warstwy ekstrudera, nawet tam, " +"gdzie kształt zmienia się w poprzek łączonych warstw lub zwisa; zakrzywione " +"granice zamieniają się w stopnie, a detale drobniejsze niż grube warstwy " +"giną. Tylko geometria zbyt krótka na całą grubą warstwę (wierzchołki części " +"i pierwsza warstwa) drukuje się cieniej." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Jak daleko obrys części przypisanej do ekstrudera z grubszą preferowaną " +"wysokością warstwy może przesunąć się w bok w poprzek warstw jednej grubej " +"serii i wciąż zostać połączony, jako procent średnicy dyszy tego ekstrudera. " +"Wyższe wartości łączą więcej zakrzywionych granic w grube warstwy, kosztem " +"bardziej chropowatych ścian granicznych: odchylenia do tego ułamka średnicy " +"dyszy są pochłaniane przez grube linie." + +msgid "Increase" +msgstr "Zwiększ" + +msgid "Inner walls" +msgstr "Wewnętrzne ściany" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Wysokość warstwy, którą powinien drukować ten ekstruder; dla drukarek, " +"których ekstrudery mają różne rozmiary dysz. Musi być całkowitą " +"wielokrotnością wysokości warstwy obiektu. Część, której wszystkie elementy " +"podążają za tym ekstruderem, drukuje się tylko co N-tą warstwę odpowiednio " +"grubszymi liniami tam, gdzie pozwala geometria; gdzie indziej wraca do " +"wysokości warstwy obiektu. Gdy reszta części nie może nadążyć, ściany " +"przypisane temu ekstruderowi i tak łączą się samodzielnie do tej wysokości, " +"w pełni gęste górne powierzchnie pochłaniają pełne warstwy pod sobą, a " +"wypełnienie (rzadkie lub o gęstości 100%) łączy się do tej wysokości " +"niezależnie. 0 oznacza użycie wysokości warstwy obiektu." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Wysokość warstwy, którą powinien drukować ten ekstruder: całkowita " +"wielokrotność wysokości warstwy obiektu w granicach ograniczeń wysokości " +"warstwy tego ekstrudera. Domyślnie zachowuje wysokość warstwy obiektu." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Żaden ekstruder nie ma dyszy zgodnej ze średnicą dyszy podpór." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Żaden załadowany filament nie pasuje do materiału podstawy podpór/tratwy (i " +"do średnicy dyszy podpór)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Żaden załadowany filament nie pasuje do materiału warstw stykowych podpór/" +"tratwy (i do średnicy dyszy podpór)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Dysza %1%: ograniczenia wysokości warstwy ustawione na %2%-%3% mm, z \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Na drukarkach, których ekstrudery mają różne średnice dysz, do druku podpór, " +"tratwy i warstw stykowych używane są tylko filamenty o tej średnicy dyszy. " +"Trzyma to filamenty innych rozmiarów dysz - z ich inną szerokością linii i " +"ograniczeniami wysokości warstwy - z dala od podpór. Filamenty podpór " +"ustawione na wartość inną niż domyślna muszą pasować do tej średnicy. " +"Wartość 0 pozwala drukować podpory dowolnym filamentem." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Zewnętrzne i wewnętrzne ściany automatycznie drukują się własnymi " +"preferowanymi wysokościami warstwy, gdy jedna wysokość jest całkowitą " +"wielokrotnością drugiej. Gdy wysokości nie dzielą się równo, ta opcja " +"dostosowuje wysokość warstwy ścian jednego z dwóch filamentów ścian " +"(wybranego poniżej) do najbliższej wielokrotności lub dzielnika drugiej, aby " +"ściany nadal mogły się rozdzielić. Dostosowana wysokość dotyczy tylko ścian " +"tego filamentu; pozostałe elementy zachowują preferowaną wysokość warstwy. " +"Dostosowania nigdy nie wychodzą poza ograniczenia wysokości warstwy " +"filamentu: jeśli w wybranym kierunku nie ma dozwolonej wysokości, ściany " +"drukują się razem na niższej wysokości jak zwykle." + +msgid "Outer walls" +msgstr "Zewnętrzne ściany" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Wysokości warstwy na ekstruder nie są obsługiwane w trybie wazy." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Wysokości warstwy na ekstruder nie są obsługiwane razem z powłokami " +"stykowymi." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Wysokości warstwy na ekstruder nie są obsługiwane razem ze zmienną " +"wysokością warstwy." + +msgid "Preferred layer height" +msgstr "Preferowana wysokość warstwy" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Drukuj podpory i podstawę tratwy tylko filamentami tego typu materiału; " +"ekstrudery z innymi typami nie są do tego używane. Działa razem z " +"ograniczeniem średnicy dyszy podpór. Zostaw puste, aby nie ograniczać; " +"jawnie wybrany filament podstawy podpór/tratwy nadal ma pierwszeństwo." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Drukuj warstwy stykowe podpór i tratwy tylko filamentami tego typu " +"materiału; ekstrudery z innymi typami nie są do tego używane. Działa razem z " +"ograniczeniem średnicy dyszy podpór. Zostaw puste, aby nie ograniczać; " +"jawnie wybrany filament warstw stykowych nadal ma pierwszeństwo." + +msgid "Raft and support base" +msgstr "Tratwa i podstawa podpór" + +msgid "Show legacy filament selection" +msgstr "Pokaż stary wybór filamentu" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Niektóre części preferują warstwy %1% mm, ale dysza filamentu %2% " +"drukującego inne elementy części jest za mała, by wytłoczyć tę wysokość. Te " +"części drukują się zamiast tego wysokością warstwy obiektu." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Niektóre części preferują warstwy %1% mm, ale dysza filamentu ścian %2% jest " +"za mała, by wytłoczyć tę wysokość. Zewnętrzne i wewnętrzne ściany drukują " +"się razem, więc te ściany zachowują wysokość warstwy obiektu. Przypisz oba " +"rodzaje ścian filamentom z wystarczająco dużymi dyszami." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Niektóre części drukują warstwy %1% mm filamentem %2%, którego maksymalna " +"wysokość warstwy to %3% mm. Przypisz elementy części filamentom grubszej " +"dyszy, zwiększ maksymalną wysokość warstwy filamentu lub zaakceptuj druk " +"powyżej niej." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Niektóre części drukują warstwy %1% mm filamentem %2%, którego minimalna " +"wysokość warstwy to %3% mm. Zwiększ wysokość warstwy obiektu, użyj do tych " +"elementów filamentu z drobniejszą dyszą lub zaakceptuj druk poniżej minimum " +"ekstrudera." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Niektóre części używają filamentów, których preferowanych wysokości warstwy " +"nie da się wszystkich spełnić: część drukuje swoje elementy jednym skokiem " +"warstwy (ustalonym przez jej filamenty ścian, a gdy żaden filament ścian nie " +"ma preferencji - przez zgodę pozostałych elementów); ściany, górne " +"powierzchnie i wypełnienie mogą łączyć się każde do własnej wysokości, gdy " +"reszta części nie może za nimi nadążyć, ale pozostałe elementy drukują się " +"skokiem części." + +msgid "Support for mixed nozzle sizes" +msgstr "Podpory przy mieszanych rozmiarach dysz" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Podpory mogą drukować się ekstruderami o różnych średnicach dysz. Ustaw " +"średnicę dyszy podpór (lub jawne filamenty podpór i warstw stykowych), aby " +"utrzymać podpory na jednym rozmiarze dyszy." + +msgid "Support nozzle diameter" +msgstr "Średnica dyszy podpór" + +msgid "Support nozzle size" +msgstr "Rozmiar dyszy podpór" + +msgid "Support/raft base material" +msgstr "Materiał podstawy podpór/tratwy" + +msgid "Support/raft interface material" +msgstr "Materiał warstw stykowych podpór/tratwy" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Szerokość linii wypełnienia %1% mm jest za mała dla wypełnienia łączonego w " +"warstwy o wysokości %2% mm. Zwiększ szerokość linii lub obniż preferowaną " +"wysokość warstwy filamentu wypełnienia." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Szerokość linii %1% mm jest za mała dla wysokości warstwy %2% mm jej " +"ekstrudera. Zwiększ szerokość linii lub obniż wysokość warstwy ekstrudera." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Wysokość warstwy ekstrudera %1% (%2% mm) nie może przekraczać średnicy jego " +"dyszy." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Wysokość warstwy ekstrudera %1% (%2% mm) jest ignorowana dla niektórych " +"części: musi być całkowitą wielokrotnością wysokości warstwy obiektu (%3% " +"mm), nie mniejszą od niej, i nie może przekraczać średnicy dyszy ekstrudera." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Wysokość warstwy ekstrudera %1% (%2% mm) jest mniejsza niż wysokość warstwy " +"obiektu (%3% mm). Obniż wysokość warstwy obiektu do najdrobniejszej " +"wysokości warstwy ekstrudera." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Wysokość warstwy ekstrudera %1% (%2% mm) musi być całkowitą wielokrotnością " +"wysokości warstwy obiektu (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Najniższa drukowalna wysokość warstwy ekstrudera. Ogranicza minimalną " +"wysokość warstwy przy włączonej adaptacyjnej wysokości warstwy. Części " +"drukowane grubszą preferowaną wysokością warstwy ekstrudera również nigdy " +"nie schodzą poniżej tej wysokości (poza pierwszą warstwą)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Preferowana wysokość warstwy dyszy %1% już przez nią nie przechodzi i " +"została zresetowana do Domyślnej." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Filament podstawy podpór/tratwy nie jest z materiału podstawy podpór/tratwy." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Filament podstawy podpór/tratwy drukuje dyszą niezgodną ze średnicą dyszy " +"podpór." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Filament warstw stykowych podpór/tratwy nie jest z materiału warstw " +"stykowych podpór/tratwy." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Filament warstw stykowych podpór/tratwy drukuje dyszą niezgodną ze średnicą " +"dyszy podpór." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Filamenty ścian niektórych części preferują różne wysokości warstwy. " +"Zewnętrzne i wewnętrzne ściany drukują się razem, więc te ściany zachowują " +"wysokość warstwy obiektu. Aby drukować grubsze ściany, przypisz oba rodzaje " +"ścian filamentom preferującym tę samą wysokość." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Filamenty ścian niektórych części preferują różne wysokości warstwy. " +"Zewnętrzne i wewnętrzne ściany drukują się razem, więc te ściany drukują się " +"niższą wysokością (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Wysokość warstwy ścian filamentu %1% została dostosowana z preferowanych %2% " +"mm do %3% mm, aby zewnętrzne i wewnętrzne ściany mogły drukować się zgodnymi " +"wysokościami warstwy (\"Dostosuj wysokość warstwy ścian\"). Dostosowaną " +"wysokością drukują się tylko ściany tego filamentu; jego pozostałe elementy " +"zachowują preferowaną." + +msgid "Thick layer regions" +msgstr "Obszary grubych warstw" + +msgid "Thick layer tolerance" +msgstr "Tolerancja grubych warstw" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Ta drukarka nie ma profilu dla dyszy %1% mm. Sprawdź ograniczenia wysokości " +"warstwy dyszy %2% w ustawieniach drukarki." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Ta drukarka używa różnych rozmiarów dysz. Wybierz rozmiar dyszy drukującej " +"podpory oraz typy filamentów używane do tratwy i warstw stykowych podpór." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Czy wysokość warstwy ścian dostosowywanego filamentu jest zmniejszana czy " +"zwiększana, aby osiągnąć wysokość zgodną z drugim filamentem ścian. " +"Wysokości poza ograniczeniami wysokości warstwy dostosowywanego filamentu " +"nigdy nie są używane: jeśli w tym kierunku nie ma dozwolonej wysokości, " +"ściany drukują się razem na niższej wysokości jak zwykle." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Który z dwóch filamentów ścian ma dostosowywaną wysokość warstwy ścian, gdy " +"preferowane wysokości warstwy nie dzielą się równo." + # AI Translated msgid "Main Extruder" msgstr "Główny ekstruder" @@ -28730,14 +29256,6 @@ msgstr "" "Jeśli ustawione na 0, zostanie użyty stary algorytm łączenia wypełnienia, " "powinien dać ten sam wynik co przy ustawieniu 1000 & 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku wewnętrznego wypełnienia.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - msgid "Infill/wall overlap" msgstr "Nakładanie wypełnienia na obrysy" @@ -29106,30 +29624,6 @@ msgstr "" "Określ procentowy udział nawisów w stosunku do szerokości ekstruzji i użyj " "różnych prędkości do druku. Dla 100%% nawisów, zostanie użyta prędkość mostu." -# AI Translated -msgid "Outer walls" -msgstr "Ściany zewnętrzne" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku ścian zewnętrznych.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - -# AI Translated -msgid "Inner walls" -msgstr "Ściany wewnętrzne" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku ścian wewnętrznych.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - msgid "This is the speed for inner walls." msgstr "Prędkość wewnętrznej ściany" @@ -29319,30 +29813,6 @@ msgstr "" "Obszar wypełnienia, który jest mniejszy od wartości progowej zostaje " "zastąpiony wewnętrznym, pełnym wypełnieniem" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku wewnętrznego wypełnienia pełnego.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku górnej powierzchni.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament do druku dolnej powierzchni.\n" -"„Domyślny” używa filamentu aktywnego obiektu/części." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29517,16 +29987,6 @@ msgstr "" "0 i dół ma warstwy interfejsu, ta wartość jest ignorowana, a podpory są " "drukowane w bezpośrednim kontakcie z obiektem (bez odstępu)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament do drukowania podstawy podpory i raftu.\n" -"„Domyślnie” oznacza brak wyboru konkretnego filamentu dla ich podstawy. " -"Zostanie użyty obecny filament" - msgid "Loop pattern interface" msgstr "Użyj wzoru pętli dla warstw łączących" @@ -29535,16 +29995,6 @@ msgid "" "by default." msgstr "Przykryj górną warstwę stykową podpór pętlami. Domyślnie wyłączone." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament do drukowania warstw łączących podpory z modelem.\n" -"„Domyślnie” oznacza brak konkretnego filamentu dla warstwy łączącej i " -"używanie obecnego filamentu" - # AI Translated msgid "This is the number of top interface layers." msgstr "Liczba górnych warstw łączących." diff --git a/localization/i18n/pt_BR/Snapmaker_Orca_pt_BR.po b/localization/i18n/pt_BR/Snapmaker_Orca_pt_BR.po index edd578fff39..86e27d6a504 100644 --- a/localization/i18n/pt_BR/Snapmaker_Orca_pt_BR.po +++ b/localization/i18n/pt_BR/Snapmaker_Orca_pt_BR.po @@ -19225,6 +19225,546 @@ msgstr "" "aumentar adequadamente a temperatura da mesa aquecida pode reduzir a " "probabilidade de empenamento?" +msgid "Adjust wall layer height" +msgstr "Ajustar a altura da camada das paredes" + +msgid "Adjusted walls" +msgstr "Paredes ajustadas" + +msgid "Adjustment direction" +msgstr "Direção do ajuste" + +msgid "Consistent" +msgstr "Consistente" + +msgid "Decrease" +msgstr "Diminuir" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir a superfície inferior.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir paredes internas.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir o preenchimento sólido interno.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir o preenchimento esparso interno.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir paredes externas.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filamento para imprimir a base de suporte e a jangada.\n" +"\"Padrão\" significa nenhum filamento específico para suporte e o filamento " +"atual será usado." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filamento para imprimir a interface de suporte.\n" +"\"Padrão\" significa nenhum filamento específico para a interface de suporte " +"e o filamento atual é usado." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filamento para imprimir a superfície superior.\n" +"\"Padrão\" usa o filamento do objeto/peça." + +msgid "Fixed" +msgstr "Fixo" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Quão agressivamente as peças atribuídas a uma extrusora com altura de camada " +"preferida mais espessa são combinadas em camadas espessas.\n" +"Consistente: as peças imprimem com no máximo duas alturas de camada - a " +"altura da camada da extrusora onde cabem séries inteiras de camadas e a " +"altura da camada do objeto em todo o resto. Isso dá as paredes mais " +"uniformes.\n" +"Adaptativo: as séries também podem ser combinadas em múltiplos " +"intermediários da altura da camada do objeto, então mais da peça imprime com " +"camadas espessas, ao custo de faixas de alturas de camada variáveis nos " +"contornos curvos.\n" +"Fixo: as peças sempre imprimem na altura da camada da extrusora, mesmo onde " +"a forma muda através das camadas combinadas ou tem balanços; contornos " +"curvos viram degraus e detalhes mais finos que as camadas espessas são " +"perdidos. Apenas a geometria curta demais para uma camada espessa inteira " +"(os topos das peças e a primeira camada) imprime mais fina." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Quanto o contorno de uma peça atribuída a uma extrusora com altura de camada " +"preferida mais espessa pode deslocar-se lateralmente através das camadas de " +"uma série espessa e ainda ser combinado, como porcentagem do diâmetro do " +"bico dessa extrusora. Valores maiores combinam mais contornos curvos em " +"camadas espessas, ao custo de paredes de contorno mais ásperas: desvios até " +"essa fração do diâmetro do bico são absorvidos pelas extrusões espessas." + +msgid "Increase" +msgstr "Aumentar" + +msgid "Inner walls" +msgstr "Paredes internas" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Altura da camada com que esta extrusora deve imprimir, para impressoras " +"cujas extrusoras têm bicos de tamanhos diferentes. Deve ser um múltiplo " +"inteiro da altura da camada do objeto. Uma peça cujas características seguem " +"todas esta extrusora imprime apenas a cada N camadas com extrusões " +"correspondentemente mais espessas, onde sua geometria permitir; no resto, " +"volta à altura da camada do objeto. Quando o resto da peça não pode " +"acompanhar, as paredes atribuídas a esta extrusora ainda se combinam " +"sozinhas nesta altura, superfícies superiores totalmente densas absorvem as " +"camadas sólidas abaixo delas, e o preenchimento esparso ou 100% denso " +"combina-se independentemente nesta altura. 0 significa usar a altura da " +"camada do objeto." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Altura da camada com que esta extrusora deve imprimir: um múltiplo inteiro " +"da altura da camada do objeto dentro dos limites de altura de camada desta " +"extrusora. Padrão mantém a altura da camada do objeto." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Nenhuma extrusora tem um bico compatível com o diâmetro do bico dos suportes." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Nenhum filamento carregado corresponde ao material da base dos suportes/" +"jangada (e ao diâmetro do bico dos suportes)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Nenhum filamento carregado corresponde ao material da interface dos suportes/" +"jangada (e ao diâmetro do bico dos suportes)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Bico %1%: limites de altura da camada definidos em %2%-%3% mm, de \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Em impressoras cujas extrusoras têm diâmetros de bico diferentes, apenas " +"filamentos desse diâmetro de bico são usados para imprimir suportes, jangada " +"e interface dos suportes. Isso mantém filamentos de outros tamanhos de bico " +"- com suas larguras de linha e limites de altura de camada diferentes - fora " +"dos suportes. Filamentos de suporte definidos com um valor não padrão devem " +"corresponder a este diâmetro. O valor 0 permite que qualquer filamento " +"imprima suportes." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"As paredes externas e internas imprimem automaticamente nas suas próprias " +"alturas de camada preferidas quando uma altura é um múltiplo inteiro da " +"outra. Quando as alturas não se dividem exatamente, esta opção ajusta a " +"altura da camada das paredes de um dos dois filamentos de parede (escolhido " +"abaixo) para o múltiplo ou divisor mais próximo da outra, para que as " +"paredes ainda possam se separar. A altura ajustada aplica-se apenas às " +"paredes desse filamento; as demais características mantêm a altura da camada " +"preferida. Os ajustes nunca saem dos limites de altura de camada do " +"filamento: se não existir altura permitida na direção escolhida, as paredes " +"imprimem juntas na altura menor, como de costume." + +msgid "Outer walls" +msgstr "Paredes externas" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Alturas de camada por extrusora não são suportadas no modo vaso espiral." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Alturas de camada por extrusora não são suportadas junto com cascas de " +"interface." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Alturas de camada por extrusora não são suportadas junto com altura de " +"camada variável." + +msgid "Preferred layer height" +msgstr "Altura da camada preferida" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Imprimir os suportes e a base da jangada apenas com filamentos deste tipo de " +"material; extrusoras carregadas com outros tipos não são usadas para isso. " +"Combina-se com a restrição do diâmetro do bico dos suportes. Deixe vazio " +"para não restringir; um filamento de base dos suportes/jangada escolhido " +"explicitamente ainda tem precedência." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Imprimir a interface dos suportes e da jangada apenas com filamentos deste " +"tipo de material; extrusoras carregadas com outros tipos não são usadas para " +"isso. Combina-se com a restrição do diâmetro do bico dos suportes. Deixe " +"vazio para não restringir; um filamento de interface dos suportes/jangada " +"escolhido explicitamente ainda tem precedência." + +msgid "Raft and support base" +msgstr "Jangada e base dos suportes" + +msgid "Show legacy filament selection" +msgstr "Mostrar a seleção antiga de filamento" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Algumas peças preferem camadas de %1% mm, mas o bico do filamento %2% que " +"imprime outras características da peça é pequeno demais para extrudar essa " +"altura. Essas peças imprimem com a altura da camada do objeto em vez disso." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Algumas peças preferem camadas de %1% mm, mas o bico do filamento de parede " +"%2% é pequeno demais para extrudar essa altura. As paredes externas e " +"internas imprimem juntas, então essas paredes mantêm a altura da camada do " +"objeto. Atribua ambas as características de parede a filamentos com bicos " +"grandes o suficiente." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Algumas peças imprimem camadas de %1% mm com o filamento %2%, cuja altura " +"máxima de camada é %3% mm. Atribua as características da peça aos filamentos " +"do bico mais grosso, aumente a altura máxima de camada do filamento ou " +"aceite imprimir acima dela." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Algumas peças imprimem camadas de %1% mm com o filamento %2%, cuja altura " +"mínima de camada é %3% mm. Aumente a altura da camada do objeto, use um " +"filamento com um bico mais fino para essas características ou aceite " +"imprimir abaixo do mínimo da extrusora." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Algumas peças usam filamentos cujas alturas de camada preferidas não podem " +"ser todas atendidas: uma peça imprime suas características com um só passo " +"de camada (definido pelos seus filamentos de parede, ou pelo acordo das " +"demais características quando nenhum filamento de parede tem preferência); " +"as paredes, as superfícies superiores e o preenchimento podem cada um " +"combinar-se na sua própria altura quando o resto da peça não pode acompanhá-" +"los, mas as características restantes imprimem com o passo da peça." + +msgid "Support for mixed nozzle sizes" +msgstr "Suportes com tamanhos de bico mistos" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Os suportes podem imprimir com extrusoras de diâmetros de bico diferentes. " +"Defina o diâmetro do bico dos suportes (ou filamentos explícitos de suporte " +"e interface) para manter os suportes em um só tamanho de bico." + +msgid "Support nozzle diameter" +msgstr "Diâmetro do bico dos suportes" + +msgid "Support nozzle size" +msgstr "Tamanho do bico dos suportes" + +msgid "Support/raft base material" +msgstr "Material da base dos suportes/jangada" + +msgid "Support/raft interface material" +msgstr "Material da interface dos suportes/jangada" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"A largura de linha do preenchimento de %1% mm é pequena demais para " +"preenchimento combinado em camadas de %2% mm de altura. Aumente a largura da " +"linha ou reduza a altura da camada preferida do filamento de preenchimento." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"A largura de linha de %1% mm é pequena demais para a altura de camada de %2% " +"mm da sua extrusora. Aumente a largura da linha ou reduza a altura da camada " +"da extrusora." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"A altura da camada da extrusora %1% (%2% mm) não pode exceder o diâmetro do " +"seu bico." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"A altura da camada da extrusora %1% (%2% mm) é ignorada para algumas peças: " +"deve ser um múltiplo inteiro da altura da camada do objeto (%3% mm), não " +"abaixo dela, e não deve exceder o diâmetro do bico da extrusora." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"A altura da camada da extrusora %1% (%2% mm) é menor que a altura da camada " +"do objeto (%3% mm). Reduza a altura da camada do objeto para a altura de " +"camada de extrusora mais fina." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"A altura da camada da extrusora %1% (%2% mm) deve ser um múltiplo inteiro da " +"altura da camada do objeto (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"A menor altura de camada imprimível da extrusora. Usada para limitar a " +"altura mínima de camada quando a altura de camada adaptativa está ativada. " +"Peças impressas com uma altura de camada de extrusora preferida mais espessa " +"também nunca caem abaixo desta altura (exceto a primeira camada)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"A altura da camada preferida do bico %1% não passa mais por ele e foi " +"redefinida para Padrão." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"O filamento da base dos suportes/jangada não é do material da base dos " +"suportes/jangada." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"O filamento da base dos suportes/jangada imprime com um bico que não " +"corresponde ao diâmetro do bico dos suportes." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"O filamento da interface dos suportes/jangada não é do material da interface " +"dos suportes/jangada." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"O filamento da interface dos suportes/jangada imprime com um bico que não " +"corresponde ao diâmetro do bico dos suportes." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Os filamentos de parede de algumas peças preferem alturas de camada " +"diferentes. As paredes externas e internas imprimem juntas, então essas " +"paredes mantêm a altura da camada do objeto. Atribua ambas as " +"características de parede a filamentos que prefiram a mesma altura para " +"imprimir paredes mais espessas." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Os filamentos de parede de algumas peças preferem alturas de camada " +"diferentes. As paredes externas e internas imprimem juntas, então essas " +"paredes imprimem com a altura menor (%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"A altura da camada das paredes do filamento %1% foi ajustada dos %2% mm " +"preferidos para %3% mm para que as paredes externas e internas possam " +"imprimir em alturas de camada compatíveis (\"Ajustar a altura da camada das " +"paredes\"). Apenas as paredes deste filamento imprimem a altura ajustada; " +"suas demais características mantêm a preferida." + +msgid "Thick layer regions" +msgstr "Regiões de camadas espessas" + +msgid "Thick layer tolerance" +msgstr "Tolerância de camadas espessas" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Esta impressora não tem perfil para um bico de %1% mm. Verifique os limites " +"de altura da camada do bico %2% nas configurações da impressora." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Esta impressora usa tamanhos de bico diferentes. Selecione o tamanho do bico " +"que imprime os suportes e os tipos de filamento usados para a jangada e a " +"interface dos suportes." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Se a altura da camada das paredes do filamento ajustado é diminuída ou " +"aumentada para alcançar uma altura compatível com o outro filamento de " +"parede. Alturas fora dos limites de altura de camada do filamento ajustado " +"nunca são usadas: se não existir altura permitida nesta direção, as paredes " +"imprimem juntas na altura menor, como de costume." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Qual dos dois filamentos de parede tem sua altura da camada das paredes " +"ajustada quando as alturas de camada preferidas não se dividem exatamente." + msgid "Main Extruder" msgstr "Extrusora Principal" @@ -28154,13 +28694,6 @@ msgstr "" "Se definido como 0, o antigo algoritmo de conexão de preenchimento será " "usado, ele deve criar o mesmo resultado que com 1000 e 0." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir o preenchimento esparso interno.\n" -"\"Padrão\" usa o filamento do objeto/peça." - msgid "Infill/wall overlap" msgstr "Sobreposição de preenchimento/parede" @@ -28510,26 +29043,6 @@ msgstr "" "perímetro e usa uma velocidade diferente de impressão. Para saliências " "100%%, a velocidade de ponte é usada." -msgid "Outer walls" -msgstr "Paredes externas" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir paredes externas.\n" -"\"Padrão\" usa o filamento do objeto/peça." - -msgid "Inner walls" -msgstr "Paredes internas" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir paredes internas.\n" -"\"Padrão\" usa o filamento do objeto/peça." - msgid "This is the speed for inner walls." msgstr "Essa é a velocidade para paredes internas." @@ -28706,27 +29219,6 @@ msgstr "" "Áreas de preenchimento esparso menores que este valor limiar são " "substituídas por preenchimento sólido interno." -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir o preenchimento sólido interno.\n" -"\"Padrão\" usa o filamento do objeto/peça." - -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir a superfície superior.\n" -"\"Padrão\" usa o filamento do objeto/peça." - -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filamento para imprimir a superfície inferior.\n" -"\"Padrão\" usa o filamento do objeto/peça." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -28887,15 +29379,6 @@ msgstr "" "Suporte for 0 e a base tiver camadas de interface, este valor é ignorado e o " "suporte é impresso em contato direto com o objeto (sem espaço)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filamento para imprimir a base de suporte e a jangada.\n" -"\"Padrão\" significa nenhum filamento específico para suporte e o filamento " -"atual será usado." - msgid "Loop pattern interface" msgstr "Interface do padrão de volta" @@ -28906,15 +29389,6 @@ msgstr "" "Isso cobre a camada de contato superior dos suportes com voltas. É " "desativado por padrão." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filamento para imprimir a interface de suporte.\n" -"\"Padrão\" significa nenhum filamento específico para a interface de suporte " -"e o filamento atual é usado." - msgid "This is the number of top interface layers." msgstr "Este é o número de camadas de interface superiores." diff --git a/localization/i18n/ru/Snapmaker_Orca_ru.po b/localization/i18n/ru/Snapmaker_Orca_ru.po index 9ea00d2663e..1f73df6536a 100644 --- a/localization/i18n/ru/Snapmaker_Orca_ru.po +++ b/localization/i18n/ru/Snapmaker_Orca_ru.po @@ -19429,6 +19429,532 @@ msgstr "" "ABS, повышение температуры подогреваемого стола может снизить эту " "вероятность?" +msgid "Adjust wall layer height" +msgstr "Подгонять высоту слоя стенок" + +msgid "Adjusted walls" +msgstr "Подгоняемые стенки" + +msgid "Adjustment direction" +msgstr "Направление подгонки" + +msgid "Consistent" +msgstr "Единообразно" + +msgid "Decrease" +msgstr "Уменьшать" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати нижней поверхности.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати внутренних периметров.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати внутреннего сплошного заполнения.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати внутреннего заполнения.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати внешних периметров.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Материал для печати основной части поддержки и подложки. «По умолчанию» – " +"использовать материал модели." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Материал для печати связующего слоя поддержки. «По умолчанию» – использовать " +"материал модели." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Материал для печати верхней поверхности.\n" +"\"По умолчанию\" использует активный материал объекта/детали." + +msgid "Fixed" +msgstr "Фиксированно" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Насколько агрессивно детали, назначенные экструдеру с более толстой " +"предпочитаемой высотой слоя, объединяются в толстые слои.\n" +"Единообразно: детали печатаются максимум двумя высотами слоя — высотой слоя " +"экструдера там, где помещаются целые серии слоёв, и высотой слоя объекта в " +"остальных местах. Это даёт самые ровные стенки.\n" +"Адаптивно: серии могут объединяться и на промежуточных кратных высоты слоя " +"объекта, поэтому большая часть детали печатается толстыми слоями — ценой " +"полос переменной высоты слоя на криволинейных границах.\n" +"Фиксированно: детали всегда печатаются высотой слоя экструдера, даже там, " +"где форма меняется поперёк объединённых слоёв или нависает; криволинейные " +"границы превращаются в ступени, а детали мельче толстых слоёв теряются. " +"Только геометрия, слишком короткая для целого толстого слоя (верхушки " +"деталей и первый слой), печатается тоньше." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Насколько контур детали, назначенной экструдеру с более толстой " +"предпочитаемой высотой слоя, может смещаться вбок между слоями одной толстой " +"серии и всё же объединяться — в процентах от диаметра сопла этого " +"экструдера. Большие значения объединяют больше криволинейных границ в " +"толстые слои ценой более грубых стенок на границах: отклонения до этой доли " +"диаметра сопла поглощаются толстыми линиями." + +msgid "Increase" +msgstr "Увеличивать" + +msgid "Inner walls" +msgstr "Внутренние периметры" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Высота слоя, которой должен печатать этот экструдер; для принтеров, у " +"которых экструдеры имеют разные размеры сопла. Должна быть целым кратным " +"высоты слоя объекта. Деталь, все элементы которой следуют за этим " +"экструдером, печатается только на каждом N-м слое соответственно более " +"толстыми линиями там, где позволяет её геометрия; в остальных местах " +"используется высота слоя объекта. Когда остальная часть детали не может " +"следовать, стенки, назначенные этому экструдеру, всё равно объединяются до " +"этой высоты самостоятельно, полностью плотные верхние поверхности поглощают " +"сплошные слои под собой, а заполнение (разреженное или 100% плотности) " +"объединяется до этой высоты независимо. 0 — использовать высоту слоя объекта." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Высота слоя, которой должен печатать этот экструдер: целое кратное высоты " +"слоя объекта в пределах ограничений высоты слоя этого экструдера. По " +"умолчанию сохраняется высота слоя объекта." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "" +"Ни у одного экструдера нет сопла, соответствующего диаметру сопла поддержек." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Ни один загруженный материал не соответствует материалу основания поддержек/" +"подложки (и диаметру сопла поддержек)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Ни один загруженный материал не соответствует материалу связующего слоя " +"поддержек/подложки (и диаметру сопла поддержек)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Сопло %1%: ограничения высоты слоя установлены на %2%-%3% мм из \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"На принтерах, у которых экструдеры имеют разные диаметры сопла, для печати " +"поддержек, подложки и связующего слоя используются только материалы этого " +"диаметра сопла. Это не пускает в поддержки материалы других размеров сопла — " +"с их другой шириной линии и ограничениями высоты слоя. Материалы поддержек, " +"заданные не по умолчанию, должны соответствовать этому диаметру. Значение 0 " +"позволяет печатать поддержки любым материалом." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Внешние и внутренние периметры автоматически печатаются со своими " +"предпочитаемыми высотами слоя, когда одна высота — целое кратное другой. " +"Когда высоты не делятся нацело, эта опция подгоняет высоту слоя стенок " +"одного из двух материалов стенок (выбранного ниже) к ближайшему кратному или " +"делителю другой, чтобы стенки всё же могли разделиться. Подогнанная высота " +"применяется только к стенкам этого материала; остальные элементы сохраняют " +"предпочитаемую высоту слоя. Подгонка никогда не выходит за ограничения " +"высоты слоя материала: если в выбранном направлении нет допустимой высоты, " +"стенки печатаются вместе на меньшей высоте, как обычно." + +msgid "Outer walls" +msgstr "Внешние периметры" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Высоты слоя для отдельных экструдеров не поддерживаются в режиме вазы." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Высоты слоя для отдельных экструдеров не поддерживаются вместе со связующими " +"оболочками." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Высоты слоя для отдельных экструдеров не поддерживаются вместе с переменной " +"высотой слоя." + +msgid "Preferred layer height" +msgstr "Предпочитаемая высота слоя" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Печатать поддержки и основание подложки только материалами этого типа; " +"экструдеры с другими типами для этого не используются. Действует вместе с " +"ограничением диаметра сопла поддержек. Оставьте пустым, чтобы не " +"ограничивать; явно выбранный материал основания поддержек/подложки по-" +"прежнему в приоритете." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Печатать связующий слой поддержек и подложки только материалами этого типа; " +"экструдеры с другими типами для этого не используются. Действует вместе с " +"ограничением диаметра сопла поддержек. Оставьте пустым, чтобы не " +"ограничивать; явно выбранный материал связующего слоя по-прежнему в " +"приоритете." + +msgid "Raft and support base" +msgstr "Подложка и основание поддержек" + +msgid "Show legacy filament selection" +msgstr "Показать старый выбор материала" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Некоторые детали предпочитают слои %1% мм, но сопло материала %2%, " +"печатающего другие элементы детали, слишком мало для такой высоты. Эти " +"детали печатаются высотой слоя объекта." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Некоторые детали предпочитают слои %1% мм, но сопло материала стенок %2% " +"слишком мало для такой высоты. Внешние и внутренние периметры печатаются " +"вместе, поэтому эти стенки сохраняют высоту слоя объекта. Назначьте оба типа " +"стенок материалам с достаточно большими соплами." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Некоторые детали печатают слои %1% мм материалом %2%, у которого " +"максимальная высота слоя %3% мм. Назначьте элементы детали материалам более " +"крупного сопла, увеличьте максимальную высоту слоя материала или согласитесь " +"печатать выше неё." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Некоторые детали печатают слои %1% мм материалом %2%, у которого минимальная " +"высота слоя %3% мм. Увеличьте высоту слоя объекта, используйте для этих " +"элементов материал с более тонким соплом или согласитесь печатать ниже " +"минимума экструдера." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Некоторые детали используют материалы, чьи предпочитаемые высоты слоя нельзя " +"соблюсти все сразу: деталь печатает свои элементы одним шагом слоя " +"(задаваемым её материалами стенок, а если ни один материал стенок не имеет " +"предпочтения — согласием остальных элементов); стенки, верхние поверхности и " +"заполнение могут объединяться каждый до своей высоты, когда остальная часть " +"детали не может за ними следовать, но остальные элементы печатаются шагом " +"детали." + +msgid "Support for mixed nozzle sizes" +msgstr "Поддержки при разных размерах сопла" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Поддержки могут печататься экструдерами с разными диаметрами сопла. Задайте " +"диаметр сопла поддержек (или явные материалы поддержек и связующего слоя), " +"чтобы держать поддержки на одном размере сопла." + +msgid "Support nozzle diameter" +msgstr "Диаметр сопла поддержек" + +msgid "Support nozzle size" +msgstr "Размер сопла поддержек" + +msgid "Support/raft base material" +msgstr "Материал основания поддержек/подложки" + +msgid "Support/raft interface material" +msgstr "Материал связующего слоя поддержек/подложки" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Ширина линии заполнения %1% мм слишком мала для заполнения, объединённого в " +"слои высотой %2% мм. Увеличьте ширину линии или уменьшите предпочитаемую " +"высоту слоя материала заполнения." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Ширина линии %1% мм слишком мала для высоты слоя %2% мм её экструдера. " +"Увеличьте ширину линии или уменьшите высоту слоя экструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Высота слоя экструдера %1% (%2% мм) не может превышать диаметр его сопла." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Высота слоя экструдера %1% (%2% мм) игнорируется для некоторых деталей: она " +"должна быть целым кратным высоты слоя объекта (%3% мм), не меньше её и не " +"должна превышать диаметр сопла экструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Высота слоя экструдера %1% (%2% мм) меньше высоты слоя объекта (%3% мм). " +"Уменьшите высоту слоя объекта до самой тонкой высоты слоя экструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Высота слоя экструдера %1% (%2% мм) должна быть целым кратным высоты слоя " +"объекта (%3% мм)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Наименьшая печатаемая высота слоя экструдера. Ограничивает минимальную " +"высоту слоя при адаптивной высоте слоя. Детали, печатаемые с более толстой " +"предпочитаемой высотой слоя экструдера, тоже никогда не опускаются ниже этой " +"высоты (кроме первого слоя)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Предпочитаемая высота слоя сопла %1% больше не проходит через него и была " +"сброшена на \"По умолчанию\"." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Материал основания поддержек/подложки не относится к материалу основания " +"поддержек/подложки." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Материал основания поддержек/подложки печатается соплом, не соответствующим " +"диаметру сопла поддержек." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Материал связующего слоя поддержек/подложки не относится к материалу " +"связующего слоя поддержек/подложки." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Материал связующего слоя поддержек/подложки печатается соплом, не " +"соответствующим диаметру сопла поддержек." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Материалы стенок некоторых деталей предпочитают разные высоты слоя. Внешние " +"и внутренние периметры печатаются вместе, поэтому эти стенки сохраняют " +"высоту слоя объекта. Чтобы печатать более толстые стенки, назначьте оба типа " +"стенок материалам с одинаковой предпочитаемой высотой." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Материалы стенок некоторых деталей предпочитают разные высоты слоя. Внешние " +"и внутренние периметры печатаются вместе, поэтому эти стенки печатаются " +"меньшей высотой (%1% мм)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Высота слоя стенок материала %1% подогнана с предпочитаемых %2% мм до %3% " +"мм, чтобы внешние и внутренние периметры могли печататься совместимыми " +"высотами слоя (\"Подгонять высоту слоя стенок\"). Подогнанной высотой " +"печатаются только стенки этого материала; остальные его элементы сохраняют " +"предпочитаемую." + +msgid "Thick layer regions" +msgstr "Области толстых слоёв" + +msgid "Thick layer tolerance" +msgstr "Допуск толстых слоёв" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"У этого принтера нет профиля для сопла %1% мм. Проверьте ограничения высоты " +"слоя сопла %2% в настройках принтера." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Этот принтер использует разные размеры сопла. Выберите размер сопла для " +"печати поддержек и типы материалов для подложки и связующего слоя поддержек." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Уменьшать или увеличивать высоту слоя стенок подгоняемого материала, чтобы " +"достичь высоты, совместимой с другим материалом стенок. Высоты вне " +"ограничений высоты слоя подгоняемого материала никогда не используются: если " +"в этом направлении нет допустимой высоты, стенки печатаются вместе на " +"меньшей высоте, как обычно." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Какому из двух материалов стенок подгоняется высота слоя стенок, когда " +"предпочитаемые высоты слоя не делятся нацело." + msgid "Main Extruder" msgstr "Основной экструдер" @@ -28266,13 +28792,6 @@ msgstr "" "непрерывную. Можно указать процент от ширины линии заполнения. 0 – отключить " "стыковку." -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Материал для печати разреженного заполнения.\n" -"«По умолчанию» – текущий материал модели/части." - # Придется сократить «Перекрытие линий заполнения с линиями периметра» msgid "Infill/wall overlap" msgstr "Перекрытие заполнения с периметром" @@ -28644,28 +29163,6 @@ msgstr "" "относительно её опоры. Для нависаний без опоры используется скорость печати " "мостов." -# В секции "Материал для линий" -msgid "Outer walls" -msgstr "Внешние периметры" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Материал для печати внешних периметров.\n" -"«По умолчанию» – текущий материал модели/части." - -# В секции "Материал для линий" -msgid "Inner walls" -msgstr "Внутренние периметры" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Материал для печати внутренних периметров.\n" -"«По умолчанию» – текущий материал модели/части." - msgid "This is the speed for inner walls." msgstr "" "Ограничение скорости движения головы при печати внутренних периметров " @@ -28874,27 +29371,6 @@ msgid "" msgstr "" "Заполнять целиком области внутри слоя с площадью меньше указанного значения." -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 "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29059,14 +29535,6 @@ msgstr "" "интерфейсные слои, это значение игнорируется, и поддержка печатается в " "прямом контакте с моделью (без зазора)." -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Материал для печати основной части поддержки и подложки.\n" -"«По умолчанию» – использовать материал модели." - msgid "Loop pattern interface" msgstr "Связующий слой петлями" @@ -29079,14 +29547,6 @@ msgstr "" "полилинию. По умолчанию отключено. Устаревшая функция, которая не всегда " "работает корректно." -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Материал для печати связующего слоя поддержки.\n" -"«По умолчанию» – использовать материал модели." - msgid "This is the number of top interface layers." msgstr "Количество связующих слоёв сверху" diff --git a/localization/i18n/sv/Snapmaker_Orca_sv.po b/localization/i18n/sv/Snapmaker_Orca_sv.po index 8741e667dc5..72a4e9777a4 100644 --- a/localization/i18n/sv/Snapmaker_Orca_sv.po +++ b/localization/i18n/sv/Snapmaker_Orca_sv.po @@ -19634,6 +19634,521 @@ msgstr "" "ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten " "för vridning?" +msgid "Adjust wall layer height" +msgstr "Justera väggarnas lagerhöjd" + +msgid "Adjusted walls" +msgstr "Justerade väggar" + +msgid "Adjustment direction" +msgstr "Justeringsriktning" + +msgid "Consistent" +msgstr "Konsekvent" + +msgid "Decrease" +msgstr "Minska" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut bottenytan.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut inre väggar.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut inre solid ifyllnad.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut inre sparsam ifyllnad.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut yttre väggar.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Filament för att skriva ut support och rafts. ”Standard” betyder ingen " +"specifik filament för support, och nuvarande filament används" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament för att skriva ut supportens anläggningsyta. ” Standard” betyder " +"ingen specifik filament för supportens anläggningsyta, och nuvarande " +"filament används" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Filament för att skriva ut toppytan.\n" +"\"Standard\" använder objektets/delens aktiva filament." + +msgid "Fixed" +msgstr "Fast" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Hur aggressivt delar som tilldelats en extruder med tjockare föredragen " +"lagerhöjd slås ihop till tjocka lager.\n" +"Konsekvent: delar skrivs ut med högst två lagerhöjder - extruderns lagerhöjd " +"där hela lagerserier får plats och objektets lagerhöjd överallt annars. Det " +"ger de jämnaste väggarna.\n" +"Adaptiv: serier kan också slås ihop vid mellanliggande multiplar av " +"objektets lagerhöjd, så mer av delen skrivs ut med tjockare lager, till " +"priset av band med varierande lagerhöjd på böjda kanter.\n" +"Fast: delar skrivs alltid ut med extruderns lagerhöjd, även där formen " +"ändras tvärs de ihopslagna lagren eller hänger över; böjda kanter blir " +"trappsteg och detaljer finare än de tjocka lagren går förlorade. Bara " +"geometri som är för kort för ett helt tjockt lager (delarnas toppar och " +"första lagret) skrivs ut tunnare." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Hur långt konturen av en del som tilldelats en extruder med tjockare " +"föredragen lagerhöjd får driva i sidled över lagren i en tjock serie och " +"ändå slås ihop, som procent av den extruderns nozzeldiameter. Högre värden " +"slår ihop mer av böjda kanter till tjocka lager, till priset av grövre " +"kantväggar: avvikelser upp till denna andel av nozzeldiametern sväljs av de " +"tjocka strängarna." + +msgid "Increase" +msgstr "Öka" + +msgid "Inner walls" +msgstr "Inre väggar" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Lagerhöjd som denna extruder ska skriva ut med, för skrivare vars extrudrar " +"har olika nozzelstorlekar. Den måste vara en heltalsmultipel av objektets " +"lagerhöjd. En del vars alla delar följer denna extruder skrivs bara ut på " +"vart N:e lager med motsvarande tjockare strängar, där geometrin tillåter " +"det; annars faller den tillbaka till objektets lagerhöjd. När resten av " +"delen inte kan följa med slås väggar tilldelade denna extruder ändå ihop på " +"egen hand till denna höjd, helt täta toppytor absorberar de solida lagren " +"under sig, och sparsam eller 100% tät ifyllnad slås ihop oberoende till " +"denna höjd. 0 betyder att objektets lagerhöjd används." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Lagerhöjd som denna extruder ska skriva ut med: en heltalsmultipel av " +"objektets lagerhöjd inom extruderns lagerhöjdsbegränsningar. Standard " +"behåller objektets lagerhöjd." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Ingen extruder har en nozzel som matchar stödens nozzeldiameter." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Inget laddat filament matchar materialet för stöd-/raftbasen (och stödens " +"nozzeldiameter)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Inget laddat filament matchar materialet för stöd-/raftgränssnittet (och " +"stödens nozzeldiameter)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Nozzel %1%: lagerhöjdsbegränsningar satta till %2%-%3% mm, från \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"På skrivare vars extrudrar har olika nozzeldiametrar används bara filament " +"med denna nozzeldiameter för att skriva ut stöd, raft och stödgränssnitt. " +"Det håller filament med andra nozzelstorlekar - med sina andra linjebredder " +"och lagerhöjdsbegränsningar - borta från stöden. Stödfilament som satts till " +"ett icke-standardvärde måste matcha denna diameter. Värdet 0 låter vilket " +"filament som helst skriva ut stöd." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Yttre och inre väggar skrivs automatiskt ut med sina egna föredragna " +"lagerhöjder när den ena höjden är en heltalsmultipel av den andra. När " +"höjderna inte delas jämnt justerar detta alternativ vägglagerhöjden för ett " +"av de två väggfilamenten (valt nedan) till närmaste multipel eller delare av " +"den andra, så att väggarna ändå kan delas upp. Den justerade höjden gäller " +"bara det filamentets väggar; övriga delar behåller den föredragna " +"lagerhöjden. Justeringar lämnar aldrig filamentets lagerhöjdsbegränsningar: " +"finns ingen tillåten höjd i den valda riktningen skrivs väggarna ut " +"tillsammans med den lägre höjden som vanligt." + +msgid "Outer walls" +msgstr "Yttre väggar" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "Lagerhöjder per extruder stöds inte i spiralvasläge." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "Lagerhöjder per extruder stöds inte tillsammans med gränssnittsskal." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Lagerhöjder per extruder stöds inte tillsammans med variabel lagerhöjd." + +msgid "Preferred layer height" +msgstr "Föredragen lagerhöjd" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Skriv bara ut stöd och raftbas med filament av denna materialtyp; extrudrar " +"laddade med andra typer används inte till det. Verkar tillsammans med " +"begränsningen av stödens nozzeldiameter. Lämna tomt för ingen begränsning; " +"ett uttryckligen valt stöd-/raftbasfilament har fortfarande företräde." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Skriv bara ut stöd- och raftgränssnittet med filament av denna materialtyp; " +"extrudrar laddade med andra typer används inte till det. Verkar tillsammans " +"med begränsningen av stödens nozzeldiameter. Lämna tomt för ingen " +"begränsning; ett uttryckligen valt stöd-/raftgränssnittsfilament har " +"fortfarande företräde." + +msgid "Raft and support base" +msgstr "Raft och stödbas" + +msgid "Show legacy filament selection" +msgstr "Visa gammalt filamentval" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Vissa delar föredrar %1% mm lager, men nozzeln på filament %2% som skriver " +"ut andra delar av delen är för liten för att extrudera den höjden. Dessa " +"delar skrivs istället ut med objektets lagerhöjd." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Vissa delar föredrar %1% mm lager, men nozzeln på väggfilament %2% är för " +"liten för att extrudera den höjden. Yttre och inre väggar skrivs ut " +"tillsammans, så dessa väggar behåller objektets lagerhöjd. Tilldela båda " +"väggtyperna filament med tillräckligt stora nozzlar." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Vissa delar skriver ut %1% mm lager med filament %2%, vars maximala " +"lagerhöjd är %3% mm. Tilldela delens delar filament med den grövre nozzeln, " +"höj filamentets maximala lagerhöjd eller acceptera att skriva ut över den." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Vissa delar skriver ut %1% mm lager med filament %2%, vars minsta lagerhöjd " +"är %3% mm. Höj objektets lagerhöjd, använd ett filament med finare nozzel " +"för dessa delar eller acceptera att skriva ut under extruderns minimum." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Vissa delar använder filament vars föredragna lagerhöjder inte alla kan " +"uppfyllas: en del skriver ut sina delar med ett enda lagersteg (satt av dess " +"väggfilament, eller av de andra delarnas överenskommelse när inget " +"väggfilament har någon preferens); väggarna, toppytorna och ifyllnaden kan " +"var för sig slås ihop till sin egen höjd när resten av delen inte kan följa " +"dem, men de återstående delarna skrivs ut med delens steg." + +msgid "Support for mixed nozzle sizes" +msgstr "Stöd för blandade nozzelstorlekar" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Stöd kan skrivas ut med extrudrar med olika nozzeldiametrar. Ställ in " +"stödens nozzeldiameter (eller uttryckliga stöd- och gränssnittsfilament) för " +"att hålla stöden på en nozzelstorlek." + +msgid "Support nozzle diameter" +msgstr "Stödens nozzeldiameter" + +msgid "Support nozzle size" +msgstr "Stödens nozzelstorlek" + +msgid "Support/raft base material" +msgstr "Material för stöd-/raftbas" + +msgid "Support/raft interface material" +msgstr "Material för stöd-/raftgränssnitt" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Ifyllnadens linjebredd på %1% mm är för liten för ifyllnad ihopslagen till " +"%2% mm höga lager. Öka linjebredden eller sänk ifyllnadsfilamentets " +"föredragna lagerhöjd." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Linjebredden på %1% mm är för liten för extruderns lagerhöjd på %2% mm. Öka " +"linjebredden eller sänk extruderns lagerhöjd." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Lagerhöjden för extruder %1% (%2% mm) kan inte överstiga dess nozzeldiameter." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Lagerhöjden för extruder %1% (%2% mm) ignoreras för vissa delar: den måste " +"vara en heltalsmultipel av objektets lagerhöjd (%3% mm), inte under den, och " +"får inte överstiga extruderns nozzeldiameter." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Lagerhöjden för extruder %1% (%2% mm) är mindre än objektets lagerhöjd (%3% " +"mm). Sänk objektets lagerhöjd till den finaste extruderlagerhöjden." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Lagerhöjden för extruder %1% (%2% mm) måste vara en heltalsmultipel av " +"objektets lagerhöjd (%3% mm)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Extruderns lägsta utskrivbara lagerhöjd. Begränsar minsta lagerhöjd när " +"adaptiv lagerhöjd är aktiverad. Delar som skrivs ut med en tjockare " +"föredragen extruderlagerhöjd faller heller aldrig under denna höjd (utom " +"första lagret)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Den föredragna lagerhöjden för nozzel %1% går inte längre igenom den och har " +"återställts till Standard." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "Stöd-/raftbasfilamentet är inte av stöd-/raftbasmaterialet." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Stöd-/raftbasfilamentet skrivs ut med en nozzel som inte matchar stödens " +"nozzeldiameter." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Stöd-/raftgränssnittsfilamentet är inte av stöd-/raftgränssnittsmaterialet." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Stöd-/raftgränssnittsfilamentet skrivs ut med en nozzel som inte matchar " +"stödens nozzeldiameter." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Väggfilamenten för vissa delar föredrar olika lagerhöjder. Yttre och inre " +"väggar skrivs ut tillsammans, så dessa väggar behåller objektets lagerhöjd. " +"Tilldela båda väggtyperna filament som föredrar samma höjd för att skriva ut " +"tjockare väggar." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Väggfilamenten för vissa delar föredrar olika lagerhöjder. Yttre och inre " +"väggar skrivs ut tillsammans, så dessa väggar skrivs ut med den lägre höjden " +"(%1% mm)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Vägglagerhöjden för filament %1% justerades från föredragna %2% mm till %3% " +"mm så att yttre och inre väggar kan skrivas ut med kompatibla lagerhöjder " +"(\"Justera väggarnas lagerhöjd\"). Bara detta filaments väggar skrivs ut med " +"den justerade höjden; dess övriga delar behåller den föredragna." + +msgid "Thick layer regions" +msgstr "Områden med tjocka lager" + +msgid "Thick layer tolerance" +msgstr "Tolerans för tjocka lager" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Den här skrivaren har ingen profil för en %1% mm nozzel. Kontrollera " +"lagerhöjdsbegränsningarna för nozzel %2% i skrivarinställningarna." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Den här skrivaren använder olika nozzelstorlekar. Välj nozzelstorleken som " +"skriver ut stöden och filamenttyperna som används för raften och " +"stödgränssnittet." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Om det justerade väggfilamentets vägglagerhöjd minskas eller ökas för att nå " +"en höjd som är kompatibel med det andra väggfilamentet. Höjder utanför det " +"justerade filamentets lagerhöjdsbegränsningar används aldrig: finns ingen " +"tillåten höjd i denna riktning skrivs väggarna ut tillsammans med den lägre " +"höjden som vanligt." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Vilket av de två väggfilamenten som får sin vägglagerhöjd justerad när de " +"föredragna lagerhöjderna inte delas jämnt." + # AI Translated msgid "Main Extruder" msgstr "Huvudextruder" @@ -29557,14 +30072,6 @@ msgstr "" "Om värdet sätts till 0 används den gamla algoritmen för ifyllnadsanslutning, " "som bör ge samma resultat som med 1000 och 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut inre sparsam ifyllnad.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - msgid "Infill/wall overlap" msgstr "Ifyllnad/Vägg överlapp" @@ -29934,30 +30441,6 @@ msgstr "" "hastigheter för att skriva ut. Vid 100%% överhäng, bridge/brygg hastighet " "användas." -# AI Translated -msgid "Outer walls" -msgstr "Ytterväggar" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut yttre väggar.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - -# AI Translated -msgid "Inner walls" -msgstr "Innerväggar" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut inre väggar.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - msgid "This is the speed for inner walls." msgstr "Hastighet för inre vägg" @@ -30149,30 +30632,6 @@ msgstr "" "Sparsam ifyllnads ytor som är mindre än detta gränsvärde ersätts med inre " "solid ifyllnad" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut inre solid ifyllnad.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut ovansidan.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Filament för att skriva ut undersidan.\n" -"\"Standard\" använder det aktiva objektets/delens filament." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -30342,16 +30801,6 @@ msgstr "" "botten har gränssnittslager ignoreras detta värde och supporten skrivs ut i " "direkt kontakt med objektet (utan mellanrum)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Filament för att skriva ut supportbas och raft.\n" -"”Standard” betyder ingen specifik filament för support, och nuvarande " -"filament används" - msgid "Loop pattern interface" msgstr "Loop mönstrets gränssnitt" @@ -30362,16 +30811,6 @@ msgstr "" "Täcker den övre kontaktytan av support med öglor. Den är inaktiverad som " "standard." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Filament för att skriva ut supportens anläggningsyta.\n" -"”Standard” betyder ingen specifik filament för supportens anläggningsyta, " -"och nuvarande filament används" - # AI Translated msgid "This is the number of top interface layers." msgstr "Antal övre gränssnitts lager." diff --git a/localization/i18n/th/OrcaSlicer_th.po b/localization/i18n/th/Snapmaker_Orca_th.po similarity index 100% rename from localization/i18n/th/OrcaSlicer_th.po rename to localization/i18n/th/Snapmaker_Orca_th.po diff --git a/localization/i18n/tr/Snapmaker_Orca_tr.po b/localization/i18n/tr/Snapmaker_Orca_tr.po index 00a1eb0cb2f..f32eca30c59 100644 --- a/localization/i18n/tr/Snapmaker_Orca_tr.po +++ b/localization/i18n/tr/Snapmaker_Orca_tr.po @@ -18998,6 +18998,529 @@ msgstr "" "sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını " "azaltabileceğini biliyor muydunuz?" +msgid "Adjust wall layer height" +msgstr "Duvar katman yüksekliğini ayarla" + +msgid "Adjusted walls" +msgstr "Ayarlanan duvarlar" + +msgid "Adjustment direction" +msgstr "Ayarlama yönü" + +msgid "Consistent" +msgstr "Tutarlı" + +msgid "Decrease" +msgstr "Azalt" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Alt yüzeyi basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"İç duvarları basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"İç dolu dolguyu basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"İç seyrek dolguyu basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Dış duvarları basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Destek tabanını ve salı yazdırmak için filament. \"Varsayılan\", destek için " +"belirli bir filamentin olmadığı ve mevcut filamentin kullanıldığı anlamına " +"gelir." + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Filament baskı desteği arayüzü. \"Varsayılan\", destek arayüzü için özel bir " +"filamentin olmadığı ve mevcut filamentin kullanıldığı anlamına gelir." + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Üst yüzeyi basmak için filament.\n" +"\"Varsayılan\", nesnenin/parçanın etkin filamentini kullanır." + +msgid "Fixed" +msgstr "Sabit" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Daha kalın tercih edilen katman yüksekliğine sahip ekstrudere atanmış " +"parçaların kalın katmanlara ne kadar agresif birleştirileceğini belirler.\n" +"Tutarlı: parçalar en fazla iki katman yüksekliğiyle basılır - tam katman " +"dizilerinin sığdığı yerlerde ekstruder katman yüksekliği, diğer her yerde " +"nesne katman yüksekliği. En düzgün duvarları verir.\n" +"Uyarlanabilir: diziler nesne katman yüksekliğinin ara katlarında da " +"birleştirilebilir; parçanın daha büyük kısmı kalın katmanlarla basılır ancak " +"kavisli parça sınırlarında değişen katman yüksekliği bantları oluşur.\n" +"Sabit: parçalar, şekil birleştirilen katmanlar boyunca değişse ya da sarksa " +"bile her zaman ekstruder katman yüksekliğiyle basılır; kavisli sınırlar " +"basamaklara dönüşür ve kalın katmanlardan ince ayrıntılar kaybolur. Yalnızca " +"tam bir kalın katmana yetmeyen geometri (parça tepeleri ve ilk katman) daha " +"ince basılır." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Daha kalın tercih edilen katman yüksekliğine sahip ekstrudere atanmış bir " +"parçanın dış hattının, bir kalın dizinin katmanları boyunca yana ne kadar " +"kayıp yine de birleştirilebileceğini, o ekstruderin nozul çapının yüzdesi " +"olarak belirler. Daha yüksek değerler kavisli parça sınırlarının daha " +"fazlasını kalın katmanlara birleştirir; bedeli daha pürüzlü sınır " +"duvarlarıdır: nozul çapının bu oranına kadar sapmalar kalın ekstrüzyonlar " +"tarafından yutulur." + +msgid "Increase" +msgstr "Artır" + +msgid "Inner walls" +msgstr "İç duvarlar" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Bu ekstruderin basması gereken katman yüksekliği; ekstruderlerinin nozul " +"boyutları farklı olan yazıcılar içindir. Nesne katman yüksekliğinin tam katı " +"olmalıdır. Tüm özellikleri bu ekstruderi izleyen bir parça, geometrisi izin " +"verdiği yerlerde yalnızca her N. katmanda buna uygun daha kalın " +"ekstrüzyonlarla basılır; diğer yerlerde nesne katman yüksekliğine döner. " +"Parçanın kalanı izleyemediğinde, bu ekstrudere atanmış duvarlar yine de " +"kendi başlarına bu yüksekliğe birleşir, tam yoğunluklu üst yüzeyler " +"altlarındaki dolu katmanları emer ve seyrek ya da %100 yoğun dolgu bağımsız " +"olarak bu yüksekliğe birleşir. 0, nesne katman yüksekliğini kullanmak " +"demektir." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Bu ekstruderin basması gereken katman yüksekliği: bu ekstruderin katman " +"yüksekliği sınırları içinde, nesne katman yüksekliğinin tam katı. " +"Varsayılan, nesne katman yüksekliğini korur." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Destek nozul çapıyla eşleşen nozula sahip ekstruder yok." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Yüklü filamentlerden hiçbiri destek/raft taban malzemesiyle (ve destek nozul " +"çapıyla) eşleşmiyor." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Yüklü filamentlerden hiçbiri destek/raft arayüz malzemesiyle (ve destek " +"nozul çapıyla) eşleşmiyor." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "" +"Nozul %1%: katman yüksekliği sınırları \"%4%\" üzerinden %2%-%3% mm olarak " +"ayarlandı." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"Ekstruderlerinin nozul çapları farklı olan yazıcılarda destek, raft ve " +"destek arayüzünü basmak için yalnızca bu nozul çapındaki filamentler " +"kullanılır. Bu, farklı hat genişlikleri ve katman yüksekliği sınırlarına " +"sahip diğer nozul boyutlarındaki filamentleri desteğin dışında tutar. " +"Varsayılan olmayan bir değere ayarlanmış destek filamentleri bu çapla " +"eşleşmelidir. 0 değeri her filamentin destek basmasına izin verir." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Bir yükseklik diğerinin tam katı olduğunda dış ve iç duvarlar otomatik " +"olarak kendi tercih edilen katman yükseklikleriyle basılır. Yükseklikler tam " +"bölünmediğinde bu seçenek, iki duvar filamentinden birinin (aşağıda seçilen) " +"duvar katman yüksekliğini diğerinin en yakın katına veya bölenine ayarlar; " +"böylece duvarlar yine ayrılabilir. Ayarlanan yükseklik yalnızca o filamentin " +"duvarlarına uygulanır; diğer özellikler tercih edilen katman yüksekliğini " +"korur. Ayarlamalar filamentin katman yüksekliği sınırlarının dışına asla " +"çıkmaz: seçilen yönde izin verilen bir yükseklik yoksa duvarlar her zamanki " +"gibi daha düşük yükseklikte birlikte basılır." + +msgid "Outer walls" +msgstr "Dış duvarlar" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Ekstruder başına katman yükseklikleri spiral vazo modunda desteklenmez." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Ekstruder başına katman yükseklikleri arayüz kabuklarıyla birlikte " +"desteklenmez." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Ekstruder başına katman yükseklikleri değişken katman yüksekliğiyle birlikte " +"desteklenmez." + +msgid "Preferred layer height" +msgstr "Tercih edilen katman yüksekliği" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Destek ve raft tabanını yalnızca bu malzeme türündeki filamentlerle basar; " +"başka türler yüklü ekstruderler bunun için kullanılmaz. Destek nozul çapı " +"kısıtlamasıyla birlikte çalışır. Kısıtlama olmaması için boş bırakın; açıkça " +"seçilmiş bir destek/raft taban filamenti yine önceliklidir." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Destek ve raft arayüzünü yalnızca bu malzeme türündeki filamentlerle basar; " +"başka türler yüklü ekstruderler bunun için kullanılmaz. Destek nozul çapı " +"kısıtlamasıyla birlikte çalışır. Kısıtlama olmaması için boş bırakın; açıkça " +"seçilmiş bir destek/raft arayüz filamenti yine önceliklidir." + +msgid "Raft and support base" +msgstr "Raft ve destek tabanı" + +msgid "Show legacy filament selection" +msgstr "Eski filament seçimini göster" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Bazı parçalar %1% mm katmanları tercih ediyor, ancak parçanın diğer " +"özelliklerini basan %2% filamentinin nozulu bu yüksekliği basamayacak kadar " +"küçük. Bu parçalar bunun yerine nesne katman yüksekliğiyle basılır." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Bazı parçalar %1% mm katmanları tercih ediyor, ancak duvar filamenti %2%'nin " +"nozulu bu yüksekliği basamayacak kadar küçük. Dış ve iç duvarlar birlikte " +"basıldığından bu duvarlar nesne katman yüksekliğini korur. Her iki duvar " +"özelliğini de yeterince büyük nozullu filamentlere atayın." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Bazı parçalar, maksimum katman yüksekliği %3% mm olan %2% filamentiyle %1% " +"mm katmanlar basıyor. Parça özelliklerini daha kalın nozulun filamentlerine " +"atayın, filamentin maksimum katman yüksekliğini artırın ya da üzerinde " +"basmayı kabul edin." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Bazı parçalar, minimum katman yüksekliği %3% mm olan %2% filamentiyle %1% mm " +"katmanlar basıyor. Nesne katman yüksekliğini artırın, bu özellikler için " +"daha ince nozullu bir filament kullanın ya da ekstruder minimumunun altında " +"basmayı kabul edin." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Bazı parçalar, tercih edilen katman yükseklikleri tümüyle karşılanamayan " +"filamentler kullanıyor: bir parça özelliklerini tek bir katman adımıyla " +"basar (duvar filamentleri belirler; hiçbir duvar filamentinin tercihi yoksa " +"diğer özelliklerin uzlaşması belirler); parçanın kalanı izleyemediğinde " +"duvarlar, üst yüzeyler ve dolgu her biri kendi yüksekliğine birleşebilir, " +"ancak kalan özellikler parçanın adımıyla basılır." + +msgid "Support for mixed nozzle sizes" +msgstr "Karışık nozul boyutları için destek" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Destek, farklı nozul çaplarına sahip ekstruderlerle basılabilir. Desteği tek " +"nozul boyutunda tutmak için destek nozul çapını (ya da açık destek ve arayüz " +"filamentlerini) ayarlayın." + +msgid "Support nozzle diameter" +msgstr "Destek nozul çapı" + +msgid "Support nozzle size" +msgstr "Destek nozul boyutu" + +msgid "Support/raft base material" +msgstr "Destek/raft taban malzemesi" + +msgid "Support/raft interface material" +msgstr "Destek/raft arayüz malzemesi" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mm dolgu hat genişliği, %2% mm yüksekliğe birleştirilmiş dolgu için çok " +"küçük. Hat genişliğini artırın ya da dolgu filamentinin tercih edilen katman " +"yüksekliğini düşürün." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"%1% mm hat genişliği, ekstruderinin %2% mm katman yüksekliği için çok küçük. " +"Hat genişliğini artırın ya da ekstruder katman yüksekliğini düşürün." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "Ekstruder %1%'in katman yüksekliği (%2% mm) nozul çapını aşamaz." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Ekstruder %1%'in katman yüksekliği (%2% mm) bazı parçalar için yok " +"sayılıyor: nesne katman yüksekliğinin (%3% mm) tam katı olmalı, onun altında " +"olmamalı ve ekstruderin nozul çapını aşmamalıdır." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Ekstruder %1%'in katman yüksekliği (%2% mm) nesne katman yüksekliğinden (%3% " +"mm) küçük. Nesne katman yüksekliğini en ince ekstruder katman yüksekliğine " +"düşürün." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Ekstruder %1%'in katman yüksekliği (%2% mm) nesne katman yüksekliğinin (%3% " +"mm) tam katı olmalıdır." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Ekstruderin basabileceği en düşük katman yüksekliği. Uyarlanabilir katman " +"yüksekliği etkinken minimum katman yüksekliğini sınırlamak için kullanılır. " +"Daha kalın tercih edilen ekstruder katman yüksekliğiyle basılan parçalar da " +"asla bu yüksekliğin altına düşmez (ilk katman hariç)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Nozul %1%'in tercih edilen katman yüksekliği artık içinden geçemiyor ve " +"Varsayılan'a sıfırlandı." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "Destek/raft taban filamenti, destek/raft taban malzemesinden değil." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Destek/raft taban filamenti, destek nozul çapıyla eşleşmeyen bir nozulla " +"basılıyor." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "Destek/raft arayüz filamenti, destek/raft arayüz malzemesinden değil." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Destek/raft arayüz filamenti, destek nozul çapıyla eşleşmeyen bir nozulla " +"basılıyor." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Bazı parçaların duvar filamentleri farklı katman yükseklikleri tercih " +"ediyor. Dış ve iç duvarlar birlikte basıldığından bu duvarlar nesne katman " +"yüksekliğini korur. Daha kalın duvarlar basmak için her iki duvar özelliğini " +"de aynı yüksekliği tercih eden filamentlere atayın." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Bazı parçaların duvar filamentleri farklı katman yükseklikleri tercih " +"ediyor. Dış ve iç duvarlar birlikte basıldığından bu duvarlar daha düşük " +"yükseklikle (%1% mm) basılır." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Filament %1%'in duvar katman yüksekliği, dış ve iç duvarların uyumlu katman " +"yüksekliklerinde basılabilmesi için tercih edilen %2% mm'den %3% mm'ye " +"ayarlandı (\"Duvar katman yüksekliğini ayarla\"). Ayarlanan yükseklikle " +"yalnızca bu filamentin duvarları basılır; diğer özellikleri tercih edileni " +"korur." + +msgid "Thick layer regions" +msgstr "Kalın katman bölgeleri" + +msgid "Thick layer tolerance" +msgstr "Kalın katman toleransı" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Bu yazıcının %1% mm nozul için profili yok. Lütfen yazıcı ayarlarında nozul " +"%2%'nin katman yüksekliği sınırlarını gözden geçirin." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Bu yazıcı farklı nozul boyutları kullanıyor. Desteği basacak nozul boyutunu " +"ve raft ile destek arayüzü için kullanılacak filament türlerini seçin." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Ayarlanan duvar filamentinin duvar katman yüksekliğinin, diğer duvar " +"filamentiyle uyumlu bir yüksekliğe ulaşmak için azaltılacağını mı yoksa " +"artırılacağını mı belirler. Ayarlanan filamentin katman yüksekliği " +"sınırlarının dışındaki yükseklikler asla kullanılmaz: bu yönde izin verilen " +"bir yükseklik yoksa duvarlar her zamanki gibi daha düşük yükseklikte " +"birlikte basılır." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Tercih edilen katman yükseklikleri tam bölünmediğinde iki duvar " +"filamentinden hangisinin duvar katman yüksekliğinin ayarlanacağını belirler." + # AI Translated msgid "Main Extruder" msgstr "Ana Ekstruder" @@ -28265,14 +28788,6 @@ msgstr "" "0'a ayarlanırsa dolgu bağlantısı için eski algoritma kullanılacaktır; 1000 " "ve 0 ile aynı sonucu oluşturmalıdır." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"İç seyrek dolguyu yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - msgid "Infill/wall overlap" msgstr "Dolgu/Duvar örtüşmesi" @@ -28636,30 +29151,6 @@ msgstr "" "Çizgi genişliğine göre çıkıntı yüzdesini tespit edin ve yazdırmak için " "farklı hızlar kullanın. %%100 çıkıntı için köprü hızı kullanılır." -# AI Translated -msgid "Outer walls" -msgstr "Dış duvarlar" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Dış duvarları yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - -# AI Translated -msgid "Inner walls" -msgstr "İç duvarlar" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"İç duvarları yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - msgid "This is the speed for inner walls." msgstr "İç duvarın hızı." @@ -28848,30 +29339,6 @@ msgstr "" "Eşik değerinden küçük olan seyrek dolgu alanı, yerini iç katı dolguya " "bırakmıştır." -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"İç katı dolguyu yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Üst yüzeyi yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Alt yüzeyi yazdıracak filament.\n" -"\"Varsayılan\", etkin nesne/parça filamentini kullanır." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29034,16 +29501,6 @@ msgstr "" "altta arayüz katmanları varsa bu değer yok sayılır ve destek nesneyle " "doğrudan temas halinde basılır (boşluk yok)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Destek tabanını ve salı yazdırmak için filament.\n" -"\"Varsayılan\", destek için belirli bir filamentin olmadığı ve mevcut " -"filamentin kullanıldığı anlamına gelir." - msgid "Loop pattern interface" msgstr "Arayüz kullanım döngüsü modeli" @@ -29054,16 +29511,6 @@ msgstr "" "Desteklerin üst temas katmanını ilmeklerle örtün. Varsayılan olarak devre " "dışıdır." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Destek arayüzünü yazdırmak için filament.\n" -"\"Varsayılan\", destek arayüzü için özel bir filamentin olmadığı ve mevcut " -"filamentin kullanıldığı anlamına gelir." - # AI Translated msgid "This is the number of top interface layers." msgstr "Üst arayüz katmanlarının sayısı." diff --git a/localization/i18n/uk/Snapmaker_Orca_uk.po b/localization/i18n/uk/Snapmaker_Orca_uk.po index 890fd08e6c9..c7060a4b4f9 100644 --- a/localization/i18n/uk/Snapmaker_Orca_uk.po +++ b/localization/i18n/uk/Snapmaker_Orca_uk.po @@ -19217,6 +19217,528 @@ msgstr "" "ABS, відповідне підвищення температури гарячого ліжка може зменшити " "ймовірність деформації?" +msgid "Adjust wall layer height" +msgstr "Підганяти висоту шару стінок" + +msgid "Adjusted walls" +msgstr "Підганяні стінки" + +msgid "Adjustment direction" +msgstr "Напрямок підгонки" + +msgid "Consistent" +msgstr "Однорідно" + +msgid "Decrease" +msgstr "Зменшувати" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку нижньої поверхні.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку внутрішніх стінок.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку внутрішнього суцільного заповнення.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку внутрішнього часткового заповнення.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку зовнішніх стінок.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"Філамент для друку підтримок та підкладки. «За замовчуванням» означає " +"відсутність конкретного філаменту для підтримок та використання поточного " +"філаменту" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"Філамент для друку підтримки. «За замовчуванням» означає відсутність " +"конкретного філаменту для друку підтримки, і використовується поточний " +"філамент" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"Філамент для друку верхньої поверхні.\n" +"\"За замовчуванням\" використовує активний філамент об'єкта/деталі." + +msgid "Fixed" +msgstr "Фіксовано" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"Наскільки агресивно деталі, призначені екструдеру з товщою бажаною висотою " +"шару, об'єднуються в товсті шари.\n" +"Однорідно: деталі друкуються щонайбільше двома висотами шару — висотою шару " +"екструдера там, де вміщуються цілі серії шарів, і висотою шару об'єкта " +"скрізь інде. Це дає найрівніші стінки.\n" +"Адаптивно: серії можуть об'єднуватися і на проміжних кратних висоти шару " +"об'єкта, тож більша частина деталі друкується товстими шарами — ціною смуг " +"змінної висоти шару на криволінійних межах.\n" +"Фіксовано: деталі завжди друкуються висотою шару екструдера, навіть там, де " +"форма змінюється поперек об'єднаних шарів або нависає; криволінійні межі " +"перетворюються на сходинки, а деталі дрібніші за товсті шари втрачаються. " +"Лише геометрія, закоротка для цілого товстого шару (верхівки деталей і " +"перший шар), друкується тонше." + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"Наскільки контур деталі, призначеної екструдеру з товщою бажаною висотою " +"шару, може зміщуватися вбік поперек шарів однієї товстої серії і все ж " +"об'єднуватися — у відсотках діаметра сопла цього екструдера. Більші значення " +"об'єднують більше криволінійних меж у товсті шари ціною грубіших стінок на " +"межах: відхилення до цієї частки діаметра сопла поглинаються товстими " +"лініями." + +msgid "Increase" +msgstr "Збільшувати" + +msgid "Inner walls" +msgstr "Внутрішні стінки" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"Висота шару, якою має друкувати цей екструдер; для принтерів, у яких " +"екструдери мають різні розміри сопла. Має бути цілим кратним висоти шару " +"об'єкта. Деталь, усі елементи якої слідують за цим екструдером, друкується " +"лише на кожному N-му шарі відповідно товщими лініями там, де дозволяє її " +"геометрія; в інших місцях використовується висота шару об'єкта. Коли решта " +"деталі не може слідувати, стінки, призначені цьому екструдеру, все одно " +"самостійно об'єднуються до цієї висоти, повністю щільні верхні поверхні " +"поглинають суцільні шари під собою, а заповнення (часткове чи 100% " +"щільності) об'єднується до цієї висоти незалежно. 0 — використовувати висоту " +"шару об'єкта." + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"Висота шару, якою має друкувати цей екструдер: ціле кратне висоти шару " +"об'єкта в межах обмежень висоти шару цього екструдера. За замовчуванням " +"зберігається висота шару об'єкта." + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "Жоден екструдер не має сопла, що відповідає діаметру сопла підтримок." + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "" +"Жоден завантажений філамент не відповідає матеріалу основи підтримок/" +"підкладки (і діаметру сопла підтримок)." + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "" +"Жоден завантажений філамент не відповідає матеріалу інтерфейсу підтримок/" +"підкладки (і діаметру сопла підтримок)." + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "Сопло %1%: обмеження висоти шару встановлено на %2%-%3% мм із \"%4%\"." + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"На принтерах, у яких екструдери мають різні діаметри сопла, для друку " +"підтримок, підкладки та інтерфейсу підтримок використовуються лише філаменти " +"цього діаметра сопла. Це не пускає до підтримок філаменти інших розмірів " +"сопла — з їхніми іншими ширинами ліній та обмеженнями висоти шару. Філаменти " +"підтримок, задані не за замовчуванням, мають відповідати цьому діаметру. " +"Значення 0 дозволяє друкувати підтримки будь-яким філаментом." + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"Зовнішні та внутрішні стінки автоматично друкуються своїми бажаними висотами " +"шару, коли одна висота є цілим кратним іншої. Коли висоти не діляться " +"націло, ця опція підганяє висоту шару стінок одного з двох філаментів стінок " +"(обраного нижче) до найближчого кратного або дільника іншої, щоб стінки все " +"ж могли розділитися. Підігнана висота стосується лише стінок цього " +"філаменту; решта елементів зберігають бажану висоту шару. Підгонка ніколи не " +"виходить за обмеження висоти шару філаменту: якщо в обраному напрямку немає " +"дозволеної висоти, стінки друкуються разом на меншій висоті, як звичайно." + +msgid "Outer walls" +msgstr "Зовнішні стінки" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "" +"Висоти шару для окремих екструдерів не підтримуються в режимі спіральної " +"вази." + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "" +"Висоти шару для окремих екструдерів не підтримуються разом з інтерфейсними " +"оболонками." + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "" +"Висоти шару для окремих екструдерів не підтримуються разом зі змінною " +"висотою шару." + +msgid "Preferred layer height" +msgstr "Бажана висота шару" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"Друкувати підтримки та основу підкладки лише філаментами цього типу " +"матеріалу; екструдери з іншими типами для цього не використовуються. Діє " +"разом з обмеженням діаметра сопла підтримок. Залиште порожнім, щоб не " +"обмежувати; явно обраний філамент основи підтримок/підкладки все одно має " +"пріоритет." + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"Друкувати інтерфейс підтримок і підкладки лише філаментами цього типу " +"матеріалу; екструдери з іншими типами для цього не використовуються. Діє " +"разом з обмеженням діаметра сопла підтримок. Залиште порожнім, щоб не " +"обмежувати; явно обраний філамент інтерфейсу все одно має пріоритет." + +msgid "Raft and support base" +msgstr "Підкладка та основа підтримок" + +msgid "Show legacy filament selection" +msgstr "Показати старий вибір філаменту" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"Деякі деталі віддають перевагу шарам %1% мм, але сопло філаменту %2%, що " +"друкує інші елементи деталі, замале для видавлювання такої висоти. Ці деталі " +"друкуються висотою шару об'єкта." + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"Деякі деталі віддають перевагу шарам %1% мм, але сопло філаменту стінок %2% " +"замале для видавлювання такої висоти. Зовнішні та внутрішні стінки " +"друкуються разом, тому ці стінки зберігають висоту шару об'єкта. Призначте " +"обидва типи стінок філаментам із достатньо великими соплами." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"Деякі деталі друкують шари %1% мм філаментом %2%, максимальна висота шару " +"якого %3% мм. Призначте елементи деталі філаментам грубішого сопла, збільште " +"максимальну висоту шару філаменту або погодьтеся друкувати вище за неї." + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"Деякі деталі друкують шари %1% мм філаментом %2%, мінімальна висота шару " +"якого %3% мм. Збільште висоту шару об'єкта, використайте для цих елементів " +"філамент із тоншим соплом або погодьтеся друкувати нижче мінімуму екструдера." + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"Деякі деталі використовують філаменти, чиї бажані висоти шару неможливо " +"задовольнити всі одразу: деталь друкує свої елементи одним кроком шару (який " +"задають її філаменти стінок, а якщо жоден філамент стінок не має переваги — " +"згода решти елементів); стінки, верхні поверхні та заповнення можуть " +"об'єднуватися кожен до своєї висоти, коли решта деталі не може за ними " +"слідувати, але решта елементів друкується кроком деталі." + +msgid "Support for mixed nozzle sizes" +msgstr "Підтримки за різних розмірів сопла" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"Підтримки можуть друкуватися екструдерами з різними діаметрами сопла. " +"Задайте діаметр сопла підтримок (або явні філаменти підтримок та " +"інтерфейсу), щоб тримати підтримки на одному розмірі сопла." + +msgid "Support nozzle diameter" +msgstr "Діаметр сопла підтримок" + +msgid "Support nozzle size" +msgstr "Розмір сопла підтримок" + +msgid "Support/raft base material" +msgstr "Матеріал основи підтримок/підкладки" + +msgid "Support/raft interface material" +msgstr "Матеріал інтерфейсу підтримок/підкладки" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"Ширина лінії заповнення %1% мм замала для заповнення, об'єднаного в шари " +"заввишки %2% мм. Збільште ширину лінії або зменште бажану висоту шару " +"філаменту заповнення." + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "" +"Ширина лінії %1% мм замала для висоти шару %2% мм її екструдера. Збільште " +"ширину лінії або зменште висоту шару екструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "" +"Висота шару екструдера %1% (%2% мм) не може перевищувати діаметр його сопла." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"Висота шару екструдера %1% (%2% мм) ігнорується для деяких деталей: вона має " +"бути цілим кратним висоти шару об'єкта (%3% мм), не меншою за неї і не " +"повинна перевищувати діаметр сопла екструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"Висота шару екструдера %1% (%2% мм) менша за висоту шару об'єкта (%3% мм). " +"Зменште висоту шару об'єкта до найтоншої висоти шару екструдера." + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "" +"Висота шару екструдера %1% (%2% мм) має бути цілим кратним висоти шару " +"об'єкта (%3% мм)." + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"Найменша друкована висота шару екструдера. Обмежує мінімальну висоту шару за " +"адаптивної висоти шару. Деталі, друковані товщою бажаною висотою шару " +"екструдера, також ніколи не опускаються нижче цієї висоти (крім першого " +"шару)." + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "" +"Бажана висота шару сопла %1% більше не проходить крізь нього і була скинута " +"на \"За замовчуванням\"." + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "" +"Філамент основи підтримок/підкладки не належить до матеріалу основи " +"підтримок/підкладки." + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "" +"Філамент основи підтримок/підкладки друкується соплом, що не відповідає " +"діаметру сопла підтримок." + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "" +"Філамент інтерфейсу підтримок/підкладки не належить до матеріалу інтерфейсу " +"підтримок/підкладки." + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "" +"Філамент інтерфейсу підтримок/підкладки друкується соплом, що не відповідає " +"діаметру сопла підтримок." + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"Філаменти стінок деяких деталей віддають перевагу різним висотам шару. " +"Зовнішні та внутрішні стінки друкуються разом, тому ці стінки зберігають " +"висоту шару об'єкта. Щоб друкувати товщі стінки, призначте обидва типи " +"стінок філаментам з однаковою бажаною висотою." + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"Філаменти стінок деяких деталей віддають перевагу різним висотам шару. " +"Зовнішні та внутрішні стінки друкуються разом, тому ці стінки друкуються " +"меншою висотою (%1% мм)." + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"Висоту шару стінок філаменту %1% підігнано з бажаних %2% мм до %3% мм, щоб " +"зовнішні та внутрішні стінки могли друкуватися сумісними висотами шару " +"(\"Підганяти висоту шару стінок\"). Підігнаною висотою друкуються лише " +"стінки цього філаменту; решта його елементів зберігають бажану." + +msgid "Thick layer regions" +msgstr "Області товстих шарів" + +msgid "Thick layer tolerance" +msgstr "Допуск товстих шарів" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"Цей принтер не має профілю для сопла %1% мм. Перевірте обмеження висоти шару " +"сопла %2% в налаштуваннях принтера." + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"Цей принтер використовує різні розміри сопла. Виберіть розмір сопла для " +"друку підтримок і типи філаментів для підкладки та інтерфейсу підтримок." + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"Зменшувати чи збільшувати висоту шару стінок підганяного філаменту, щоб " +"досягти висоти, сумісної з іншим філаментом стінок. Висоти поза обмеженнями " +"висоти шару підганяного філаменту ніколи не використовуються: якщо в цьому " +"напрямку немає дозволеної висоти, стінки друкуються разом на меншій висоті, " +"як звичайно." + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "" +"Якому з двох філаментів стінок підганяється висота шару стінок, коли бажані " +"висоти шару не діляться націло." + # AI Translated msgid "Main Extruder" msgstr "Основний екструдер" @@ -28549,14 +29071,6 @@ msgstr "" "Підключення заповнення, він повинен створити той же результат, що і для 1000 " "& 0." -# AI Translated -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку внутрішнього часткового заповнення.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - msgid "Infill/wall overlap" msgstr "Накладання заповнення/стінки" @@ -28936,30 +29450,6 @@ msgstr "" "друку іншу швидкість. Для 100%%-вого нависання використовується швидкість " "моста." -# AI Translated -msgid "Outer walls" -msgstr "Зовнішні стінки" - -# AI Translated -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку зовнішніх стінок.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - -# AI Translated -msgid "Inner walls" -msgstr "Внутрішні стінки" - -# AI Translated -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку внутрішніх стінок.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - msgid "This is the speed for inner walls." msgstr "Швидкість внутрішнього периметра" @@ -29145,30 +29635,6 @@ msgstr "" "Ділянки часткового заповнення, менші за порогове значення, замінюються " "внутрішнім суцільним заповненням" -# AI Translated -msgid "" -"Filament to print internal solid infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку внутрішнього суцільного заповнення.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - -# AI Translated -msgid "" -"Filament to print top surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку верхньої поверхні.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - -# AI Translated -msgid "" -"Filament to print bottom surface.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"Філамент для друку нижньої поверхні.\n" -"\"Типовий\" використовує філамент активного обʼєкта/частини." - msgid "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -29337,16 +29803,6 @@ msgstr "" "підтримки дорівнює 0 і знизу є інтерфейсні шари, це значення ігнорується, і " "підтримка друкується в прямому контакті з моделлю (без зазору)." -# AI Translated -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"Філамент для друку основи підтримок та підкладки.\n" -"«За замовчуванням» означає, що окремий філамент для підтримок не " -"використовується, а береться поточний філамент" - msgid "Loop pattern interface" msgstr "Інтерфейс використовує шаблон контуру" @@ -29356,16 +29812,6 @@ msgid "" msgstr "" "Накрийте петлями верхній контактний шар опор. Вимкнено за замовчуванням." -# AI Translated -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"Філамент для друку інтерфейсу підтримок.\n" -"«За замовчуванням» означає, що окремий філамент для інтерфейсу підтримок не " -"використовується, а береться поточний філамент" - # AI Translated msgid "This is the number of top interface layers." msgstr "Кількість верхніх інтерфейсних шарів." diff --git a/localization/i18n/vi/OrcaSlicer_vi.po b/localization/i18n/vi/Snapmaker_Orca_vi.po similarity index 100% rename from localization/i18n/vi/OrcaSlicer_vi.po rename to localization/i18n/vi/Snapmaker_Orca_vi.po diff --git a/localization/i18n/zh_CN/Snapmaker_Orca_zh_CN.po b/localization/i18n/zh_CN/Snapmaker_Orca_zh_CN.po index b117ab8f900..105a30c7d7c 100644 --- a/localization/i18n/zh_CN/Snapmaker_Orca_zh_CN.po +++ b/localization/i18n/zh_CN/Snapmaker_Orca_zh_CN.po @@ -17998,6 +17998,455 @@ msgstr "其他颜色" msgid "Multiple Color" msgstr "多色" +msgid "Adjust wall layer height" +msgstr "调整墙层高" + +msgid "Adjusted walls" +msgstr "被调整的墙" + +msgid "Adjustment direction" +msgstr "调整方向" + +msgid "Consistent" +msgstr "一致" + +msgid "Decrease" +msgstr "降低" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印底面的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印内墙的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印内部实心填充的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印内部稀疏填充的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印外墙的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"用于打印支撑基底和筏层的耗材。\n" +"“默认”表示不为支撑指定特定耗材,使用当前耗材。" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"用于打印支撑面的耗材。\n" +"“默认”表示不为支撑面指定特定耗材,使用当前耗材。" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用于打印顶面的耗材。\n" +"“默认”使用当前对象/零件的耗材。" + +msgid "Fixed" +msgstr "固定" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"决定分配给较厚首选层高挤出机的零件被合并为厚层的激进程度。\n" +"一致:零件最多以两种层高打印——在能容纳完整厚层组的位置使用挤出机层高,其余位" +"置使用对象层高。墙面最均匀。\n" +"自适应:层组还可以按对象层高的中间倍数合并,零件更多部分以厚层打印,代价是曲" +"面边界上出现层高交替的条带。\n" +"固定:零件始终以挤出机层高打印,即使形状在合并的层之间变化或悬空;曲面边界变" +"成台阶,比厚层更精细的细节会丢失。只有高度不足一个完整厚层的几何(零件顶部和" +"首层)以较薄的层打印。" + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"分配给较厚首选层高挤出机的零件轮廓在一个厚层组内允许横向偏移多少仍可合并,以" +"该挤出机喷嘴直径的百分比表示。数值越大,曲面边界被合并为厚层的比例越高,代价" +"是边界墙面更粗糙:不超过喷嘴直径该比例的偏差会被厚挤出线吞掉。" + +msgid "Increase" +msgstr "提高" + +msgid "Inner walls" +msgstr "内墙" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"该挤出机应使用的层高,用于挤出机喷嘴规格不同的打印机。必须是对象层高的整数" +"倍。若零件的所有特征都由该挤出机打印,则在几何允许处每N层打印一次并相应加厚挤" +"出;其余位置回退到对象层高。当零件其余部分无法跟随时,分配给该挤出机的墙仍会" +"单独合并到该层高,全密度顶面会吸收其下方的实心层,稀疏或100%密度的填充也会独" +"立合并到该层高。0表示使用对象层高。" + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"该挤出机应使用的层高:对象层高的整数倍,且在该挤出机的层高限制内。默认保持对" +"象层高。" + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "没有挤出机的喷嘴与支撑喷嘴直径匹配。" + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "没有已装载的耗材丝与支撑/筏层底部材料匹配(且符合支撑喷嘴直径)。" + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "没有已装载的耗材丝与支撑/筏层接触面材料匹配(且符合支撑喷嘴直径)。" + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "喷嘴%1%:层高限制已设为%2%-%3% mm,来自\"%4%\"。" + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"在挤出机喷嘴直径不同的打印机上,仅使用该喷嘴直径的耗材丝打印支撑、筏层和支撑" +"面。这样可将其他喷嘴规格的耗材丝——线宽和层高限制都不同——挡在支撑之外。设置为" +"非默认值的支撑耗材丝必须与该直径匹配。0表示允许任何耗材丝打印支撑。" + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"当一方层高是另一方的整数倍时,外墙和内墙会自动以各自的首选层高打印。当两者不" +"能整除时,此选项将其中一个墙耗材丝(在下方选择)的墙层高调整为另一方最接近的" +"倍数或约数,使墙仍能拆分。调整后的层高仅作用于该耗材丝的墙;其他特征保持首选" +"层高。调整绝不超出该耗材丝的层高限制:若所选方向上没有允许的层高,墙照常以较" +"低层高一起打印。" + +msgid "Outer walls" +msgstr "外墙" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "旋转花瓶模式不支持按挤出机设置层高。" + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "按挤出机设置层高与接触面外壳不兼容。" + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "按挤出机设置层高与可变层高不兼容。" + +msgid "Preferred layer height" +msgstr "首选层高" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"仅使用此材料类型的耗材丝打印支撑和筏层底部;装载其他类型的挤出机不用于此。与" +"支撑喷嘴直径限制叠加生效。留空表示不限制;显式选择的支撑/筏层底部耗材丝仍然优" +"先。" + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"仅使用此材料类型的耗材丝打印支撑面和筏层接触面;装载其他类型的挤出机不用于" +"此。与支撑喷嘴直径限制叠加生效。留空表示不限制;显式选择的支撑/筏层接触面耗材" +"丝仍然优先。" + +msgid "Raft and support base" +msgstr "筏层与支撑底部" + +msgid "Show legacy filament selection" +msgstr "显示旧版耗材丝选择" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"部分零件首选%1% mm层,但打印该零件其他特征的耗材丝%2%的喷嘴太小,无法挤出该层" +"高。这些零件将改用对象层高打印。" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"部分零件首选%1% mm层,但墙耗材丝%2%的喷嘴太小,无法挤出该层高。外墙和内墙一起" +"打印,因此这些墙保持对象层高。请将两种墙特征都分配给喷嘴足够大的耗材丝。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"部分零件使用耗材丝%2%打印%1% mm层,但其最大层高为%3% mm。请将零件特征分配给较" +"粗喷嘴的耗材丝,提高该耗材丝的最大层高,或接受超限打印。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"部分零件使用耗材丝%2%打印%1% mm层,但其最小层高为%3% mm。请提高对象层高,为这" +"些特征改用更细喷嘴的耗材丝,或接受低于挤出机最小值打印。" + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"部分零件所用耗材丝的首选层高无法全部满足:零件的各特征以同一层距打印(由其墙" +"耗材丝决定;若墙耗材丝无偏好,则由其余特征协商决定);当零件其余部分无法跟随" +"时,墙、顶面和填充可各自合并到自己的层高,但其余特征按零件的层距打印。" + +msgid "Support for mixed nozzle sizes" +msgstr "混合喷嘴规格的支撑" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"支撑可能会由不同喷嘴直径的挤出机打印。请设置支撑喷嘴直径(或显式指定支撑及支" +"撑面耗材丝),使支撑保持单一喷嘴规格。" + +msgid "Support nozzle diameter" +msgstr "支撑喷嘴直径" + +msgid "Support nozzle size" +msgstr "支撑喷嘴规格" + +msgid "Support/raft base material" +msgstr "支撑/筏层底部材料" + +msgid "Support/raft interface material" +msgstr "支撑/筏层接触面材料" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mm的填充线宽对于合并到%2% mm高的填充层太小。请增大线宽,或降低填充耗材丝" +"的首选层高。" + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "%1% mm的线宽对于其挤出机%2% mm的层高太小。请增大线宽或降低挤出机层高。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "挤出机%1%的层高(%2% mm)不能超过其喷嘴直径。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"挤出机%1%的层高(%2% mm)对部分零件被忽略:它必须是对象层高(%3% mm)的整数" +"倍、不低于对象层高,且不得超过该挤出机的喷嘴直径。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"挤出机%1%的层高(%2% mm)小于对象层高(%3% mm)。请将对象层高降低到最细的挤出" +"机层高。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "挤出机%1%的层高(%2% mm)必须是对象层高(%3% mm)的整数倍。" + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"该挤出机可打印的最低层高。启用自适应层高时用于限制最小层高。以较厚首选挤出机" +"层高打印的零件也绝不会回落到该层高以下(首层除外)。" + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "喷嘴%1%的首选层高已无法通过该喷嘴,已重置为默认。" + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "支撑/筏层底部耗材丝不属于支撑/筏层底部材料。" + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "支撑/筏层底部耗材丝使用的喷嘴与支撑喷嘴直径不匹配。" + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "支撑/筏层接触面耗材丝不属于支撑/筏层接触面材料。" + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "支撑/筏层接触面耗材丝使用的喷嘴与支撑喷嘴直径不匹配。" + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"部分零件的墙耗材丝首选层高不同。外墙和内墙一起打印,因此这些墙保持对象层高。" +"要打印更厚的墙,请将两种墙特征分配给首选层高相同的耗材丝。" + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"部分零件的墙耗材丝首选层高不同。外墙和内墙一起打印,因此这些墙以较低层高" +"(%1% mm)打印。" + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"耗材丝%1%的墙层高已从首选的%2% mm调整为%3% mm,使外墙和内墙能以兼容的层高打印" +"(\"调整墙层高\")。仅该耗材丝的墙使用调整后的层高;其其他特征保持首选层高。" + +msgid "Thick layer regions" +msgstr "厚层区域" + +msgid "Thick layer tolerance" +msgstr "厚层容差" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"此打印机没有%1% mm喷嘴的配置文件。请在打印机设置中检查喷嘴%2%的层高限制。" + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"此打印机使用不同的喷嘴规格。请选择打印支撑的喷嘴规格,以及筏层和支撑面使用的" +"耗材丝类型。" + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"被调整的墙耗材丝的墙层高是降低还是提高,以达到与另一墙耗材丝兼容的层高。绝不" +"使用超出被调整耗材丝层高限制的层高:若该方向上没有允许的层高,墙照常以较低层" +"高一起打印。" + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "当首选层高不能整除时,两个墙耗材丝中哪一个的墙层高被调整。" + msgid "High temperature:" msgstr "高温耗材:" @@ -26121,13 +26570,6 @@ msgstr "" "不到比此参数短的周长线段,则填充线仅在一侧连接到周长线段,并且所采用的周长线" "段的长度仅限于 infl_anchor,但不超过此参数。将此参数设置为零以禁用锚点。" -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用于打印内部稀疏填充的耗材。\n" -"“默认”使用当前对象/零件的耗材。" - msgid "Infill/wall overlap" msgstr "填充/墙 重叠" @@ -26453,26 +26895,6 @@ msgid "" msgstr "" "检测悬垂相对于线宽的百分比,并应用不同的速度打印。100%%的悬垂将使用桥接速度。" -msgid "Outer walls" -msgstr "外墙" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用于打印外墙的耗材。\n" -"“默认”使用当前对象/零件的耗材。" - -msgid "Inner walls" -msgstr "内墙" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用于打印内墙的耗材。\n" -"“默认”使用当前对象/零件的耗材。" - msgid "This is the speed for inner walls." msgstr "内圈墙打印速度" @@ -26640,27 +27062,6 @@ msgid "" "by internal solid infill." msgstr "小于这个阈值的稀疏填充区域将会被内部实心填充替代。" -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 "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -26807,14 +27208,6 @@ msgstr "" "模型与支撑底部之间的Z间隙。如果支撑顶部Z距离为0且底部有界面层,则忽略该值,支" "撑与模型直接接触打印(无间隙)。" -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"用于打印支撑基底和筏层的耗材。\n" -"“默认”表示不为支撑指定特定耗材,使用当前耗材。" - msgid "Loop pattern interface" msgstr "接触面采用圈形走线。" @@ -26823,14 +27216,6 @@ msgid "" "by default." msgstr "使用圈形走线覆盖顶部接触面。默认关闭。" -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"用于打印支撑面的耗材。\n" -"“默认”表示不为支撑面指定特定耗材,使用当前耗材。" - # AI Translated msgid "This is the number of top interface layers." msgstr "顶部接触层的层数" diff --git a/localization/i18n/zh_TW/Snapmaker_Orca_zh_TW.po b/localization/i18n/zh_TW/Snapmaker_Orca_zh_TW.po index 6a02333ba21..88be5c90274 100644 --- a/localization/i18n/zh_TW/Snapmaker_Orca_zh_TW.po +++ b/localization/i18n/zh_TW/Snapmaker_Orca_zh_TW.po @@ -17631,6 +17631,454 @@ msgstr "" "您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度\n" "可以降低翹曲的機率。" +msgid "Adjust wall layer height" +msgstr "調整牆層高" + +msgid "Adjusted walls" +msgstr "被調整的牆" + +msgid "Adjustment direction" +msgstr "調整方向" + +msgid "Consistent" +msgstr "一致" + +msgid "Decrease" +msgstr "降低" + +msgid "" +"Filament to print bottom surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印底面的線材。\n" +"「預設」會使用目前作用中的物件/零件線材。" + +msgid "" +"Filament to print inner walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印內牆的線材。\n" +"「預設」會使用目前作用中的物件/零件線材。" + +msgid "" +"Filament to print internal solid infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印內部實心填充的線材。\n" +"「預設」會使用目前作用中的物件/零件線材。" + +msgid "" +"Filament to print internal sparse infill.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印內部稀疏填充的線材。\n" +"「預設」會使用目前作用中的物件/零件線材。" + +msgid "" +"Filament to print outer walls.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印外牆的線材。\n" +"「預設」會使用目前作用中的物件/零件的線材。" + +msgid "" +"Filament to print support base and raft.\n" +"\"Default\" means no specific filament for support and current filament is " +"used." +msgstr "" +"用於列印支撐基座與筏層的線材。\n" +"「預設」表示不為支撐指定特定線材,並使用目前的線材。" + +msgid "" +"Filament to print support interface.\n" +"\"Default\" means no specific filament for support interface and current " +"filament is used." +msgstr "" +"用於列印支撐面的線材。\n" +"「預設」表示不為支撐面指定特定線材,並使用目前的線材。" + +msgid "" +"Filament to print top surface.\n" +"\"Default\" uses the active object/part filament." +msgstr "" +"用於列印頂面的線材。\n" +"「預設」使用目前作用中物件/零件的線材。" + +msgid "Fixed" +msgstr "固定" + +msgid "" +"How aggressively object parts assigned to an extruder with a thicker " +"preferred layer height are combined into thick layers.\n" +"Consistent: parts print with at most two layer heights, the extruder layer " +"height wherever whole runs of layers fit and the object layer height " +"everywhere else. This gives the most uniform walls.\n" +"Adaptive: runs may also be combined at intermediate multiples of the object " +"layer height, so more of the part prints with thicker layers, at the price " +"of bands of varying layer heights on curved part boundaries.\n" +"Fixed: parts always print at the extruder layer height, even where the shape " +"changes across the combined layers or overhangs; curved boundaries turn into " +"steps and detail finer than the thick layers is lost. Only geometry too " +"short for a whole thick layer (part tops and the first layer) prints thinner." +msgstr "" +"決定分配給較厚偏好層高擠出機的零件被合併為厚層的積極程度。\n" +"一致:零件最多以兩種層高列印——在能容納完整厚層組的位置使用擠出機層高,其餘位" +"置使用物件層高。牆面最均勻。\n" +"自適應:層組也可以按物件層高的中間倍數合併,零件更多部分以厚層列印,代價是曲" +"面邊界出現層高交替的帶狀痕跡。\n" +"固定:零件始終以擠出機層高列印,即使形狀在合併的層之間變化或懸空;曲面邊界變" +"成階梯,比厚層更精細的細節會遺失。只有高度不足一個完整厚層的幾何(零件頂部與" +"首層)以較薄的層列印。" + +msgid "" +"How far the outline of an object part assigned to an extruder with a thicker " +"preferred layer height may drift sideways across the layers of one thick run " +"and still be combined, as a percentage of that extruder's nozzle diameter. " +"Higher values combine more of curved part boundaries into thick layers, at " +"the price of rougher boundary walls: deviations up to this fraction of the " +"nozzle diameter are swallowed by the thick extrusions." +msgstr "" +"分配給較厚偏好層高擠出機的零件輪廓在一個厚層組內允許橫向偏移多少仍可合併,以" +"該擠出機噴嘴直徑的百分比表示。數值越大,曲面邊界被合併為厚層的比例越高,代價" +"是邊界牆面更粗糙:不超過噴嘴直徑該比例的偏差會被厚擠出線吞掉。" + +msgid "Increase" +msgstr "提高" + +msgid "Inner walls" +msgstr "內牆" + +#, no-c-format, no-boost-format +msgid "" +"Layer height this extruder should print with, used for printers whose " +"extruders have different nozzle sizes. It must be an integer multiple of the " +"object layer height. A part whose features all follow this extruder prints " +"only on every Nth layer with correspondingly thicker extrusions, wherever " +"its geometry allows it; elsewhere it falls back to the object layer height. " +"When the rest of the part cannot follow, walls assigned to this extruder " +"still combine to this height on their own, full-density top surfaces absorb " +"the solid layers below them, and sparse or 100% dense infill combines to " +"this height independently. 0 means to use the object layer height." +msgstr "" +"該擠出機應使用的層高,用於擠出機噴嘴規格不同的印表機。必須是物件層高的整數" +"倍。若零件的所有特徵都由該擠出機列印,則在幾何允許處每N層列印一次並相應加厚擠" +"出;其餘位置回退到物件層高。當零件其餘部分無法跟隨時,分配給該擠出機的牆仍會" +"單獨合併到該層高,全密度頂面會吸收其下方的實心層,稀疏或100%密度的填充也會獨" +"立合併到該層高。0表示使用物件層高。" + +msgid "" +"Layer height this extruder should print with: an integer multiple of the " +"object layer height within this extruder's layer height limits. Default " +"keeps the object layer height." +msgstr "" +"該擠出機應使用的層高:物件層高的整數倍,且在該擠出機的層高限制內。預設保持物" +"件層高。" + +msgid "No extruder has a nozzle matching the support nozzle diameter." +msgstr "沒有擠出機的噴嘴與支撐噴嘴直徑相符。" + +msgid "" +"No loaded filament matches the support/raft base material (and the support " +"nozzle diameter)." +msgstr "沒有已裝載的線材與支撐/筏層底部材料相符(且符合支撐噴嘴直徑)。" + +msgid "" +"No loaded filament matches the support/raft interface material (and the " +"support nozzle diameter)." +msgstr "沒有已裝載的線材與支撐/筏層接觸面材料相符(且符合支撐噴嘴直徑)。" + +#, no-c-format, boost-format +msgid "Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"." +msgstr "噴嘴%1%:層高限制已設為%2%-%3% mm,來自\"%4%\"。" + +msgid "" +"On printers whose extruders have different nozzle diameters, only filaments " +"of this nozzle diameter are used to print support, raft and support " +"interface. This keeps filaments of other nozzle sizes - with their different " +"line widths and layer height limits - out of the support. Support filaments " +"set to a non-default value must match this diameter. Value 0 allows any " +"filament to print support." +msgstr "" +"在擠出機噴嘴直徑不同的印表機上,僅使用該噴嘴直徑的線材列印支撐、筏層與支撐" +"面。這樣可將其他噴嘴規格的線材——線寬與層高限制都不同——擋在支撐之外。設定為非" +"預設值的支撐線材必須與該直徑相符。0表示允許任何線材列印支撐。" + +msgid "" +"Outer and inner walls automatically print at their own preferred layer " +"heights when one height is an integer multiple of the other. When the " +"heights do not divide evenly, this option adjusts the wall layer height of " +"one of the two wall filaments (chosen below) to the nearest multiple or " +"divisor of the other, so the walls can still split. The adjusted height only " +"applies to that filament's walls; other features keep the preferred layer " +"height. Adjustments never leave the filament's layer height limits: if no " +"allowed height exists in the chosen direction, the walls print together at " +"the lower height as usual." +msgstr "" +"當一方層高是另一方的整數倍時,外牆與內牆會自動以各自的偏好層高列印。當兩者不" +"能整除時,此選項將其中一個牆線材(在下方選擇)的牆層高調整為另一方最接近的倍" +"數或約數,使牆仍能拆分。調整後的層高僅作用於該線材的牆;其他特徵保持偏好層" +"高。調整絕不超出該線材的層高限制:若所選方向上沒有允許的層高,牆照常以較低層" +"高一起列印。" + +msgid "Outer walls" +msgstr "外牆" + +msgid "Per-extruder layer heights are not supported in spiral vase mode." +msgstr "螺旋花瓶模式不支援按擠出機設定層高。" + +msgid "" +"Per-extruder layer heights are not supported together with interface shells." +msgstr "按擠出機設定層高與接觸面外殼不相容。" + +msgid "" +"Per-extruder layer heights are not supported together with variable layer " +"height." +msgstr "按擠出機設定層高與可變層高不相容。" + +msgid "Preferred layer height" +msgstr "偏好層高" + +msgid "" +"Print the support and raft base only with filaments of this material type; " +"extruders loaded with other types are not used for it. Combines with the " +"support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft base filament still takes precedence." +msgstr "" +"僅使用此材料類型的線材列印支撐與筏層底部;裝載其他類型的擠出機不用於此。與支" +"撐噴嘴直徑限制疊加生效。留空表示不限制;明確選擇的支撐/筏層底部線材仍然優先。" + +msgid "" +"Print the support and raft interface only with filaments of this material " +"type; extruders loaded with other types are not used for it. Combines with " +"the support nozzle diameter restriction. Leave empty for no restriction; an " +"explicitly selected support/raft interface filament still takes precedence." +msgstr "" +"僅使用此材料類型的線材列印支撐面與筏層接觸面;裝載其他類型的擠出機不用於此。" +"與支撐噴嘴直徑限制疊加生效。留空表示不限制;明確選擇的支撐/筏層接觸面線材仍然" +"優先。" + +msgid "Raft and support base" +msgstr "筏層與支撐底部" + +msgid "Show legacy filament selection" +msgstr "顯示舊版線材選擇" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of filament %2% " +"printing other features of the part is too small to extrude that height. " +"These parts print with the object layer height instead." +msgstr "" +"部分零件偏好%1% mm層,但列印該零件其他特徵的線材%2%的噴嘴太小,無法擠出該層" +"高。這些零件將改用物件層高列印。" + +#, no-c-format, boost-format +msgid "" +"Some object parts prefer %1% mm layers, but the nozzle of wall filament %2% " +"is too small to extrude that height. Outer and inner walls print together, " +"so these walls keep the object layer height. Assign both wall features to " +"filaments with large enough nozzles." +msgstr "" +"部分零件偏好%1% mm層,但牆線材%2%的噴嘴太小,無法擠出該層高。外牆與內牆一起列" +"印,因此這些牆保持物件層高。請將兩種牆特徵都分配給噴嘴夠大的線材。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose maximum layer " +"height is %3% mm. Assign the part's features to filaments of the coarser " +"nozzle, raise the filament's maximum layer height, or accept printing above " +"it." +msgstr "" +"部分零件使用線材%2%列印%1% mm層,但其最大層高為%3% mm。請將零件特徵分配給較粗" +"噴嘴的線材,提高該線材的最大層高,或接受超限列印。" + +#, no-c-format, boost-format +msgid "" +"Some object parts print %1% mm layers with filament %2% whose minimum layer " +"height is %3% mm. Raise the object layer height, use a filament with a finer " +"nozzle for these features, or accept printing below the extruder's minimum." +msgstr "" +"部分零件使用線材%2%列印%1% mm層,但其最小層高為%3% mm。請提高物件層高,為這些" +"特徵改用更細噴嘴的線材,或接受低於擠出機最小值列印。" + +msgid "" +"Some object parts use filaments whose preferred layer heights cannot all be " +"honored: a part prints its features with one layer pitch (set by its wall " +"filaments, or by the other features' agreement when no wall filament has a " +"preference); the walls, the top surfaces and the infill can each combine to " +"their own height when the rest of the part cannot follow them, but the " +"remaining features print with the part's pitch." +msgstr "" +"部分零件所用線材的偏好層高無法全部滿足:零件的各特徵以同一層距列印(由其牆線" +"材決定;若牆線材無偏好,則由其餘特徵協商決定);當零件其餘部分無法跟隨時," +"牆、頂面與填充可各自合併到自己的層高,但其餘特徵按零件的層距列印。" + +msgid "Support for mixed nozzle sizes" +msgstr "混合噴嘴規格的支撐" + +msgid "" +"Support may print with extruders of differing nozzle diameters. Set the " +"support nozzle diameter (or explicit support and interface filaments) to " +"keep the support on one nozzle size." +msgstr "" +"支撐可能會由不同噴嘴直徑的擠出機列印。請設定支撐噴嘴直徑(或明確指定支撐及支" +"撐面線材),使支撐保持單一噴嘴規格。" + +msgid "Support nozzle diameter" +msgstr "支撐噴嘴直徑" + +msgid "Support nozzle size" +msgstr "支撐噴嘴規格" + +msgid "Support/raft base material" +msgstr "支撐/筏層底部材料" + +msgid "Support/raft interface material" +msgstr "支撐/筏層接觸面材料" + +#, no-c-format, boost-format +msgid "" +"The %1% mm infill line width is too small for infill combined to %2% mm high " +"layers. Increase the line width or lower the preferred layer height of the " +"infill filament." +msgstr "" +"%1% mm的填充線寬對於合併到%2% mm高的填充層太小。請增大線寬,或降低填充線材的" +"偏好層高。" + +#, no-c-format, boost-format +msgid "" +"The %1% mm line width is too small for the %2% mm layer height of its " +"extruder. Increase the line width or lower the extruder layer height." +msgstr "%1% mm的線寬對於其擠出機%2% mm的層高太小。請增大線寬或降低擠出機層高。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter." +msgstr "擠出機%1%的層高(%2% mm)不能超過其噴嘴直徑。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is ignored for some object parts: " +"it must be an integer multiple of the object layer height (%3% mm), not " +"below it, and must not exceed the extruder's nozzle diameter." +msgstr "" +"擠出機%1%的層高(%2% mm)對部分零件被忽略:它必須是物件層高(%3% mm)的整數" +"倍、不低於物件層高,且不得超過該擠出機的噴嘴直徑。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) is smaller than the object layer " +"height (%3% mm). Lower the object layer height to the finest extruder layer " +"height." +msgstr "" +"擠出機%1%的層高(%2% mm)小於物件層高(%3% mm)。請將物件層高降低到最細的擠出" +"機層高。" + +#, no-c-format, boost-format +msgid "" +"The layer height of extruder %1% (%2% mm) must be an integer multiple of the " +"object layer height (%3% mm)." +msgstr "擠出機%1%的層高(%2% mm)必須是物件層高(%3% mm)的整數倍。" + +msgid "" +"The lowest printable layer height for the extruder. Used to limit the " +"minimum layer height when enable adaptive layer height. Parts printed with a " +"thicker preferred extruder layer height never fall back below this height " +"either (the first layer excepted)." +msgstr "" +"該擠出機可列印的最低層高。啟用自適應層高時用於限制最小層高。以較厚偏好擠出機" +"層高列印的零件也絕不會回落到該層高以下(首層除外)。" + +#, no-c-format, boost-format +msgid "" +"The preferred layer height of nozzle %1% no longer fits through it and was " +"reset to Default." +msgstr "噴嘴%1%的偏好層高已無法通過該噴嘴,已重設為預設。" + +msgid "" +"The support/raft base filament is not of the support/raft base material." +msgstr "支撐/筏層底部線材不屬於支撐/筏層底部材料。" + +msgid "" +"The support/raft base filament prints with a nozzle that does not match the " +"support nozzle diameter." +msgstr "支撐/筏層底部線材使用的噴嘴與支撐噴嘴直徑不相符。" + +msgid "" +"The support/raft interface filament is not of the support/raft interface " +"material." +msgstr "支撐/筏層接觸面線材不屬於支撐/筏層接觸面材料。" + +msgid "" +"The support/raft interface filament prints with a nozzle that does not match " +"the support nozzle diameter." +msgstr "支撐/筏層接觸面線材使用的噴嘴與支撐噴嘴直徑不相符。" + +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls keep the object layer " +"height. Assign both wall features to filaments preferring the same height to " +"print thicker walls." +msgstr "" +"部分零件的牆線材偏好層高不同。外牆與內牆一起列印,因此這些牆保持物件層高。要" +"列印更厚的牆,請將兩種牆特徵分配給偏好層高相同的線材。" + +#, no-c-format, boost-format +msgid "" +"The wall filaments of some object parts prefer different layer heights. " +"Outer and inner walls print together, so these walls print with the lower " +"height (%1% mm)." +msgstr "" +"部分零件的牆線材偏好層高不同。外牆與內牆一起列印,因此這些牆以較低層高(%1% " +"mm)列印。" + +#, no-c-format, boost-format +msgid "" +"The wall layer height of filament %1% was adjusted from the preferred %2% mm " +"to %3% mm so the outer and inner walls can print at compatible layer heights " +"(\"Adjust wall layer height\"). Only this filament's walls print the " +"adjusted height; its other features keep the preferred one." +msgstr "" +"線材%1%的牆層高已從偏好的%2% mm調整為%3% mm,使外牆與內牆能以相容的層高列印" +"(\"調整牆層高\")。僅該線材的牆使用調整後的層高;其其他特徵保持偏好層高。" + +msgid "Thick layer regions" +msgstr "厚層區域" + +msgid "Thick layer tolerance" +msgstr "厚層容差" + +#, no-c-format, boost-format +msgid "" +"This printer has no profile for a %1% mm nozzle. Please review the layer " +"height limits of nozzle %2% in the printer settings." +msgstr "" +"此印表機沒有%1% mm噴嘴的設定檔。請在印表機設定中檢查噴嘴%2%的層高限制。" + +msgid "" +"This printer uses different nozzle sizes. Select the nozzle size that prints " +"the support, and the filament types used for the raft and the support " +"interface." +msgstr "" +"此印表機使用不同的噴嘴規格。請選擇列印支撐的噴嘴規格,以及筏層與支撐面使用的" +"線材類型。" + +msgid "" +"Whether the adjusted wall filament's wall layer height is decreased or " +"increased to reach a height compatible with the other wall filament. Heights " +"outside the adjusted filament's layer height limits are never used: if no " +"allowed height exists in this direction, the walls print together at the " +"lower height as usual." +msgstr "" +"被調整的牆線材的牆層高是降低還是提高,以達到與另一牆線材相容的層高。絕不使用" +"超出被調整線材層高限制的層高:若該方向上沒有允許的層高,牆照常以較低層高一起" +"列印。" + +msgid "" +"Which of the two wall filaments gets its wall layer height adjusted when the " +"preferred layer heights do not divide evenly." +msgstr "當偏好層高不能整除時,兩個牆線材中哪一個的牆層高被調整。" + # AI Translated msgid "Main Extruder" msgstr "主擠出機" @@ -25761,13 +26209,6 @@ msgstr "" "infill_anchor 限制,但不會超過此參數的設定值。若此參數設定為 0,將啟用舊版填" "充連接算法,並產生與設定為 1000 和 0 相同的結果。" -msgid "" -"Filament to print internal sparse infill.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用於列印內部稀疏填充的線材。\n" -"「預設」會使用目前作用中的物件/零件線材。" - msgid "Infill/wall overlap" msgstr "填充/牆 重疊" @@ -26091,26 +26532,6 @@ msgstr "" "偵測懸空相對於線寬的百分比,並套用不同的速度列印。100%% 的懸空將使用橋接速" "度。" -msgid "Outer walls" -msgstr "外牆" - -msgid "" -"Filament to print outer walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用於列印外牆的線材。\n" -"「預設」會使用目前作用中的物件/零件的線材。" - -msgid "Inner walls" -msgstr "內牆" - -msgid "" -"Filament to print inner walls.\n" -"\"Default\" uses the active object/part filament." -msgstr "" -"用於列印內牆的線材。\n" -"「預設」會使用目前作用中的物件/零件線材。" - msgid "This is the speed for inner walls." msgstr "內圈牆列印速度" @@ -26277,27 +26698,6 @@ msgid "" "by internal solid infill." msgstr "小於設定門檻值的稀疏填充區域將替換為內部實心填充" -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 "" "This is the speed for internal solid infill, not including the top or bottom " "surface." @@ -26444,14 +26844,6 @@ msgstr "" "模型與支撐底部之間的Z間隙。若支撐頂部Z距離為0且底部有介面層,則忽略此值,支撐" "與模型直接接觸列印(無間隙)。" -msgid "" -"Filament to print support base and raft.\n" -"\"Default\" means no specific filament for support and current filament is " -"used." -msgstr "" -"用於列印支撐基座與筏層的線材。\n" -"「預設」表示不為支撐指定特定線材,並使用目前的線材。" - msgid "Loop pattern interface" msgstr "接觸面採用圈形走線" @@ -26460,14 +26852,6 @@ msgid "" "by default." msgstr "使用圈形走線覆蓋頂部接觸面。預設關閉。" -msgid "" -"Filament to print support interface.\n" -"\"Default\" means no specific filament for support interface and current " -"filament is used." -msgstr "" -"用於列印支撐面的線材。\n" -"「預設」表示不為支撐面指定特定線材,並使用目前的線材。" - # AI Translated msgid "This is the number of top interface layers." msgstr "頂部介面層的層數" diff --git a/resources/profiles/Snapmaker.json b/resources/profiles/Snapmaker.json index ece77949c5b..eee6bd1b64a 100644 --- a/resources/profiles/Snapmaker.json +++ b/resources/profiles/Snapmaker.json @@ -1,6 +1,6 @@ { "name": "Snapmaker", - "version": "02.02.56.02", + "version": "02.02.56.03", "force_update": "0", "description": "Snapmaker configurations", "machine_model_list": [ diff --git a/resources/profiles/Snapmaker/filament/Snapmaker TPU 95A @U1.json b/resources/profiles/Snapmaker/filament/Snapmaker TPU 95A @U1.json index 9ab3640efd4..35ccba58ea3 100644 --- a/resources/profiles/Snapmaker/filament/Snapmaker TPU 95A @U1.json +++ b/resources/profiles/Snapmaker/filament/Snapmaker TPU 95A @U1.json @@ -279,7 +279,5 @@ ], "textured_plate_temp_initial_layer": [ "35" - ], - "filament_type": ["TPU"] - + ] } \ No newline at end of file diff --git a/resources/profiles/Snapmaker/process/0.25 Benchy @Snapmaker U1 (0.4 nozzle).json b/resources/profiles/Snapmaker/process/0.25 Benchy @Snapmaker U1 (0.4 nozzle).json index 9d0aec1feb0..33856cf0962 100644 --- a/resources/profiles/Snapmaker/process/0.25 Benchy @Snapmaker U1 (0.4 nozzle).json +++ b/resources/profiles/Snapmaker/process/0.25 Benchy @Snapmaker U1 (0.4 nozzle).json @@ -39,12 +39,12 @@ "infill_combination": "1", "infill_direction": "90", "gap_fill_target": "nowhere", - "line_width": "0.4", - "inner_wall_line_width": "0.5", - "internal_solid_infill_line_width": "0.5", - "outer_wall_line_width": "0.5", - "sparse_infill_line_width": "0.5", - "top_surface_line_width": "0.5", + "line_width": "100%", + "inner_wall_line_width": "125%", + "internal_solid_infill_line_width": "125%", + "outer_wall_line_width": "125%", + "sparse_infill_line_width": "125%", + "top_surface_line_width": "125%", "bottom_shell_layers": "2", "initial_layer_travel_speed": "100%", "bridge_acceleration": "3000", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1.json b/resources/profiles/Snapmaker/process/fdm_process_U1.json index 6c9935cce7b..9c75c70c9c5 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1.json @@ -12,18 +12,18 @@ "default_acceleration": "10000", "bridge_no_support": "0", "elefant_foot_compensation": "0.1", - "outer_wall_line_width": "0.42", + "outer_wall_line_width": "105%", "outer_wall_speed": "120", - "line_width": "0.45", + "line_width": "112.5%", "infill_direction": "45", "sparse_infill_density": "15%", "sparse_infill_pattern": "grid", - "initial_layer_line_width": "0.42", + "initial_layer_line_width": "105%", "initial_layer_print_height": "0.2", "initial_layer_speed": "20", "gap_infill_speed": "30", "infill_combination": "0", - "sparse_infill_line_width": "0.45", + "sparse_infill_line_width": "112.5%", "infill_wall_overlap": "15%", "sparse_infill_speed": "50", "interface_shells": "0", @@ -31,7 +31,7 @@ "reduce_infill_retraction": "0", "filename_format": "{input_filename_base}.gcode", "wall_loops": "2", - "inner_wall_line_width": "0.45", + "inner_wall_line_width": "112.5%", "inner_wall_speed": "40", "print_settings_id": "", "raft_layers": "0", @@ -39,13 +39,13 @@ "skirt_distance": "2", "skirt_height": "2", "minimum_sparse_infill_area": "0", - "internal_solid_infill_line_width": "0.45", + "internal_solid_infill_line_width": "112.5%", "internal_solid_infill_speed": "40", "spiral_mode": "0", "standby_temperature_delta": "-5", "enable_support": "0", "support_filament": "0", - "support_line_width": "0.42", + "support_line_width": "105%", "support_interface_filament": "0", "support_on_build_plate_only": "0", "support_top_z_distance": "0.15", @@ -60,7 +60,7 @@ "support_threshold_angle": "40", "support_object_xy_distance": "0.5", "detect_thin_wall": "0", - "top_surface_line_width": "0.42", + "top_surface_line_width": "105%", "top_surface_speed": "30", "travel_speed": "400", "enable_prime_tower": "0", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.06_nozzle_0.2.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.06_nozzle_0.2.json index b028d9087a0..36e972e066b 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.06_nozzle_0.2.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.06_nozzle_0.2.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "5", "top_shell_layers": "7", "bridge_flow": "1", - "line_width": "0.22", - "outer_wall_line_width": "0.22", - "initial_layer_line_width": "0.25", - "sparse_infill_line_width": "0.22", - "inner_wall_line_width": "0.22", - "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.22", - "top_surface_line_width": "0.22", + "line_width": "110%", + "outer_wall_line_width": "110%", + "initial_layer_line_width": "125%", + "sparse_infill_line_width": "110%", + "inner_wall_line_width": "110%", + "internal_solid_infill_line_width": "110%", + "support_line_width": "110%", + "top_surface_line_width": "110%", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.08_nozzle_0.2.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.08_nozzle_0.2.json index 79430d26d2d..255713a98d3 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.08_nozzle_0.2.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.08_nozzle_0.2.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "5", "top_shell_layers": "7", "bridge_flow": "1", - "line_width": "0.22", - "outer_wall_line_width": "0.22", - "initial_layer_line_width": "0.25", - "sparse_infill_line_width": "0.22", - "inner_wall_line_width": "0.22", - "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.22", - "top_surface_line_width": "0.22", + "line_width": "110%", + "outer_wall_line_width": "110%", + "initial_layer_line_width": "125%", + "sparse_infill_line_width": "110%", + "inner_wall_line_width": "110%", + "internal_solid_infill_line_width": "110%", + "support_line_width": "110%", + "top_surface_line_width": "110%", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.10_nozzle_0.2.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.10_nozzle_0.2.json index 3e47d1bf5ae..d86cafb29fa 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.10_nozzle_0.2.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.10_nozzle_0.2.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "5", "top_shell_layers": "7", "bridge_flow": "1", - "line_width": "0.22", - "outer_wall_line_width": "0.22", - "initial_layer_line_width": "0.25", - "sparse_infill_line_width": "0.22", - "inner_wall_line_width": "0.22", - "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.22", - "top_surface_line_width": "0.22", + "line_width": "110%", + "outer_wall_line_width": "110%", + "initial_layer_line_width": "125%", + "sparse_infill_line_width": "110%", + "inner_wall_line_width": "110%", + "internal_solid_infill_line_width": "110%", + "support_line_width": "110%", + "top_surface_line_width": "110%", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.12_nozzle_0.2.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.12_nozzle_0.2.json index c52683cb8f4..0a14422db8f 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.12_nozzle_0.2.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.12_nozzle_0.2.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "5", "top_shell_layers": "7", "bridge_flow": "1", - "line_width": "0.22", - "outer_wall_line_width": "0.22", - "initial_layer_line_width": "0.25", - "sparse_infill_line_width": "0.22", - "inner_wall_line_width": "0.22", - "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.22", - "top_surface_line_width": "0.22", + "line_width": "110%", + "outer_wall_line_width": "110%", + "initial_layer_line_width": "125%", + "sparse_infill_line_width": "110%", + "inner_wall_line_width": "110%", + "internal_solid_infill_line_width": "110%", + "support_line_width": "110%", + "top_surface_line_width": "110%", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.14_nozzle_0.2.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.14_nozzle_0.2.json index 57119f0f022..58a403c7361 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.14_nozzle_0.2.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.14_nozzle_0.2.json @@ -10,14 +10,14 @@ "bottom_shell_layers": "5", "top_shell_layers": "7", "bridge_flow": "1", - "line_width": "0.22", - "outer_wall_line_width": "0.22", - "initial_layer_line_width": "0.25", - "sparse_infill_line_width": "0.22", - "inner_wall_line_width": "0.22", - "internal_solid_infill_line_width": "0.22", - "support_line_width": "0.22", - "top_surface_line_width": "0.22", + "line_width": "110%", + "outer_wall_line_width": "110%", + "initial_layer_line_width": "125%", + "sparse_infill_line_width": "110%", + "inner_wall_line_width": "110%", + "internal_solid_infill_line_width": "110%", + "support_line_width": "110%", + "top_surface_line_width": "110%", "initial_layer_speed": "40", "initial_layer_infill_speed": "70", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.18_nozzle_0.6.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.18_nozzle_0.6.json index 7d10b214291..156b714e941 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.18_nozzle_0.6.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.18_nozzle_0.6.json @@ -7,14 +7,14 @@ "layer_height": "0.18", "initial_layer_print_height": "0.3", "bridge_flow": "1", - "line_width": "0.62", - "outer_wall_line_width": "0.62", - "initial_layer_line_width": "0.62", - "sparse_infill_line_width": "0.62", - "inner_wall_line_width": "0.62", - "internal_solid_infill_line_width": "0.62", - "support_line_width": "0.62", - "top_surface_line_width": "0.62", + "line_width": "103.33%", + "outer_wall_line_width": "103.33%", + "initial_layer_line_width": "103.33%", + "sparse_infill_line_width": "103.33%", + "inner_wall_line_width": "103.33%", + "internal_solid_infill_line_width": "103.33%", + "support_line_width": "103.33%", + "top_surface_line_width": "103.33%", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24.json index 89224e3a29a..66f83313ca1 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24.json @@ -6,7 +6,7 @@ "instantiation": "false", "layer_height": "0.24", "elefant_foot_compensation": "0.15", - "top_surface_line_width": "0.45", + "top_surface_line_width": "112.5%", "top_shell_thickness": "1.0", "bridge_flow": "1", "initial_layer_speed": "50", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.6.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.6.json index 12104aa0cdf..cd408b77e55 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.6.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.6.json @@ -7,14 +7,14 @@ "layer_height": "0.24", "initial_layer_print_height": "0.3", "bridge_flow": "1", - "line_width": "0.62", - "outer_wall_line_width": "0.62", - "initial_layer_line_width": "0.62", - "sparse_infill_line_width": "0.62", - "inner_wall_line_width": "0.62", - "internal_solid_infill_line_width": "0.62", - "support_line_width": "0.62", - "top_surface_line_width": "0.62", + "line_width": "103.33%", + "outer_wall_line_width": "103.33%", + "initial_layer_line_width": "103.33%", + "sparse_infill_line_width": "103.33%", + "inner_wall_line_width": "103.33%", + "internal_solid_infill_line_width": "103.33%", + "support_line_width": "103.33%", + "top_surface_line_width": "103.33%", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.8.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.8.json index 5f0b60b231a..49508e88835 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.8.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.24_nozzle_0.8.json @@ -7,14 +7,14 @@ "layer_height": "0.24", "initial_layer_print_height": "0.4", "bridge_flow": "1", - "line_width": "0.82", - "outer_wall_line_width": "0.82", - "initial_layer_line_width": "0.82", - "sparse_infill_line_width": "0.82", - "inner_wall_line_width": "0.82", - "internal_solid_infill_line_width": "0.82", - "support_line_width": "0.82", - "top_surface_line_width": "0.82", + "line_width": "102.5%", + "outer_wall_line_width": "102.5%", + "initial_layer_line_width": "102.5%", + "sparse_infill_line_width": "102.5%", + "inner_wall_line_width": "102.5%", + "internal_solid_infill_line_width": "102.5%", + "support_line_width": "102.5%", + "top_surface_line_width": "102.5%", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.28.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.28.json index 189d8d337ce..37fd4f68e0e 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.28.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.28.json @@ -6,7 +6,7 @@ "instantiation": "false", "layer_height": "0.28", "elefant_foot_compensation": "0.15", - "top_surface_line_width": "0.45", + "top_surface_line_width": "112.5%", "top_shell_thickness": "1.0", "bridge_flow": "1", "initial_layer_speed": "50", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.30_nozzle_0.6.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.30_nozzle_0.6.json index fcf87f69513..f753c702d9b 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.30_nozzle_0.6.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.30_nozzle_0.6.json @@ -7,14 +7,14 @@ "layer_height": "0.3", "initial_layer_print_height": "0.3", "bridge_flow": "1", - "line_width": "0.62", - "outer_wall_line_width": "0.62", - "initial_layer_line_width": "0.62", - "sparse_infill_line_width": "0.62", - "inner_wall_line_width": "0.62", - "internal_solid_infill_line_width": "0.62", - "support_line_width": "0.62", - "top_surface_line_width": "0.62", + "line_width": "103.33%", + "outer_wall_line_width": "103.33%", + "initial_layer_line_width": "103.33%", + "sparse_infill_line_width": "103.33%", + "inner_wall_line_width": "103.33%", + "internal_solid_infill_line_width": "103.33%", + "support_line_width": "103.33%", + "top_surface_line_width": "103.33%", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.32_nozzle_0.8.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.32_nozzle_0.8.json index 43b3dc8f9b9..37441608522 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.32_nozzle_0.8.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.32_nozzle_0.8.json @@ -7,14 +7,14 @@ "layer_height": "0.32", "initial_layer_print_height": "0.4", "bridge_flow": "1", - "line_width": "0.82", - "outer_wall_line_width": "0.82", - "initial_layer_line_width": "0.82", - "sparse_infill_line_width": "0.82", - "inner_wall_line_width": "0.82", - "internal_solid_infill_line_width": "0.82", - "support_line_width": "0.82", - "top_surface_line_width": "0.82", + "line_width": "102.5%", + "outer_wall_line_width": "102.5%", + "initial_layer_line_width": "102.5%", + "sparse_infill_line_width": "102.5%", + "inner_wall_line_width": "102.5%", + "internal_solid_infill_line_width": "102.5%", + "support_line_width": "102.5%", + "top_surface_line_width": "102.5%", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.36_nozzle_0.6.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.36_nozzle_0.6.json index 01c90927b29..61701643e2d 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.36_nozzle_0.6.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.36_nozzle_0.6.json @@ -7,14 +7,14 @@ "layer_height": "0.36", "initial_layer_print_height": "0.3", "bridge_flow": "1", - "line_width": "0.62", - "outer_wall_line_width": "0.62", - "initial_layer_line_width": "0.62", - "sparse_infill_line_width": "0.62", - "inner_wall_line_width": "0.62", - "internal_solid_infill_line_width": "0.62", - "support_line_width": "0.62", - "top_surface_line_width": "0.62", + "line_width": "103.33%", + "outer_wall_line_width": "103.33%", + "initial_layer_line_width": "103.33%", + "sparse_infill_line_width": "103.33%", + "inner_wall_line_width": "103.33%", + "internal_solid_infill_line_width": "103.33%", + "support_line_width": "103.33%", + "top_surface_line_width": "103.33%", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.40_nozzle_0.8.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.40_nozzle_0.8.json index 45bd45c8a54..3850aaf0f55 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.40_nozzle_0.8.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.40_nozzle_0.8.json @@ -7,14 +7,14 @@ "layer_height": "0.4", "initial_layer_print_height": "0.4", "bridge_flow": "1", - "line_width": "0.82", - "outer_wall_line_width": "0.82", - "initial_layer_line_width": "0.82", - "sparse_infill_line_width": "0.82", - "inner_wall_line_width": "0.82", - "internal_solid_infill_line_width": "0.82", - "support_line_width": "0.82", - "top_surface_line_width": "0.82", + "line_width": "102.5%", + "outer_wall_line_width": "102.5%", + "initial_layer_line_width": "102.5%", + "sparse_infill_line_width": "102.5%", + "inner_wall_line_width": "102.5%", + "internal_solid_infill_line_width": "102.5%", + "support_line_width": "102.5%", + "top_surface_line_width": "102.5%", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.42_nozzle_0.6.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.42_nozzle_0.6.json index 57cc629208c..91224ef8427 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.42_nozzle_0.6.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.42_nozzle_0.6.json @@ -7,14 +7,14 @@ "layer_height": "0.42", "initial_layer_print_height": "0.3", "bridge_flow": "1", - "line_width": "0.62", - "outer_wall_line_width": "0.62", - "initial_layer_line_width": "0.62", - "sparse_infill_line_width": "0.62", - "inner_wall_line_width": "0.62", - "internal_solid_infill_line_width": "0.62", - "support_line_width": "0.62", - "top_surface_line_width": "0.62", + "line_width": "103.33%", + "outer_wall_line_width": "103.33%", + "initial_layer_line_width": "103.33%", + "sparse_infill_line_width": "103.33%", + "inner_wall_line_width": "103.33%", + "internal_solid_infill_line_width": "103.33%", + "support_line_width": "103.33%", + "top_surface_line_width": "103.33%", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", "sparse_infill_speed": "100", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.48_nozzle_0.8.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.48_nozzle_0.8.json index be97fb0672b..2bb250ed9bd 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.48_nozzle_0.8.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.48_nozzle_0.8.json @@ -7,14 +7,14 @@ "layer_height": "0.48", "initial_layer_print_height": "0.4", "bridge_flow": "1", - "line_width": "0.82", - "outer_wall_line_width": "0.82", - "initial_layer_line_width": "0.82", - "sparse_infill_line_width": "0.82", - "inner_wall_line_width": "0.82", - "internal_solid_infill_line_width": "0.82", - "support_line_width": "0.82", - "top_surface_line_width": "0.82", + "line_width": "102.5%", + "outer_wall_line_width": "102.5%", + "initial_layer_line_width": "102.5%", + "sparse_infill_line_width": "102.5%", + "inner_wall_line_width": "102.5%", + "internal_solid_infill_line_width": "102.5%", + "support_line_width": "102.5%", + "top_surface_line_width": "102.5%", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_0.56_nozzle_0.8.json b/resources/profiles/Snapmaker/process/fdm_process_U1_0.56_nozzle_0.8.json index 2aed528ea3a..30225fb7bb0 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_0.56_nozzle_0.8.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_0.56_nozzle_0.8.json @@ -7,14 +7,14 @@ "layer_height": "0.56", "initial_layer_print_height": "0.4", "bridge_flow": "1", - "line_width": "0.82", - "outer_wall_line_width": "0.82", - "initial_layer_line_width": "0.82", - "sparse_infill_line_width": "0.82", - "inner_wall_line_width": "0.82", - "internal_solid_infill_line_width": "0.82", - "support_line_width": "0.82", - "top_surface_line_width": "0.82", + "line_width": "102.5%", + "outer_wall_line_width": "102.5%", + "initial_layer_line_width": "102.5%", + "sparse_infill_line_width": "102.5%", + "inner_wall_line_width": "102.5%", + "internal_solid_infill_line_width": "102.5%", + "support_line_width": "102.5%", + "top_surface_line_width": "102.5%", "top_surface_pattern": "monotonic", "initial_layer_speed": "35", "initial_layer_infill_speed": "55", diff --git a/resources/profiles/Snapmaker/process/fdm_process_U1_common.json b/resources/profiles/Snapmaker/process/fdm_process_U1_common.json index 4f9c8a34079..4dc5e352b16 100644 --- a/resources/profiles/Snapmaker/process/fdm_process_U1_common.json +++ b/resources/profiles/Snapmaker/process/fdm_process_U1_common.json @@ -16,10 +16,10 @@ "enable_arc_fitting": "1", "outer_wall_acceleration": "5000", "wall_infill_order": "inner wall/outer wall/infill", - "line_width": "0.42", + "line_width": "105%", "internal_bridge_support_thickness": "0.8", "initial_layer_acceleration": "500", - "initial_layer_line_width": "0.5", + "initial_layer_line_width": "125%", "initial_layer_speed": "30", "gap_infill_speed": "50", "sparse_infill_speed": "250", @@ -41,7 +41,7 @@ "skirt_height": "1", "skirt_loops": "0", "minimum_sparse_infill_area": "15", - "internal_solid_infill_line_width": "0.42", + "internal_solid_infill_line_width": "105%", "internal_solid_infill_speed": "150", "initial_layer_infill_speed": "60", "resolution": "0.012", diff --git a/scripts/flatpak/io.github.Snapmaker.Snapmaker_Orca.yml b/scripts/flatpak/io.github.Snapmaker.Snapmaker_Orca.yml index 5782c3838ae..943551f0555 100644 --- a/scripts/flatpak/io.github.Snapmaker.Snapmaker_Orca.yml +++ b/scripts/flatpak/io.github.Snapmaker.Snapmaker_Orca.yml @@ -2,6 +2,8 @@ app-id: io.github.Snapmaker.Snapmaker_Orca runtime: org.gnome.Platform runtime-version: "49" sdk: org.gnome.Sdk +sdk-extensions: + - org.freedesktop.Sdk.Extension.llvm21 command: entrypoint separate-locales: true rename-icon: Snapmaker_Orca @@ -21,7 +23,12 @@ finish-args: - --env=SPNAV_SOCKET=/run/spnav.sock build-options: + append-path: /usr/lib/sdk/llvm21/bin + prepend-ld-library-path: /usr/lib/sdk/llvm21/lib env: + CC: clang + CXX: clang++ + LDFLAGS: "-fuse-ld=lld" CMAKE_POLICY_VERSION_MINIMUM: "3.5" modules: @@ -41,6 +48,9 @@ modules: sha256: e305b9f07f52743ca481da0a4e0c76c35efd60adaf1b0694eb3bb021e2137e39 - name: glu + build-options: + # clang treats C++17 'register' as an error where GCC only warns + cxxflags: -Wno-register config-opts: - --disable-static sources: @@ -70,55 +80,56 @@ modules: url: https://github.com/FreeSpacenav/libspnav/releases/download/v1.2/libspnav-1.2.tar.gz sha256: 093747e7e03b232e08ff77f1ad7f48552c06ac5236316a5012db4269951c39db + # wxWidgets built as a separate module (no network at build time). + # Config-opts mirror deps/wxWidgets/wxWidgets.cmake with FLATPAK=ON, DEP_WX_GTK3=ON - name: orca_wxwidgets - buildsystem: simple - build-commands: - - | - set -euo pipefail - export CMAKE_POLICY_VERSION_MINIMUM=3.5 - mkdir builddir && cd builddir - cmake ../ -GNinja \ - -DwxBUILD_PRECOMP=ON \ - -DwxBUILD_TOOLKIT=gtk3 \ - -DwxBUILD_DEBUG_LEVEL=0 \ - -DwxBUILD_SAMPLES=OFF \ - -DwxBUILD_SHARED=ON \ - -DwxUSE_MEDIACTRL=ON \ - -DwxUSE_DETECT_SM=OFF \ - -DwxUSE_UNICODE=ON \ - -DwxUSE_PRIVATE_FONTS=ON \ - -DwxUSE_OPENGL=ON \ - -DwxUSE_WEBREQUEST=ON \ - -DwxUSE_WEBVIEW=ON \ - -DwxUSE_WEBVIEW_EDGE=OFF \ - -DwxUSE_WEBVIEW_IE=OFF \ - -DwxUSE_REGEX=builtin \ - -DwxUSE_LIBSDL=OFF \ - -DwxUSE_XTEST=OFF \ - -DwxUSE_STC=OFF \ - -DwxUSE_AUI=ON \ - -DwxUSE_LIBPNG=sys \ - -DwxUSE_ZLIB=sys \ - -DwxUSE_LIBJPEG=sys \ - -DwxUSE_LIBTIFF=OFF \ - -DwxUSE_EXPAT=sys \ - -DBUILD_SHARED_LIBS:BOOL=ON \ - -DCMAKE_INSTALL_PREFIX:STRING=/app \ - -DCMAKE_PREFIX_PATH=/app \ - -DCMAKE_BUILD_TYPE=Release \ - -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - cmake --build . --target install -j$FLATPAK_BUILDER_N_JOBS + buildsystem: cmake-ninja + build-options: + env: + CMAKE_POLICY_VERSION_MINIMUM: "3.5" + config-opts: + - -DCMAKE_BUILD_TYPE=Release + - -DwxBUILD_PRECOMP=ON + - -DwxBUILD_TOOLKIT=gtk3 + - -DCMAKE_DEBUG_POSTFIX:STRING=d + - -DwxBUILD_DEBUG_LEVEL=0 + - -DwxBUILD_SAMPLES=OFF + - -DwxBUILD_SHARED=ON + - -DBUILD_SHARED_LIBS=ON + - -DwxUSE_MEDIACTRL=ON + - -DwxUSE_DETECT_SM=OFF + - -DwxUSE_PRIVATE_FONTS=ON + - -DwxUSE_OPENGL=ON + - -DwxUSE_GLCANVAS_EGL=ON + - -DwxUSE_WEBREQUEST=ON + - -DwxUSE_WEBVIEW=ON + - -DwxUSE_WEBVIEW_EDGE=OFF + - -DwxUSE_WEBVIEW_IE=OFF + - -DwxUSE_REGEX=builtin + - -DwxUSE_LIBSDL=OFF + - -DwxUSE_XTEST=OFF + - -DwxUSE_STC=OFF + - -DwxUSE_AUI=ON + - -DwxUSE_LIBPNG=sys + - -DwxUSE_ZLIB=sys + - -DwxUSE_LIBJPEG=sys + - -DwxUSE_LIBTIFF=OFF + # sys, not builtin (unlike the static deps build): wxWidgets installs the + # builtin libwxwebp*.so only for static builds, so a shared build leaves + # them missing at runtime. The GNOME runtime provides libwebp. + - -DwxUSE_LIBWEBP=sys + - -DwxUSE_EXPAT=sys + - -DwxUSE_NANOSVG=OFF + - -DCMAKE_EXE_LINKER_FLAGS=-fuse-ld=lld + - -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=lld + - -DCMAKE_MODULE_LINKER_FLAGS=-fuse-ld=lld sources: + # Use git instead of archive: wxWidgets 3.3 relies on multiple git + # submodules (PCRE2, etc.) that are not included in GitHub tarballs. - type: git - url: https://github.com/SoftFever/Orca-deps-wxWidgets - branch: master - path: ../ - cleanup: - - "*.la" - - "*.a" - - "*.cmake" - - /include - - /app/bin/* + url: https://github.com/SoftFever/Orca-deps-wxWidgets.git + tag: orca-3.3.2 + commit: db1005db3dea2c37a46fb455a9a02e37aa360751 - name: orca_deps buildsystem: simple @@ -173,9 +184,9 @@ modules: # CGAL - type: file - url: https://github.com/CGAL/cgal/archive/refs/tags/v5.4.zip + url: https://github.com/CGAL/cgal/releases/download/v5.6.3/CGAL-5.6.3.zip dest: external-packages/CGAL - sha256: d7605e0a5a5ca17da7547592f6f6e4a59430a0bc861948974254d0de43eab4c0 + sha256: 5d577acb4a9918ccb960491482da7a3838f8d363aff47e14d703f19fd84733d4 # GMP - type: file @@ -191,7 +202,7 @@ modules: # MPFR - type: file - url: https://www.mpfr.org/mpfr-4.2.2/mpfr-4.2.2.tar.bz2 + url: https://ftp.gnu.org/gnu/mpfr/mpfr-4.2.2.tar.bz2 dest: external-packages/MPFR sha256: 9ad62c7dc910303cd384ff8f1f4767a655124980bb6d8650fe62c815a231bb7b @@ -239,9 +250,9 @@ modules: # Qhull - type: file - url: https://github.com/qhull/qhull/archive/v8.0.1.zip + url: https://github.com/qhull/qhull/archive/v8.0.2.zip dest: external-packages/Qhull - sha256: 5287f5edd6a0372588f5d6640799086a4033d89d19711023ef8229dd9301d69b + sha256: a378e9a39e718e289102c20d45632f873bfdc58a7a5f924246ea4b176e185f1e # TBB - type: file @@ -257,15 +268,78 @@ modules: # GLFW - type: file - url: https://github.com/glfw/glfw/archive/refs/tags/3.3.7.zip + url: https://github.com/glfw/glfw/archive/refs/tags/3.4.zip dest: external-packages/GLFW - sha256: e02d956935e5b9fb4abf90e2c2e07c9a0526d7eacae8ee5353484c69a2a76cd0 + sha256: a133ddc3d3c66143eba9035621db8e0bcf34dba1ee9514a9e23e96afd39fd57a # libnoise - type: file url: https://github.com/SoftFever/Orca-deps-libnoise/archive/refs/tags/1.0.zip dest: external-packages/libnoise sha256: 96ffd6cc47898dd8147aab53d7d1b1911b507d9dbaecd5613ca2649468afd8b6 + # Eigen 5.0.1 + - type: file + url: https://gitlab.com/libeigen/eigen/-/archive/5.0.1/eigen-5.0.1.zip + dest: external-packages/Eigen + sha256: 0dbb1f9e3aaad66f352c03227d8c983f6f0b49e0b07e71a7300f4abcc01aee12 + + # Draco 1.5.7 + - type: file + url: https://github.com/google/draco/archive/refs/tags/1.5.7.zip + dest: external-packages/Draco + sha256: 27b72ba2d5ff3d0a9814ad40d4cb88f8dc89a35491c0866d952473f8f9416b77 + + # Assimp 5.4.3 + - type: file + url: https://github.com/assimp/assimp/archive/refs/tags/v5.4.3.tar.gz + dest: external-packages/Assimp + sha256: 66dfbaee288f2bc43172440a55d0235dfc7bf885dda6435c038e8000e79582cb + + # FFmpeg n7.0.3 + - type: file + url: https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n7.0.3.tar.gz + dest: external-packages/FFMPEG + sha256: deedcabe339165214a3637df4c86a507aef0d793cf8774ff68735f4737e8ddbc + + # wxInspector 1.0.0 + - type: file + url: https://github.com/Noisyfox/wxInspector/archive/refs/tags/v1.0.0.zip + dest: external-packages/wxInspector + sha256: 0ba163956f2d468b19a91b96c5aba66ee9610843ea41dda628ea44cdafde7db7 + + # CPython 3.12.13 + - type: file + url: https://www.python.org/ftp/python/3.12.13/Python-3.12.13.tar.xz + dest: external-packages/python3 + sha256: c08bc65a81971c1dd5783182826503369466c7e67374d1646519adf05207b684 + + # Fallback archives for deps normally provided by the GNOME SDK; + # only used if find_package() fails to locate them. + + # ZLIB 1.2.13 + - type: file + url: https://github.com/madler/zlib/archive/refs/tags/v1.2.13.zip + dest: external-packages/ZLIB + sha256: c2856951bbf30e30861ace3765595d86ba13f2cf01279d901f6c62258c57f4ff + + # libpng 1.6.35 + - type: file + url: https://github.com/glennrp/libpng/archive/refs/tags/v1.6.35.zip + dest: external-packages/PNG + sha256: 3d22d46c566b1761a0e15ea397589b3a5f36ac09b7c785382e6470156c04247f + + # libjpeg-turbo 3.0.1 + - type: file + url: https://github.com/libjpeg-turbo/libjpeg-turbo/archive/refs/tags/3.0.1.zip + dest: external-packages/JPEG + sha256: d6d99e693366bc03897677650e8b2dfa76b5d6c54e2c9e70c03f0af821b0a52f + + # Freetype 2.12.1 + - type: file + url: https://github.com/SoftFever/orca_deps/releases/download/freetype-2.12.1.tar.gz/freetype-2.12.1.tar.gz + dest: external-packages/FREETYPE + sha256: efe71fd4b8246f1b0b1b9bfca13cfff1c9ad85930340c27df469733bbb620938 + - name: Snapmaker_Orca buildsystem: simple build-commands: diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 7f284c6ee2d..3d9292bc205 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -578,7 +578,10 @@ static ExPolygons outer_inner_brim_area(const Print& print, } support_material_extruder = object->config().support_filament; if (support_material_extruder == 0 && object->has_support_material()) { - if (print.config().print_sequence == PrintSequence::ByObject) + // ORCA: under the support nozzle diameter restriction the brim uses the support's resolved filament. + if (unsigned int resolved = object->resolved_default_support_filament(); resolved > 0) + support_material_extruder = resolved; + else if (print.config().print_sequence == PrintSequence::ByObject) support_material_extruder = objectWithExtruder.second; else support_material_extruder = printExtruders.front() + 1; diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp index e24e0f5f117..a7fec64839d 100644 --- a/src/libslic3r/Fill/Fill.cpp +++ b/src/libslic3r/Fill/Fill.cpp @@ -943,12 +943,14 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.extrusion_role = erSolidInfill; } } - if (params.extrusion_role == erTopSolidInfill) - params.extruder = region_config.top_surface_filament_id; - else if (params.extrusion_role == erBottomSurface) - params.extruder = region_config.bottom_surface_filament_id; - else if (params.extrusion_role == erSolidInfill) - params.extruder = region_config.internal_solid_filament_id; + // ORCA: per-feature filaments. Top and internal solid fills are already resolved + // by layerm.extruder(extrusion_role) above; bottom surfaces print with the bottom + // surface filament, routed through the same mixed-filament remapping as top surfaces. + // External bridges are bottom surfaces, so they print with the bottom surface filament + // too (internal bridges keep their pre-seeded filament). + if (params.extrusion_role == erBottomSurface || params.extrusion_role == erBridgeInfill) + params.extruder = effective_layer_filament_id(layer, + (unsigned int)std::max(0, region_config.bottom_surface_filament_id.value)); // 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) { @@ -1001,10 +1003,15 @@ std::vector group_fills(const Layer &layer, LockRegionParam &lock_p params.bridge = is_bridge || Fill::use_bridge_flow(params.pattern); const bool is_thick_bridge = surface.is_bridge() && (surface.is_internal_bridge() ? object_config.thick_internal_bridges : object_config.thick_bridges); params.flow = params.bridge ? - //Orca: enable thick bridge based on config - layerm.bridging_flow(extrusion_role, is_thick_bridge) : - layerm.flow(extrusion_role, (surface.thickness == -1) ? layer.height : surface.thickness); - + //Orca: enable thick bridge based on config. Combined layers stamp their full thickness on the surface; the non-thick bridge flow must be based on it. + layerm.bridging_flow(extrusion_role, is_thick_bridge, params.extruder, + (surface.thickness == -1) ? 0. : surface.thickness) : + // Width resolves against the nozzle of the filament that actually prints + // (params.extruder), which may differ from the role's default filament mapping. + layerm.flow(extrusion_role, (surface.thickness == -1) ? layer.height : surface.thickness, params.extruder); + + // Orca: record the infill speed of the effective extrusion role, resolved against the + // filament that actually prints it (params.extruder, incl. the fork's per-feature remap). params.role_speed = 0; if (params.extrusion_role == erBridgeInfill) params.role_speed = region_config.bridge_speed.get_at(layer.get_extruder_id(params.extruder)); diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp index 45157ec42df..442c8541721 100644 --- a/src/libslic3r/Fill/FillBase.cpp +++ b/src/libslic3r/Fill/FillBase.cpp @@ -313,7 +313,12 @@ std::pair Fill::_infill_direction(const Surface *surface) const // alternate fill direction //Orca: Do not alternate direction if Fill.fixed_angle is true if (!this->dont_alternate_fill_direction) { - out_angle += this->_layer_angle(this->layer_id / surface->thickness_layers); + // Combined internal groups (thickness_layers > 1) alternate per group. External + // surfaces alternate per layer even when combined: an absorbed thick top surface + // (see PrintObject::combine_top_surfaces()) must fill in the same direction as the + // same layer's uncombined remainder of that top face. + out_angle += this->_layer_angle(surface->is_external() ? this->layer_id : + this->layer_id / surface->thickness_layers); } } else { // printf("Layer_ID undefined!\n"); diff --git a/src/libslic3r/Flow.cpp b/src/libslic3r/Flow.cpp index 80912362ce1..0116dd30675 100644 --- a/src/libslic3r/Flow.cpp +++ b/src/libslic3r/Flow.cpp @@ -229,21 +229,29 @@ double Flow::mm3_per_mm() const return res; } +// Nozzle diameter driving support / raft flows. A "default" (0) filament prints with the active extruder; the support_nozzle_diameter restriction defines which nozzle that may be. +float support_material_nozzle_diameter(const PrintObject *object, int configured_filament) +{ + if (configured_filament == 0 && object->config().support_nozzle_diameter.value > 0.) + return float(object->config().support_nozzle_diameter.value); + // for configured_filament == 0 (use the current extruder), get_at returns the 0th component. + return float(object->print()->config().nozzle_diameter.get_at(configured_filament - 1)); +} + Flow support_material_flow(const PrintObject *object, float layer_height) { return Flow::new_from_config_width( frSupportMaterial, // The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution. (object->config().support_line_width.value > 0) ? object->config().support_line_width : object->config().line_width, - // if object->config().support_filament == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component. - float(object->print()->config().nozzle_diameter.get_at(object->config().support_filament-1)), + support_material_nozzle_diameter(object, object->config().support_filament), (layer_height > 0.f) ? layer_height : float(object->config().layer_height.value)); } //BBS Flow support_transition_flow(const PrintObject* object) { //BBS: support transition of tree support is bridge flow - float dmr = float(object->print()->config().nozzle_diameter.get_at(object->config().support_filament - 1)); + float dmr = support_material_nozzle_diameter(object, object->config().support_filament); return Flow::bridging_flow(dmr, dmr); } @@ -255,7 +263,7 @@ Flow support_material_1st_layer_flow(const PrintObject *object, float layer_heig frSupportMaterial, // The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution. (width.value > 0) ? width : object->config().line_width, - float(print_config.nozzle_diameter.get_at(object->config().support_filament-1)), + support_material_nozzle_diameter(object, object->config().support_filament), (layer_height > 0.f) ? layer_height : float(print_config.initial_layer_print_height.value)); } @@ -265,8 +273,7 @@ Flow support_material_interface_flow(const PrintObject *object, float layer_heig frSupportMaterialInterface, // The width parameter accepted by new_from_config_width is of type ConfigOptionFloatOrPercent, the Flow class takes care of the percent to value substitution. (object->config().support_line_width > 0) ? object->config().support_line_width : object->config().line_width, - // if object->config().support_interface_filament == 0 (which means to not trigger tool change, but use the current extruder instead), get_at will return the 0th component. - float(object->print()->config().nozzle_diameter.get_at(object->config().support_interface_filament-1)), + support_material_nozzle_diameter(object, object->config().support_interface_filament), (layer_height > 0.f) ? layer_height : float(object->config().layer_height.value)); } diff --git a/src/libslic3r/Flow.hpp b/src/libslic3r/Flow.hpp index 79cb1b324d6..a8028a9c6fa 100644 --- a/src/libslic3r/Flow.hpp +++ b/src/libslic3r/Flow.hpp @@ -139,6 +139,8 @@ class Flow bool m_bridge { false }; }; +// ORCA: nozzle driving support / raft flows: the configured filament's, or the support_nozzle_diameter restriction when the filament is left at "default" (0). +extern float support_material_nozzle_diameter(const PrintObject *object, int configured_filament); extern Flow support_material_flow(const PrintObject* object, float layer_height = 0.f); extern Flow support_transition_flow(const PrintObject *object); //BBS extern Flow support_material_1st_layer_flow(const PrintObject *object, float layer_height = 0.f); diff --git a/src/libslic3r/Format/OBJ.cpp b/src/libslic3r/Format/OBJ.cpp index e066925a981..10abe8e4dee 100644 --- a/src/libslic3r/Format/OBJ.cpp +++ b/src/libslic3r/Format/OBJ.cpp @@ -10,6 +10,7 @@ #include #include +#include #ifdef _WIN32 #define DIR_SEPARATOR '\\' diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp index 9045b0af7cd..9c73ef2179c 100644 --- a/src/libslic3r/GCode.cpp +++ b/src/libslic3r/GCode.cpp @@ -1041,7 +1041,7 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std 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("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, (int) old_filament_id, (int) gcodegen.writer().filament()->extruder_id(), gcodegen.m_layer_index))); 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)); @@ -1106,17 +1106,17 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std 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); + int old_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, old_filament_id, old_extruder_id, gcodegen.m_layer_index); + int next_nozzle_id = nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, gcodegen.m_layer_index); config.set_key_value("previous_extruder", new ConfigOptionInt(old_filament_id)); config.set_key_value("next_extruder", new ConfigOptionInt(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))); + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, old_filament_id, old_extruder_id, gcodegen.m_layer_index))); 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))); + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, new_filament_id, (int) gcodegen.get_extruder_id(new_filament_id), gcodegen.m_layer_index))); 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)); @@ -1319,7 +1319,7 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std // 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)); + nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, gcodegen.m_layer_index)); if (!custom_gcode_changes_tool(toolchange_gcode_str, gcodegen.writer().toolchange_prefix(), new_filament_id)) toolchange_gcode_str += toolchange_command; else { @@ -1393,9 +1393,9 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std 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)); + nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, gcodegen.m_layer_index)); 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)); + hotend_id_for_gcode_placeholder(gcodegen.m_config, group_result, new_filament_id, new_extruder_id, gcodegen.m_layer_index)); { 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)); @@ -1412,7 +1412,7 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std 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("current_nozzle_id", new ConfigOptionInt(nozzle_id_for_gcode_placeholder(group_result, new_filament_id, new_extruder_id, gcodegen.m_layer_index))); 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); @@ -2261,7 +2261,11 @@ static bool custom_gcode_changes_tool(const std::string& custom_gcode, const std bool ignore_sparse = false; if (gcodegen.config().wipe_tower_no_sparse_layers.value) { - ignore_sparse = (m_tool_changes[m_layer_idx].size() == 1 && m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool); + // Mirror tool_change(): the Type2 tower never skips its first layer (brim + base + // slab), even when that layer carries no toolchange. + ignore_sparse = (m_tool_changes[m_layer_idx].size() == 1 && + m_tool_changes[m_layer_idx].front().initial_tool == m_tool_changes[m_layer_idx].front().new_tool && + (gcodegen.wipe_tower_type() != WipeTowerType::Type2 || m_layer_idx != 0)); } if ((m_enable_timelapse_print || m_enable_wrapping_detection) && m_is_first_print) { @@ -2495,7 +2499,13 @@ std::vector GCode::collect_layers_to_print(const PrintObjec } extra_gap = std::max(extra_gap, object.config().raft_contact_distance.value); } - double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) + layer_to_print.layer()->height + + double layer_span = layer_to_print.layer()->height; + // ORCA: the top layer of a combined group or walls-only run prints the whole group at + // once, so tolerate a gap of its height (equals the layer height when not combined). + if (layer_to_print.object_layer != nullptr) + for (const LayerRegion *layerm : layer_to_print.object_layer->regions()) + layer_span = std::max(layer_span, layerm->wall_combined_height()); + double maximal_print_z = (last_extrusion_layer ? last_extrusion_layer->print_z() : 0.) + layer_span + std::max(0., extra_gap); // Negative support_contact_z is not taken into account, it can result in false positives in cases @@ -3228,7 +3238,11 @@ void GCode::_do_export(Print& print, GCodeOutputStream& file, ThumbnailsGenerato // How many times will be change_layer() called? // change_layer() in turn increments the progress bar status. m_layer_count = 0; - if (print.config().print_sequence == PrintSequence::ByObject) { + // A by-object print with a wipe tower is emitted by layer (see the sequential branch below), + // so it changes layer once per merged print Z like a by-layer print. + const bool count_layers_by_object = print.config().print_sequence == PrintSequence::ByObject && + !(print.has_wipe_tower() && print.tool_ordering().has_wipe_tower()); + if (count_layers_by_object) { // Add each of the object's layers separately. for (auto object : print.objects()) { std::vector zs; @@ -3511,7 +3525,28 @@ void GCode::_do_export(Print& print, GCodeOutputStream& file, ThumbnailsGenerato // Use the extruder IDs collected from Regions. this->set_extruders(print.extruders()); - has_wipe_tower = print.has_wipe_tower() && tool_ordering.has_wipe_tower(); + // With a wipe tower the layers are emitted by layer (see below) from the print-wide + // ordering the tower was planned on: the per-object ordering lacks layers that only + // other objects print (e.g. support-only layers), which would desynchronize the + // positional tower consumption, and the last object's own ordering may not even carry + // a tower although the print does. Everything the by-layer branch derives from its + // ordering (initial tool, extruder set, first filaments) has to come from that same + // ordering too, or the first layer may end on a tool the tower never planned a change + // to, or a filament only the print-wide ordering knows (custom per-layer change) has + // no extruder entry in the writer. + has_wipe_tower = print.has_wipe_tower() && print.tool_ordering().has_wipe_tower(); + if (has_wipe_tower) { + tool_ordering = print.tool_ordering(); + tool_ordering.assign_custom_gcodes(print); + initial_extruder_id = (wipe_tower_type == WipeTowerType::Type2 && !print.config().single_extruder_multi_material_priming) ? + tool_ordering.all_extruders().back() : + tool_ordering.first_extruder(); + initial_non_support_extruder_id = (unsigned int) -1; + std::fill(first_non_support_filaments.begin(), first_non_support_filaments.end(), -1); + std::fill(first_filaments.begin(), first_filaments.end(), -1); + tool_ordering.cal_non_support_filaments(print.config(), initial_non_support_extruder_id, first_non_support_filaments, first_filaments); + this->set_extruders(tool_ordering.all_extruders()); + } } else { // Find tool ordering for all the objects at once, and the initial extruder ID. // If the tool ordering has been pre-calculated by Print class for wipe tower already, reuse it. @@ -6901,12 +6936,20 @@ LayerResult GCode::process_layer( if (entity_type == GCode::ObjectByExtruder::Island::Region::INFILL) { if (layer_tools.extruder_override != 0) return layer_tools.extruder_override; - const ExtrusionRole role = entities.entities.empty() ? erNone : entities.entities.front()->role(); - if (role == erSolidInfill && std::abs(region.config().sparse_infill_density.value - 100.) < EPSILON) - return unsigned(region.config().sparse_infill_filament_id.value); + // gap fill inherits the filament of the surface it fills; derive the role from the + // first non-gap-fill entity (must match ToolOrdering::collect_extruders()). + ExtrusionRole role = erNone; + for (const ExtrusionEntity *fill_entity : entities.entities) + if (fill_entity->role() != erGapFill) { + role = fill_entity->role(); + break; + } + if (role == erNone && ! entities.entities.empty()) + // perimeter-generated gap fill with no sibling surface prints with the outer wall filament. + return unsigned(region.config().outer_wall_filament_id.value); if (role == erTopSolidInfill || role == erIroning) return unsigned(region.config().top_surface_filament_id.value); - if (role == erBottomSurface) + if (role == erBottomSurface || role == erBridgeInfill) // ORCA: external bridges print as bottom surfaces (internal bridges stay internal solid) return unsigned(region.config().bottom_surface_filament_id.value); if (is_solid_infill(role)) return unsigned(region.config().internal_solid_filament_id.value); @@ -6914,16 +6957,39 @@ LayerResult GCode::process_layer( } if (layer_tools.extruder_override != 0) return layer_tools.extruder_override; - return entities.role() == erPerimeter ? unsigned(region.config().inner_wall_filament_id.value) - : unsigned(region.config().outer_wall_filament_id.value); + bool any_outer = false, any_inner = false; + classify_wall_filaments(entities, any_outer, any_inner); + return any_inner && ! any_outer ? unsigned(region.config().inner_wall_filament_id.value) + : unsigned(region.config().outer_wall_filament_id.value); }; - // Zero based counterpart of configured_filament_id_1based(), which already folds in extruder_override. - auto configured_extruder_id = [&configured_filament_id_1based](const GCode::ObjectByExtruder::Island::Region::Type entity_type, - const ExtrusionEntityCollection& entities, - const PrintRegion& region) -> int { - const unsigned int filament_id = configured_filament_id_1based(entity_type, entities, region); - return filament_id == 0 ? 0 : int(filament_id) - 1; + auto configured_extruder_id = [&layer_tools](const GCode::ObjectByExtruder::Island::Region::Type entity_type, + const ExtrusionEntityCollection& entities, + const PrintRegion& region) -> int { + if (entity_type == GCode::ObjectByExtruder::Island::Region::INFILL) { + // gap fill inherits the filament of the surface it fills; derive the role from the + // first non-gap-fill entity (must match ToolOrdering::collect_extruders()). + ExtrusionRole role = erNone; + for (const ExtrusionEntity *fill_entity : entities.entities) + if (fill_entity->role() != erGapFill) { + role = fill_entity->role(); + break; + } + if (role == erNone && ! entities.entities.empty()) + // perimeter-generated gap fill with no sibling surface prints with the outer wall filament. + return int(layer_tools.wall_extruder_id(region)); + if (role == erTopSolidInfill || role == erIroning) + return int(layer_tools.top_surface_filament_id(region)); + if (role == erBottomSurface || role == erBridgeInfill) // ORCA: external bridges print as bottom surfaces (internal bridges stay internal solid) + return int(layer_tools.bottom_surface_filament_id(region)); + if (is_solid_infill(role)) + return int(layer_tools.internal_solid_filament_id(region)); + return int(layer_tools.sparse_infill_filament_id(region)); + } + bool any_outer = false, any_inner = false; + classify_wall_filaments(entities, any_outer, any_inner); + return any_inner && ! any_outer ? int(layer_tools.inner_wall_extruder_id(region)) + : int(layer_tools.wall_extruder_id(region)); }; auto pointillism_sequence_for_filament = [&](unsigned int filament_id_1based) -> const std::vector* { @@ -7268,6 +7334,29 @@ LayerResult GCode::process_layer( if (interface_dontcare) interface_extruder = dontcare_extruder; } + // ORCA: with support nozzle diameter / material restrictions, ("don't care") support/interface may only use a passing extruder; prefer one scheduled on this layer (as ToolOrdering did). + if (object.has_support_filament_restriction()) { + auto restrict_to_support_filaments = [&print, &object, &layer_tools](unsigned int extruder_id, bool interface_role) -> unsigned int { + if (object.support_filament_allowed(extruder_id + 1, interface_role)) + return extruder_id; + unsigned int fallback = extruder_id; + bool have_fallback = false; + for (unsigned int candidate : layer_tools.extruders) // 0 based at this point + if (object.support_filament_allowed(candidate + 1, interface_role)) { + if (! print.config().filament_soluble.get_at(candidate)) + return candidate; + if (! have_fallback) { + fallback = candidate; + have_fallback = true; + } + } + return fallback; + }; + if (support_dontcare) + support_extruder = restrict_to_support_filaments(support_extruder, false); + if (interface_dontcare) + interface_extruder = restrict_to_support_filaments(interface_extruder, true); + } // 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; @@ -7644,29 +7733,36 @@ LayerResult GCode::process_layer( } }; - bool split_mixed_perimeters = - entity_type == ObjectByExtruder::Island::Region::PERIMETERS && - region.config().outer_wall_filament_id.value != region.config().inner_wall_filament_id.value && - filtered_extrusions->role() == erMixed; + // ORCA: gate the split on the actual per-path classification: the collection + // role() is erMixed only when the loops' FIRST paths differ, missing e.g. a + // collection whose loops all start with an overhang path. + bool any_outer_wall = false, any_inner_wall = false; + if (entity_type == ObjectByExtruder::Island::Region::PERIMETERS && + region.config().outer_wall_filament_id.value != region.config().inner_wall_filament_id.value) + classify_wall_filaments(*filtered_extrusions, any_outer_wall, any_inner_wall); + const bool split_mixed_perimeters = any_outer_wall && any_inner_wall; if (split_mixed_perimeters) { auto outer_perimeters = std::make_unique(); auto inner_perimeters = std::make_unique(); for (const ExtrusionEntity* entity : filtered_extrusions->entities) { - const ExtrusionRole role = entity->role(); - if (role == erExternalPerimeter || role == erOverhangPerimeter) + // Same classification as the wall filament dispatch (LayerTools::extruder()). + if (perimeter_entity_uses_outer_wall_filament(*entity)) outer_perimeters->append(*entity); - else if (role == erPerimeter) + else inner_perimeters->append(*entity); } + // Wiping-extrusion overrides were marked (and their purge volume + // credited) against the ORIGINAL collection - look them up under that + // key so a purge planned into these perimeters still happens. if (!outer_perimeters->entities.empty()) { split_perimeter_storage.emplace_back(std::move(outer_perimeters)); - process_extrusions(split_perimeter_storage.back().get(), nullptr, false); + process_extrusions(split_perimeter_storage.back().get(), filtered_extrusions, true); } if (!inner_perimeters->entities.empty()) { split_perimeter_storage.emplace_back(std::move(inner_perimeters)); - process_extrusions(split_perimeter_storage.back().get(), nullptr, false); + process_extrusions(split_perimeter_storage.back().get(), filtered_extrusions, true); } } else { process_extrusions(filtered_extrusions, filtered_extrusions, true); @@ -8370,7 +8466,8 @@ LayerResult GCode::process_layer( } } - if (print.config().print_sequence == PrintSequence::ByLayer && m_enable_exclude_object && print.config().support_object_skip_flush.value) { + // By-layer emission (including a sequential print that falls back to it for the wipe tower). + if (single_object_instance_idx == size_t(-1) && m_enable_exclude_object && print.config().support_object_skip_flush.value) { std::set all_label_ids; for (InstanceToPrint &instance : filament_to_print_instances[extruder_id].first) all_label_ids.insert(instance.label_object_id); diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp index 4c5d5fc11e6..20990587582 100644 --- a/src/libslic3r/GCode/ToolOrdering.cpp +++ b/src/libslic3r/GCode/ToolOrdering.cpp @@ -100,23 +100,56 @@ void append_unique_preserve_order(std::vector &dst, unsigned int v dst.emplace_back(value); } -bool internal_solid_infill_uses_sparse_filament(const PrintRegion ®ion, ExtrusionRole role) +unsigned int sparse_infill_filament_id_1based(const PrintRegion ®ion) { - return role == erSolidInfill && std::abs(region.config().sparse_infill_density.value - 100.) < EPSILON; + return region.config().sparse_infill_filament_id.value; } -unsigned int sparse_infill_filament_id_1based(const PrintRegion ®ion) +} // anonymous namespace + +bool perimeter_entity_uses_outer_wall_filament(const ExtrusionEntity &entity) { - return region.config().sparse_infill_filament_id.value; + // Chaining may put an overhang path first and fully overhanging loops have no plain + // perimeter path: classify by scanning every path (must match the mixed-perimeter split + // in GCode::process_layer()). + bool has_external = false, has_internal = false; + auto classify = [&](const ExtrusionPaths &paths) { + for (const ExtrusionPath &path : paths) { + if (path.role() == erExternalPerimeter) + has_external = true; + else if (path.role() == erPerimeter) + has_internal = true; + } + }; + if (const auto *loop = dynamic_cast(&entity)) + classify(loop->paths); + else if (const auto *multi_path = dynamic_cast(&entity)) + classify(multi_path->paths); + else { + const ExtrusionRole role = entity.role(); + has_external = role == erExternalPerimeter; + has_internal = role == erPerimeter; + } + return has_external || ! has_internal; } +void classify_wall_filaments(const ExtrusionEntityCollection &collection, bool &any_outer, bool &any_inner) +{ + any_outer = any_inner = false; + for (const ExtrusionEntity *entity : collection.entities) + (perimeter_entity_uses_outer_wall_filament(*entity) ? any_outer : any_inner) = true; +} + +namespace { + +// The internal solid filament owns internal solid infill at every density - including the solid +// interior at 100% sparse density (matches mainline Orca and PrintRegion::extruder(); this fork +// used to hand the 100% interior to the sparse filament, hiding the internal solid selector). unsigned int infill_filament_id_1based(const LayerTools &layer_tools, const PrintRegion ®ion, ExtrusionRole role) { - if (internal_solid_infill_uses_sparse_filament(region, role)) - return sparse_infill_filament_id_1based(region); if (role == erTopSolidInfill || role == erIroning) return region.config().top_surface_filament_id.value; - if (role == erBottomSurface) + if (role == erBottomSurface || role == erBridgeInfill) // ORCA: external bridges print as bottom surfaces (internal bridges stay internal solid) return region.config().bottom_surface_filament_id.value; return is_solid_infill(role) ? region.config().internal_solid_filament_id.value : sparse_infill_filament_id_1based(region); } @@ -298,22 +331,38 @@ unsigned int LayerTools::extruder(const ExtrusionEntityCollection &extrusions, c assert(region.config().top_surface_filament_id.value > 0); assert(region.config().bottom_surface_filament_id.value > 0); if (extrusions.has_infill()) { - const ExtrusionRole role = extrusions.entities.empty() ? erNone : extrusions.entities.front()->role(); - if (internal_solid_infill_uses_sparse_filament(region, role)) - return sparse_infill_filament_id(region); + ExtrusionRole role = extrusions.entities.empty() ? erNone : extrusions.entities.front()->role(); + // Gap fill inherits the filament of the surface it fills; derive the role from + // the first non-gap-fill entity (must match ToolOrdering::collect_extruders()). + if (role == erGapFill) + for (const ExtrusionEntity *ee : extrusions.entities) + if (ee->role() != erGapFill) { + role = ee->role(); + break; + } if (extrusions.has_solid_infill()) { - const ExtrusionRole solid_role = extrusions.role(); + ExtrusionRole solid_role = extrusions.role(); + // Gap fill inherits the filament of the surface it fills; derive the role from + // the first non-gap-fill entity (must match ToolOrdering::collect_extruders()). + if (solid_role == erMixed) + for (const ExtrusionEntity *ee : extrusions.entities) + if (ee->role() != erGapFill) { + solid_role = ee->role(); + break; + } if (solid_role == erTopSolidInfill || solid_role == erIroning) return top_surface_filament_id(region); - if (solid_role == erBottomSurface) + if (solid_role == erBottomSurface || solid_role == erBridgeInfill) // ORCA: external bridges print as bottom surfaces (internal bridges stay internal solid) return bottom_surface_filament_id(region); return internal_solid_filament_id(region); } return sparse_infill_filament_id(region); } - // Every accessor above already applied both mixed-resolution stages and honours - // extruder_override internally, so there is nothing left to resolve here. - return extrusions.role() == erPerimeter ? inner_wall_extruder_id(region) : wall_extruder_id(region); + // Classify like the mixed-perimeter split: role() only reflects the first path of the first + // loop, which may be an overhang path of an inner loop. + bool any_outer = false, any_inner = false; + classify_wall_filaments(extrusions, any_outer, any_inner); + return any_inner && ! any_outer ? inner_wall_extruder_id(region) : wall_extruder_id(region); } static double calc_max_layer_height(const PrintConfig &config, double max_object_layer_height) @@ -576,7 +625,9 @@ bool ToolOrdering::insert_wipe_tower_extruder() bool changed = false; const unsigned int wipe_extruder = (unsigned int)(m_print_config_ptr->wipe_tower_filament - 1); for (LayerTools < : m_layer_tools) { - if (lt.wipe_tower_partitions > 0) { + // Only layers that carry a tower slab (fill_wipe_tower_partitions has run): a + // fractional support-only layer without one must not switch to the tower filament. + if (lt.wipe_tower_partitions > 0 && lt.has_wipe_tower) { if (std::find(lt.extruders.begin(), lt.extruders.end(), wipe_extruder) == lt.extruders.end()) { lt.extruders.emplace_back(wipe_extruder); changed = true; @@ -597,16 +648,21 @@ void ToolOrdering::sort_and_build_data(const Print& print, unsigned int first_ex m_sorted = true; double max_layer_height = 0.; - double object_bottom_z = 0.; + // The lowest object bottom: below it the tower needs its base (raft, support under a + // floating part); above it a lower object's fractional support layers must not be taken + // for raft layers. + double object_bottom_z = std::numeric_limits::max(); for (const auto& object : print.objects()) { for (const Layer* layer : object->layers()) { if (layer->has_extrusions()) { - object_bottom_z = layer->print_z - layer->height; + object_bottom_z = std::min(object_bottom_z, layer->print_z - layer->height); break; } } max_layer_height = std::max(max_layer_height, object->config().layer_height.value); } + if (object_bottom_z == std::numeric_limits::max()) + object_bottom_z = 0.; max_layer_height = calc_max_layer_height(print.config(), max_layer_height); @@ -672,6 +728,8 @@ ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extrude for (auto layer : object.support_layers()) zs.emplace_back(layer->print_z); this->initialize_layers(zs); + for (auto layer : object.layers()) + this->tools_for_layer(layer->print_z).on_object_grid = true; } // Collect extruders reuqired to print the layers. Add dontcare extruders @@ -723,6 +781,9 @@ ToolOrdering::ToolOrdering(const Print &print, unsigned int first_extruder, bool max_layer_height = std::max(max_layer_height, object->config().layer_height.value); } this->initialize_layers(zs); + for (auto object : print.objects()) + for (auto layer : object->layers()) + this->tools_for_layer(layer->print_z).on_object_grid = true; } max_layer_height = calc_max_layer_height(print.config(), max_layer_height); @@ -1042,42 +1103,50 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto } if (something_nonoverriddable){ - const unsigned int configured_wall = (extruder_override == 0) ? region.config().outer_wall_filament_id.value : extruder_override; - unsigned int wall_ext = resolve_mixed(configured_wall, layerCount, float(layer->print_z), float(layer->height), &object); - const unsigned int grouped_id = - grouped_manual_pattern_mixed_filament_id_for_layer(layer_tools, configured_wall); - if (grouped_id != 0) { - const std::vector ordered = - m_mixed_mgr->ordered_perimeter_extruders(grouped_id, - m_num_physical, - layerCount, - float(layer->print_z), - float(layer->height)); - if (!ordered.empty()) { - if (ordered.size() >= 2) - layer_tools.preserve_extruder_order = true; - for (unsigned int extruder_id : ordered) { - layer_tools.extruders.emplace_back(extruder_id); - if (layerCount == 0 && - std::find(firstLayerExtruders.begin(), firstLayerExtruders.end(), int(extruder_id)) == firstLayerExtruders.end()) - firstLayerExtruders.emplace_back(int(extruder_id)); + // Emplace a wall filament, expanding a grouped manual-pattern mixed filament + // into its per-layer ordered physical extruders (both walls need this so the + // wipe tower planner sees every extruder the grouped split will emit). + auto emplace_wall_filament = [&](unsigned int configured_wall, bool first_layer_candidate) { + unsigned int wall_ext = resolve_mixed(configured_wall, layerCount, float(layer->print_z), float(layer->height), &object); + const unsigned int grouped_id = + grouped_manual_pattern_mixed_filament_id_for_layer(layer_tools, configured_wall); + if (grouped_id != 0) { + const std::vector ordered = + m_mixed_mgr->ordered_perimeter_extruders(grouped_id, + m_num_physical, + layerCount, + float(layer->print_z), + float(layer->height)); + if (!ordered.empty()) { + if (ordered.size() >= 2) + layer_tools.preserve_extruder_order = true; + for (unsigned int extruder_id : ordered) { + layer_tools.extruders.emplace_back(extruder_id); + if (first_layer_candidate && layerCount == 0 && + std::find(firstLayerExtruders.begin(), firstLayerExtruders.end(), int(extruder_id)) == firstLayerExtruders.end()) + firstLayerExtruders.emplace_back(int(extruder_id)); + } + return; } - } else { - layer_tools.extruders.emplace_back(wall_ext); - if (layerCount == 0) - firstLayerExtruders.emplace_back(wall_ext); } - } else { layer_tools.extruders.emplace_back(wall_ext); - if (layerCount == 0) + if (first_layer_candidate && layerCount == 0) firstLayerExtruders.emplace_back(wall_ext); - } - if (extruder_override == 0 && region.config().wall_loops.value > 1) - layer_tools.extruders.emplace_back(resolve_mixed(region.config().inner_wall_filament_id.value, - layerCount, - float(layer->print_z), - float(layer->height), - &object)); + }; + emplace_wall_filament((extruder_override == 0) ? region.config().outer_wall_filament_id.value : extruder_override, true); + // alternate_extra_wall should add an inner loop on odd layers (mirrors + // PerimeterGenerator's loop_number and the spiral gate of + // LayerRegion::make_perimeters()); layers dropping the loop again + // (only_one_wall_top / only_one_wall_first_layer) may reserve the filament + // unused, which merely costs a toolchange. + const bool spiral_vase_layer = object.print()->config().spiral_mode.value && + layer->id() >= size_t(region.config().bottom_shell_layers.value) && + layer->print_z >= region.config().bottom_shell_thickness - EPSILON; + if (extruder_override == 0 && + (region.config().wall_loops.value > 1 || + (region.config().alternate_extra_wall.value && layer->id() % 2 == 1 && + region.config().sparse_infill_density.value > 0 && !spiral_vase_layer))) + emplace_wall_filament(region.config().inner_wall_filament_id.value, false); } layer_tools.has_object = true; @@ -1087,19 +1156,28 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto bool has_internal_solid = false; bool has_top_solid_surface = false; bool has_bottom_surface = false; + bool has_pure_gap_fill = false; bool something_nonoverriddable = false; for (const ExtrusionEntity *ee : layerm->fills.entities) { // fill represents infill extrusions of a single island. const auto *fill = dynamic_cast(ee); ExtrusionRole role = fill->entities.empty() ? erNone : fill->entities.front()->role(); - if (internal_solid_infill_uses_sparse_filament(region, role)) - has_sparse_infill = true; - else if (role == erTopSolidInfill || role == erIroning) + // gap fill inherits its surface's filament; classify by the first non-gap-fill entity (must match LayerTools::extruder()). + if (role == erGapFill) + for (const ExtrusionEntity *fill_entity : fill->entities) + if (fill_entity->role() != erGapFill) { + role = fill_entity->role(); + break; + } + if (role == erTopSolidInfill || role == erIroning) has_top_solid_surface = true; - else if (role == erBottomSurface) + else if (role == erBottomSurface || role == erBridgeInfill) // ORCA: external bridges print as bottom surfaces has_bottom_surface = true; else if (is_solid_infill(role)) has_internal_solid = true; + else if (role == erGapFill) + // perimeter-generated gap fill with no sibling surface dispatches to the outer wall filament. + has_pure_gap_fill = true; else if (role != erNone) has_sparse_infill = true; @@ -1123,7 +1201,11 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto if (has_sparse_infill) { layer_tools.extruders.emplace_back(layer_tools.sparse_infill_filament_id(region) + 1); } - } else if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_sparse_infill) { + if (has_pure_gap_fill) { + // perimeter-generated gap fill with no sibling surface uses the outer wall filament. + layer_tools.extruders.emplace_back(layer_tools.wall_extruder_id(region) + 1); + } + } else if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_sparse_infill || has_pure_gap_fill) { layer_tools.extruders.emplace_back(resolve_mixed(extruder_override, layerCount, float(layer->print_z), @@ -1131,7 +1213,7 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto &object)); } } - if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_sparse_infill) + if (has_internal_solid || has_top_solid_surface || has_bottom_surface || has_sparse_infill || has_pure_gap_fill) layer_tools.has_object = true; } @@ -1191,7 +1273,8 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto // Collect the support extruders. for (auto support_layer : object.support_layers()) { LayerTools &layer_tools = this->tools_for_layer(support_layer->print_z); - layer_tools.layer_height = support_layer->height; + if (!layer_tools.has_object) // a shared Z keeps the object layer height + layer_tools.layer_height = support_layer->height; ExtrusionRole role = support_layer->support_fills.role(); bool has_support = false; bool has_interface = false; @@ -1211,6 +1294,24 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto float(support_layer->print_z), float(support_layer->height), &object); + // support nozzle diameter / material restrictions, resolve a "default" (0) support filament to a passing one here, + // preferring a filament this layer already prints with to save toolchanges. GCode::process_layer() re-prefers + // layer-scheduled extruders for "don't care" support when the G-code is emitted. + if (object.has_support_filament_restriction()) { + auto restrict_default_filament = [&object, &layer_tools](unsigned int configured, bool interface_role) -> unsigned int { + if (configured != 0) + return configured; + const PrintConfig &print_config = object.print()->config(); + for (unsigned int filament : layer_tools.extruders) // 1 based at this point + if (filament > 0 && object.support_filament_allowed(filament, interface_role) && + ! print_config.filament_soluble.get_at(filament - 1)) + return filament; + unsigned int resolved = object.resolved_default_support_filament(interface_role); + return resolved > 0 ? resolved : configured; + }; + extruder_support = restrict_default_filament(extruder_support, false); + extruder_interface = restrict_default_filament(extruder_interface, true); + } if (has_support) { if (extruder_support > 0 || !has_interface || extruder_interface == 0 || layer_tools.has_object) layer_tools.extruders.push_back(extruder_support); @@ -1264,20 +1365,33 @@ void ToolOrdering::collect_extruders(const PrintObject &object, const std::vecto } +// The chain the tower plan and the G-code emission walk: a layer starts with the tool still +// loaded whenever it uses it (GCode::process_layer rotates the layer's extruders to it), so a +// custom or cyclic sequence never counts a phantom initial toolchange. +static std::vector rotate_extruders_to_start_with(const std::vector &extruders, unsigned int start_extruder) +{ + std::vector rotated = extruders; + auto it = std::find(rotated.begin(), rotated.end(), start_extruder); + if (it != rotated.end()) + std::rotate(rotated.begin(), it, rotated.end()); + return rotated; +} + void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_t object_bottom_z, coordf_t max_layer_height) { if (m_layer_tools.empty()) return; - // Count the minimum number of tool changes per layer. + // Count the minimum number of tool changes per layer, on the rotated chain. size_t last_extruder = size_t(-1); for (LayerTools < : m_layer_tools) { lt.wipe_tower_partitions = lt.extruders.size(); if (! lt.extruders.empty()) { - if (last_extruder == size_t(-1) || last_extruder == lt.extruders.front()) + const std::vector chain = rotate_extruders_to_start_with(lt.extruders, (unsigned int) last_extruder); + if (last_extruder == size_t(-1) || last_extruder == chain.front()) // The first extruder on this layer is equal to the current one, no need to do an initial tool change. -- lt.wipe_tower_partitions; - last_extruder = lt.extruders.back(); + last_extruder = chain.back(); } } @@ -1286,17 +1400,49 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ m_layer_tools[i].wipe_tower_partitions = std::max(m_layer_tools[i + 1].wipe_tower_partitions, m_layer_tools[i].wipe_tower_partitions); - int wrapping_layer_nums = config.wrapping_detection_layers; - for (size_t i = 0; i < wrapping_layer_nums; ++i) { - if (i >= m_layer_tools.size()) - break; - LayerTools < = m_layer_tools[i]; + // Fractional independent support heights place support-only layers between the object + // grid Zs. Those layers get no tower layer of their own: the tower would have to print + // a sub-minimum slab there, and the toolchange they carry switches TO the support + // filament, which tolerates an unpurged nozzle (the residue lands in the support). + // The switch back to an object filament happens on an object-grid layer with a full + // tower slab; the tower re-syncs its loaded tool per layer. Smooth timelapse needs a + // tower layer on every print layer and single-extruder multi-material needs the + // tower's ramming for every change, so both keep the old behavior. + auto off_grid_gates = [&config]() { + return config.enable_prime_tower && + config.independent_support_layer_height && + config.support_layer_height_step != slhsWholeLayer && + config.timelapse_type != TimelapseType::tlSmooth && + !config.single_extruder_multi_material; + }; + auto support_only_off_grid = [&off_grid_gates](const LayerTools <) { + return lt.has_support && !lt.has_object && !lt.on_object_grid && off_grid_gates(); + }; + // Only fractional Zs are ever left without a tower slab: support-only layers there and + // support layers that ended up without extrusions (the ladder continues above the + // support tops). Object grid layers (even empty ones) keep theirs, so the slabs that + // remain are whole grid steps. + auto tower_skippable = [&off_grid_gates](const LayerTools <) { + return !lt.has_object && !lt.on_object_grid && (lt.has_support || lt.extruders.empty()) && off_grid_gates(); + }; + + // The first wrapping_detection_layers slabs; a fractional entry never carries a slab and + // does not consume one of them. + const int wrapping_layer_nums = config.wrapping_detection_layers; + for (size_t i = 0, marked = 0; i < m_layer_tools.size() && int(marked) < wrapping_layer_nums; ++i) { + LayerTools < = m_layer_tools[i]; + if (tower_skippable(lt)) + continue; lt.has_wipe_tower = config.enable_wrapping_detection; + ++marked; } //FIXME this is a hack to get the ball rolling. for (LayerTools < : m_layer_tools) - lt.has_wipe_tower |= ((lt.has_object || lt.has_support) && (config.timelapse_type == TimelapseType::tlSmooth || lt.wipe_tower_partitions > 0)) + lt.has_wipe_tower |= ((lt.has_object || lt.has_support) && !support_only_off_grid(lt) && + (config.timelapse_type == TimelapseType::tlSmooth || lt.wipe_tower_partitions > 0)) + // Below the object bottom (raft layers, support under a floating part) the tower + // always needs its base, fractional support Zs included. || lt.print_z < object_bottom_z + EPSILON; // Test for a raft, insert additional wipe tower layer to fill in the raft separation gap. @@ -1365,6 +1511,22 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ } for (int i = first_wt_idx + 1; i < last_wt_idx; ++i) { LayerTools < = m_layer_tools[i]; + if (tower_skippable(lt) && !lt.has_wipe_tower) { + // Prefer no tower slab on a fractional support-only (or empty) layer, but + // only when the slab bridging over it stays within the maximum layer + // height - otherwise this layer keeps its (thin) tower slab. + coordf_t prev_z = m_layer_tools[first_wt_idx].print_z; + for (int j = i - 1; j >= first_wt_idx; --j) + if (m_layer_tools[j].has_wipe_tower) { prev_z = m_layer_tools[j].print_z; break; } + coordf_t next_z = m_layer_tools[last_wt_idx].print_z; + for (int j = i + 1; j <= last_wt_idx; ++j) + if (m_layer_tools[j].has_wipe_tower || !tower_skippable(m_layer_tools[j])) { + next_z = m_layer_tools[j].print_z; + break; + } + if (next_z - prev_z <= max_layer_height + EPSILON) + continue; + } lt.has_wipe_tower = true; // GCode::process_layer emits wipe-tower G-code inside `for (extruder_id : layer_tools.extruders)`. // An empty extruders vector here would silently skip wipe tower output, leaving the tower @@ -1420,24 +1582,50 @@ void ToolOrdering::fill_wipe_tower_partitions(const PrintConfig &config, coordf_ // and maybe other problems. We will therefore go through layer_tools and detect and fix this. // So, if there is a non-object layer starting with different extruder than the last one ended with (or containing more than one extruder), // we'll mark it with has_wipe tower. + // Per-extruder layer height combines layers away, leaving many LayerTools empty; skip them and + // compare against the last printing layer. Without the feature keep the historic behavior of + // stopping at the first empty layer. + const bool skip_empty_layer_tools = has_extruder_layer_heights(config); + const LayerTools *lt_last_printing = nullptr; + // The tool loaded after the last printing layer, on the rotated chain. + unsigned int loaded_tool = (unsigned int) -1; for (unsigned int i=0; i+1 1)) + if (lt.extruders.empty() || lt_next.extruders.empty()) { + if (! skip_empty_layer_tools) + break; + if (lt_last_printing == nullptr || lt_next.extruders.empty()) + continue; + } + if (!lt_next.has_wipe_tower && !tower_skippable(lt_next) && + (lt_next.extruders.size() > 1 || + std::find(lt_next.extruders.begin(), lt_next.extruders.end(), loaded_tool) == lt_next.extruders.end())) lt_next.has_wipe_tower = true; - // We should also check that the next wipe tower layer is no further than max_layer_height: + // We should also check that the next wipe tower layer is no further than max_layer_height. + // Fractional entries are transparent here: they never carry a slab, their neighbours + // bridge them. unsigned int j = i+1; double last_wipe_tower_print_z = lt_next.print_z; - while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower) - if (m_layer_tools[j+1].print_z - last_wipe_tower_print_z > max_layer_height + EPSILON) { + while (++j < m_layer_tools.size()-1 && !m_layer_tools[j].has_wipe_tower) { + if (tower_skippable(m_layer_tools[j])) + continue; + size_t jn = j + 1; + while (jn < m_layer_tools.size() && !m_layer_tools[jn].has_wipe_tower && tower_skippable(m_layer_tools[jn])) + ++jn; + if (jn < m_layer_tools.size() && m_layer_tools[jn].print_z - last_wipe_tower_print_z > max_layer_height + EPSILON) { if (!config.enable_wrapping_detection) m_layer_tools[j].has_wipe_tower = true; last_wipe_tower_print_z = m_layer_tools[j].print_z; } + } } + // Calculate the wipe_tower_layer_height values. coordf_t wipe_tower_print_z_last = 0.; for (LayerTools < : m_layer_tools) @@ -3397,8 +3585,9 @@ void ToolOrdering::mark_skirt_layers(const PrintConfig &config, coordf_t max_lay static CustomGCode::Info custom_gcode_per_print_z; void ToolOrdering::assign_custom_gcodes(const Print &print) { - // Only valid for non-sequential print. - assert(print.config().print_sequence == PrintSequence::ByLayer); + // Only valid for non-sequential print; a sequential print with a wipe tower is emitted + // by layer from the print-wide ordering and takes the custom G-codes the same way. + assert(print.config().print_sequence == PrintSequence::ByLayer || print.has_wipe_tower()); custom_gcode_per_print_z = print.model().get_curr_plate_custom_gcodes(); if (custom_gcode_per_print_z.gcodes.empty()) @@ -3525,12 +3714,36 @@ int WipingExtrusions::last_nonsoluble_extruder_on_layer(const PrintConfig& print return (-1); } +// diameter of the nozzle a 0-based filament prints through. +static double filament_nozzle_diameter(const Print &print, unsigned int filament_id) +{ + return print.config().nozzle_diameter.get_at(print.extruder_index_of(filament_id)); +} + // Decides whether this entity could be overridden bool WipingExtrusions::is_overriddable(const ExtrusionEntityCollection& eec, const PrintConfig& print_config, const PrintObject& object, const PrintRegion& region) const { - if (print_config.filament_soluble.get_at(m_layer_tools->extruder(eec, region))) + const unsigned int intended_filament = m_layer_tools->extruder(eec, region); + if (print_config.filament_soluble.get_at(intended_filament)) return false; + // Entity widths/heights were computed for its filament's nozzle, so only a filament with the same nozzle diameter may take it over; with no candidate it must keep its own filament. + if (print_config.nozzle_diameter.values.size() > 1) { + const Print &print = *object.print(); + const double intended_nozzle = filament_nozzle_diameter(print, intended_filament); + bool has_candidate = false; + for (size_t filament = 0; filament < print_config.filament_soluble.values.size(); ++ filament) + if (filament != intended_filament && + !print_config.filament_soluble.get_at(filament) && + !print_config.filament_is_support.get_at(filament) && + std::abs(filament_nozzle_diameter(print, (unsigned int)filament) - intended_nozzle) < EPSILON) { + has_candidate = true; + break; + } + if (!has_candidate) + return false; + } + if (object.config().flush_into_objects) return true; @@ -3624,6 +3837,11 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int if (!is_overriddable(*fill, print.config(), *object, region)) continue; + // Only wipe into entities computed for this extruder's nozzle diameter. + if (std::abs(filament_nozzle_diameter(print, lt.extruder(*fill, region)) - + filament_nozzle_diameter(print, new_extruder)) > EPSILON) + continue; + if (wipe_into_infill_only && ! is_infill_first) // In this case we must check that the original extruder is used on this layer before the one we are overridding // (and the perimeters will be finished before the infill is printed): @@ -3645,7 +3863,10 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int { for (const ExtrusionEntity* ee : layerm->perimeters.entities) { auto* fill = dynamic_cast(ee); - if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume) { + if (is_overriddable(*fill, print.config(), *object, region) && !is_entity_overridden(fill, object, copy) && fill->total_volume() > min_infill_volume && + // nozzle diameter must match + std::abs(filament_nozzle_diameter(print, lt.extruder(*fill, region)) - + filament_nozzle_diameter(print, new_extruder)) < EPSILON) { set_extruder_override(fill, object, copy, new_extruder, num_of_copies); if ((volume_to_wipe -= float(fill->total_volume())) <= 0.f) // More material was purged already than asked for. @@ -3664,8 +3885,9 @@ float WipingExtrusions::mark_wiping_extrusions(const Print& print, unsigned int if (this_support_layer == nullptr) break; - bool support_overriddable = object_config.support_filament == 0; - bool support_intf_overriddable = object_config.support_interface_filament == 0; + // Only a filament passing the object's support restrictions (nozzle diameter, material) may flush into its support. + bool support_overriddable = object_config.support_filament == 0 && object->support_filament_allowed(new_extruder + 1, false); + bool support_intf_overriddable = object_config.support_interface_filament == 0 && object->support_filament_allowed(new_extruder + 1, true); if (!support_overriddable && !support_intf_overriddable) break; @@ -3715,6 +3937,25 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) unsigned int first_nonsoluble_extruder = first_nonsoluble_extruder_on_layer(print.config()); unsigned int last_nonsoluble_extruder = last_nonsoluble_extruder_on_layer(print.config()); + // Prefer filaments printing through the nozzle diameter the entity's widths were computed for; returns -1 when the layer offers none. + auto nonsoluble_matching_extruder = [this, &print](bool first, unsigned int intended_filament) -> int { + const PrintConfig &config = print.config(); + const double intended_nozzle = filament_nozzle_diameter(print, intended_filament); + auto matches = [&](unsigned int filament) { + return !config.filament_soluble.get_at(filament) && !config.filament_is_support.get_at(filament) && + std::abs(filament_nozzle_diameter(print, filament) - intended_nozzle) < EPSILON; + }; + const std::vector &extruders = m_layer_tools->extruders; + if (first) { + for (auto it = extruders.begin(); it != extruders.end(); ++ it) + if (matches(*it)) return int(*it); + } else { + for (auto it = extruders.rbegin(); it != extruders.rend(); ++ it) + if (matches(*it)) return int(*it); + } + return -1; + }; + for (const PrintObject* object : print.objects()) { // Finds this layer: const Layer* this_layer = object->get_layer_at_printz(lt.print_z, EPSILON); @@ -3746,8 +3987,13 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) //BBS //|| object->config().flush_into_objects // in this case the perimeter is overridden, so we can override by the last one safely || lt.is_extruder_order(lt.wall_extruder_id(region), last_nonsoluble_extruder // !infill_first, but perimeter is already printed when last extruder prints - || ! lt.has_extruder(lt.sparse_infill_filament_id(region)))) // we have to force override - this could violate infill_first (FIXME) - set_extruder_override(fill, object, copy, (is_infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder), num_of_copies); + || ! lt.has_extruder(lt.sparse_infill_filament_id(region)))) { // we have to force override - this could violate infill_first (FIXME) + // Prefer a nozzle-matching filament; fall back so the entity still prints. + int flush_extruder = nonsoluble_matching_extruder(is_infill_first, lt.extruder(*fill, region)); + if (flush_extruder < 0) + flush_extruder = is_infill_first ? first_nonsoluble_extruder : last_nonsoluble_extruder; + set_extruder_override(fill, object, copy, flush_extruder, num_of_copies); + } else { // In this case we can (and should) leave it to be printed normally. // Force overriding would mean it gets printed before its perimeter. @@ -3757,8 +4003,13 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print) // Now the same for perimeters - see comments above for explanation: for (const ExtrusionEntity* ee : layerm->perimeters.entities) { // iterate through all perimeter Collections auto* fill = dynamic_cast(ee); - if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, object, copy)) - set_extruder_override(fill, object, copy, (is_infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder), num_of_copies); + if (is_overriddable(*fill, print.config(), *object, region) && ! is_entity_overridden(fill, object, copy)) { + // Same nozzle-matching preference as above. + int flush_extruder = nonsoluble_matching_extruder(!is_infill_first, lt.extruder(*fill, region)); + if (flush_extruder < 0) + flush_extruder = is_infill_first ? last_nonsoluble_extruder : first_nonsoluble_extruder; + set_extruder_override(fill, object, copy, flush_extruder, num_of_copies); + } } } } diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp index fa02ecd03c9..916f44ddb4d 100644 --- a/src/libslic3r/GCode/ToolOrdering.hpp +++ b/src/libslic3r/GCode/ToolOrdering.hpp @@ -23,6 +23,15 @@ namespace Slic3r { class Print; class PrintObject; class LayerTools; + +// ORCA: per-feature wall filaments. Classify a perimeter entity the way GCode::process_layer()'s +// mixed-perimeter split does: a loop carrying an external perimeter path - or a fully overhanging +// loop without any plain perimeter path - prints with the outer wall filament, everything else +// with the inner wall filament. The split and every wall filament dispatch must agree on this. +bool perimeter_entity_uses_outer_wall_filament(const ExtrusionEntity &entity); +// Do any of the collection's perimeter entities print with the outer / the inner wall filament? +void classify_wall_filaments(const ExtrusionEntityCollection &collection, bool &any_outer, bool &any_inner); + namespace CustomGCode { struct Item; } class PrintRegion; @@ -161,6 +170,9 @@ class LayerTools coordf_t print_z = 0.; bool has_object = false; bool has_support = false; + // This print_z is an object layer boundary (of any object, extrusions or not); support-only + // layers between such Zs come from fractional independent support layer heights. + bool on_object_grid = false; // Zero based extruder IDs, ordered to minimize tool switches. std::vector extruders; bool preserve_extruder_order = false; diff --git a/src/libslic3r/GCode/WipeTower.cpp b/src/libslic3r/GCode/WipeTower.cpp index 5834937169f..27c289e98bd 100644 --- a/src/libslic3r/GCode/WipeTower.cpp +++ b/src/libslic3r/GCode/WipeTower.cpp @@ -2726,7 +2726,7 @@ void WipeTower::set_for_wipe_tower_writer(WipeTowerWriter &writer) writer.set_accel_to_decel_enable(m_accel_to_decel_enable); writer.set_accel_to_decel_factor(m_accel_to_decel_factor); writer.set_first_layer(m_cur_layer_id == 0); - writer.set_layer_id(m_cur_layer_id); + writer.set_layer_id(nozzle_layer_id(int(m_cur_layer_id))); // per-layer nozzle maps use the ToolOrdering index writer.set_physical_extruder_map(m_physical_extruder_map); } #if 0 @@ -2930,8 +2930,10 @@ void WipeTower::plan_toolchange(float z_par, float layer_height_par, unsigned in { assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one - if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first + if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) { // if we moved to a new layer, we'll add it to m_plan first m_plan.push_back(WipeTowerInfo(z_par, layer_height_par)); + m_plan.back().start_tool = int(old_tool); + } if (m_first_layer_idx == size_t(-1) && (! m_no_sparse_layers || old_tool != new_tool)) m_first_layer_idx = m_plan.size() - 1; @@ -4429,6 +4431,10 @@ void WipeTower::generate_wipe_tower_blocks(bool add_solid_flag) } for (auto &info : m_plan) { std::unordered_set used_tools; + // The tool loaded at this layer may have changed off the tower since the last + // planned toolchange (fractional support layers): trust the recorded start tool. + if (info.start_tool >= 0) + first_tool = info.start_tool; if (info.tool_changes.empty()) { used_tools.insert(get_filament_category(first_tool)); } else { @@ -4653,6 +4659,9 @@ int WipeTower::get_wall_filament_for_all_layer() std::map filament_counts; int current_tool = m_current_tool; for (const auto &layer : m_plan) { + // The tool loaded at a layer may have changed off the tower since the last toolchange. + if (layer.start_tool >= 0) + current_tool = layer.start_tool; if (layer.tool_changes.empty()){ filament_counts[current_tool]++; category_counts[get_filament_category(current_tool)]++; @@ -4712,11 +4721,13 @@ void WipeTower::generate_new(std::vector= 0) { m_current_tool = size_t(layer.start_tool); start_tool_known = true; break; } + if (!start_tool_known) + for (const auto &layer : m_plan) + if (!layer.tool_changes.empty()) { m_current_tool = layer.tool_changes.front().old_tool; break; } } for (auto &used : m_used_filament_length) // reset used filament stats @@ -4730,6 +4741,9 @@ void WipeTower::generate_new(std::vector= 0 && size_t(layer.start_tool) != m_current_tool) + m_current_tool = size_t(layer.start_tool); if (m_layer_info->depth < m_perimeter_width) continue; if (m_wipe_tower_blocks.size() == 1) { if (m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width) { @@ -4933,11 +4947,13 @@ void WipeTower::generate(std::vector> & m_layer_info = m_plan.begin(); // we don't know which extruder to start with - we'll set it according to the first toolchange - for (const auto& layer : m_plan) { - if (!layer.tool_changes.empty()) { - m_current_tool = layer.tool_changes.front().old_tool; - break; - } + { + bool start_tool_known = false; + for (const auto &layer : m_plan) + if (layer.start_tool >= 0) { m_current_tool = size_t(layer.start_tool); start_tool_known = true; break; } + if (!start_tool_known) + for (const auto &layer : m_plan) + if (!layer.tool_changes.empty()) { m_current_tool = layer.tool_changes.front().old_tool; break; } } for (auto& used : m_used_filament_length) // reset used filament stats @@ -5317,24 +5333,26 @@ float WipeTower::get_block_gap_width(int tool,bool is_nozzlechangle) } +// All callers pass a plan layer index; the nozzle group result is indexed by the ToolOrdering +// layer index, which differs once fractional layers carry no tower slab. bool WipeTower::is_need_ramming(int filament_id_1, int filament_id_2, int layer_id) const { - return !m_multi_nozzle_group_result->are_filaments_same_nozzle(filament_id_1, filament_id_2, layer_id); + return !m_multi_nozzle_group_result->are_filaments_same_nozzle(filament_id_1, filament_id_2, nozzle_layer_id(layer_id)); } bool WipeTower::is_same_extruder(int filament_id_1, int filament_id_2, int layer_id) const { - return m_multi_nozzle_group_result->are_filaments_same_extruder(filament_id_1, filament_id_2, layer_id); + return m_multi_nozzle_group_result->are_filaments_same_extruder(filament_id_1, filament_id_2, nozzle_layer_id(layer_id)); } bool WipeTower::is_same_nozzle(int filament_id_1, int filament_id_2, int layer_id) const { - return m_multi_nozzle_group_result->are_filaments_same_nozzle(filament_id_1, filament_id_2, layer_id); + return m_multi_nozzle_group_result->are_filaments_same_nozzle(filament_id_1, filament_id_2, nozzle_layer_id(layer_id)); } -int WipeTower::get_nozzle_id(int filament_id, int layer_id) const { return m_multi_nozzle_group_result->get_nozzle_id(filament_id, layer_id); } +int WipeTower::get_nozzle_id(int filament_id, int layer_id) const { return m_multi_nozzle_group_result->get_nozzle_id(filament_id, nozzle_layer_id(layer_id)); } int WipeTower::get_extruder_id(int filament_id, int layer_id) const { - return m_multi_nozzle_group_result->get_extruder_id(filament_id, layer_id); + return m_multi_nozzle_group_result->get_extruder_id(filament_id, nozzle_layer_id(layer_id)); } } // namespace Slic3r diff --git a/src/libslic3r/GCode/WipeTower.hpp b/src/libslic3r/GCode/WipeTower.hpp index 045c82cbf36..862823508cd 100644 --- a/src/libslic3r/GCode/WipeTower.hpp +++ b/src/libslic3r/GCode/WipeTower.hpp @@ -205,6 +205,13 @@ class WipeTower // Appends into internal structure m_plan containing info about the future wipe tower // to be used before building begins. The entries must be added ordered in z. void plan_toolchange(float z_par, float layer_height_par, unsigned int old_tool, unsigned int new_tool, float wipe_volume_ec = 0.f, float wipe_volume_nc = 0.f, float prime_volume = 0.f); + // Records the ToolOrdering layer index of the last planned layer (see WipeTowerInfo::ordering_layer_idx). + void set_plan_layer_ordering_index(int ordering_layer_idx) { if (!m_plan.empty()) m_plan.back().ordering_layer_idx = ordering_layer_idx; } + // Maps a plan layer index to the ToolOrdering layer index the per-layer nozzle maps use. + int nozzle_layer_id(int plan_layer_id) const { + return plan_layer_id >= 0 && size_t(plan_layer_id) < m_plan.size() && m_plan[plan_layer_id].ordering_layer_idx >= 0 ? + m_plan[plan_layer_id].ordering_layer_idx : plan_layer_id; + } // Iterates through prepared m_plan, generates ToolChangeResults and appends them to "result" @@ -610,6 +617,11 @@ class WipeTower float toolchanges_depth() const { float sum = 0.f; for (const auto &a : tool_changes) sum += a.required_depth; return sum; } std::vector tool_changes; + // Tool loaded when this layer starts (-1 = unknown); toolchanges may happen off the tower. + int start_tool = -1; + // Index of this layer in the ToolOrdering that planned it (-1 = same as the plan index). + // Per-layer nozzle maps are indexed by it; the plan skips layers without a slab. + int ordering_layer_idx = -1; WipeTowerInfo(float z_par, float layer_height_par) : z{z_par}, height{layer_height_par}, depth{0}, extra_spacing{1.f} {} diff --git a/src/libslic3r/GCode/WipeTower2.cpp b/src/libslic3r/GCode/WipeTower2.cpp index 68c07155298..f8ab6d6c7aa 100644 --- a/src/libslic3r/GCode/WipeTower2.cpp +++ b/src/libslic3r/GCode/WipeTower2.cpp @@ -1219,7 +1219,10 @@ void WipeTower2::set_extruder(size_t idx, const PrintConfig& config) if (max_vol_speed != 0.f) m_filpar[idx].max_e_speed = (max_vol_speed / filament_area()); - m_perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; // all extruders are now assumed to have the same diameter + // ORCA: every tool purges with a width matching its own nozzle; the tower's geometric layout + // (m_perimeter_width) uses the widest configured nozzle, not whichever was configured last. + m_filpar[idx].perimeter_width = nozzle_diameter * Width_To_Nozzle_Ratio; + m_perimeter_width = idx == 0 ? m_filpar[idx].perimeter_width : std::max(m_perimeter_width, m_filpar[idx].perimeter_width); if (m_semm) { std::istringstream stream{config.filament_ramming_parameters.get_at(idx)}; @@ -1291,7 +1294,7 @@ std::vector WipeTower2::prime( for (size_t idx_tool = 0; idx_tool < tools.size(); ++idx_tool) { size_t old_tool = m_current_tool; - WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); + WipeTowerWriter2 writer(m_layer_height, tool_perimeter_width(m_current_tool), m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); writer.set_extrusion_flow(m_extrusion_flow).set_z(m_z_pos).set_initial_tool(m_current_tool); writer.set_is_prime(true); @@ -1395,7 +1398,7 @@ WipeTower::ToolChangeResult WipeTower2::emit_planned_tool_change(const WipeTower (!is_no_tool_sentinel(tool) ? wipe_area + m_depth_traversed - 0.5f * m_perimeter_width : m_wipe_tower_depth - m_perimeter_width)); - WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); + WipeTowerWriter2 writer(m_layer_height, tool_perimeter_width(m_current_tool), m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -1541,7 +1544,7 @@ WipeTower::ToolChangeResult WipeTower2::local_z_tool_change(size_t new_tool, { const size_t old_tool = m_current_tool; - WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); + WipeTowerWriter2 writer(m_layer_height, tool_perimeter_width(m_current_tool), m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -1606,7 +1609,7 @@ void WipeTower2::toolchange_Unload(WipeTowerWriter2& writer, float xl = cleaning_box.ld.x() + 1.f * m_perimeter_width; float xr = cleaning_box.rd.x() - 1.f * m_perimeter_width; - const float line_width = m_perimeter_width * + const float line_width = tool_perimeter_width(m_current_tool) * m_filpar[m_current_tool].ramming_line_width_multiplicator; // desired ramming line thickness const float y_step = line_width * m_filpar[m_current_tool].ramming_step_multiplicator * m_extra_spacing_ramming; // spacing between lines in mm @@ -1728,7 +1731,7 @@ void WipeTower2::toolchange_Unload(WipeTowerWriter2& writer, } Vec2f end_of_ramming(writer.x(), writer.y()); - writer.change_analyzer_line_width(m_perimeter_width); // so the next lines are not affected by ramming_line_width_multiplier + writer.change_analyzer_line_width(tool_perimeter_width(m_current_tool)); // so the next lines are not affected by ramming_line_width_multiplier // Retraction: if (m_enable_filament_ramming) @@ -1989,6 +1992,8 @@ void WipeTower2::toolchange_Change( writer.flush_planner_queue(); m_current_tool = new_tool; + // The new toolhead may have a different nozzle, so the extrusion flow must follow the tool change. + m_extrusion_flow = extrusion_flow(m_layer_height); } void WipeTower2::toolchange_Load(WipeTowerWriter2& writer, const WipeTower::box_coordinates& cleaning_box) @@ -2032,14 +2037,16 @@ void WipeTower2::toolchange_Wipe( const float& xr = cleaning_box.rd.x(); writer.set_extrusion_flow(m_extrusion_flow * m_extra_flow); - const float line_width = m_perimeter_width * m_extra_flow; + // Purge lines use the tool's own width; row spacing dy keeps m_perimeter_width so consumed depth matches the plan. + const float line_width = tool_perimeter_width(m_current_tool) * m_extra_flow; writer.change_analyzer_line_width(line_width); // Variables x_to_wipe and traversed_x are here to be able to make sure it always wipes at least // the ordered volume, even if it means violating the box. This can later be removed and simply // wipe until the end of the assigned area. - float x_to_wipe = volume_to_length(wipe_volume, m_perimeter_width, m_layer_height) / m_extra_flow; + // Snapmaker: convert the purge volume with the tool's own line width (multi-nozzle). + float x_to_wipe = volume_to_length(wipe_volume, tool_perimeter_width(m_current_tool), m_layer_height) / m_extra_flow; float dy = wipe_row_spacing(is_first_layer()); // Don't use the extra spacing for the first layer, but do use the spacing resulting from increased flow. // All the calculations in all other places take the spacing into account for all the layers. @@ -2130,7 +2137,7 @@ void WipeTower2::toolchange_Wipe( } writer.set_extrusion_flow(m_extrusion_flow); // Reset the extrusion flow. - writer.change_analyzer_line_width(m_perimeter_width); + writer.change_analyzer_line_width(tool_perimeter_width(m_current_tool)); } WipeTower::ToolChangeResult WipeTower2::finish_layer() @@ -2140,7 +2147,7 @@ WipeTower::ToolChangeResult WipeTower2::finish_layer() size_t old_tool = m_current_tool; - WipeTowerWriter2 writer(m_layer_height, m_perimeter_width, m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); + WipeTowerWriter2 writer(m_layer_height, tool_perimeter_width(m_current_tool), m_gcode_flavor, m_filpar, m_enable_arc_fitting, m_printer_model); writer.set_extrusion_flow(m_extrusion_flow) .set_z(m_z_pos) .set_initial_tool(m_current_tool) @@ -2416,12 +2423,13 @@ float WipeTower2::estimate_semm_flush_volume(const ConfigBase& config, size_t fi return maximum; } -static float get_wipe_depth(float volume, float layer_height, float perimeter_width, float extra_flow, float extra_spacing, float width) +// purge_line_width is what the purging tool extrudes, row_spacing_width the tower's geometric row pitch - they differ on printers with mixed nozzle diameters. +static float get_wipe_depth(float volume, float layer_height, float purge_line_width, float row_spacing_width, float extra_flow, float extra_spacing, float width) { - float length_to_extrude = (volume_to_length(volume, perimeter_width, layer_height)) / extra_flow; + float length_to_extrude = (volume_to_length(volume, purge_line_width, layer_height)) / extra_flow; length_to_extrude = std::max(length_to_extrude, 0.f); - return (int(length_to_extrude / width) + 1) * perimeter_width * extra_spacing; + return (int(length_to_extrude / width) + 1) * row_spacing_width * extra_spacing; } // Appends a toolchange into m_plan and calculates neccessary depth of the corresponding box @@ -2429,8 +2437,10 @@ void WipeTower2::plan_toolchange(float z_par, float layer_height_par, unsigned i { assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); // refuses to add a layer below the last one - if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) // if we moved to a new layer, we'll add it to m_plan first + if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) { // if we moved to a new layer, we'll add it to m_plan first m_plan.push_back(WipeTowerInfo(z_par, layer_height_par)); + m_plan.back().start_tool = int(old_tool); + } if (m_first_layer_idx == size_t(-1) && (!m_no_sparse_layers || old_tool != new_tool || m_plan.size() == 1)) m_first_layer_idx = m_plan.size() - 1; @@ -2445,7 +2455,9 @@ void WipeTower2::plan_toolchange(float z_par, float layer_height_par, unsigned i WipeTower2::WipeTowerInfo::ToolChange WipeTower2::set_toolchange(size_t old_tool, size_t new_tool, float layer_height, float wipe_volume, bool first_layer_plan) { - float ramming_lw = m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator; + // Snapmaker: ramming uses the OLD tool's own line width and the wipe the NEW tool's; the planned + // depths must match the widths toolchange_Unload() / toolchange_Wipe() will actually use. + float ramming_lw = tool_perimeter_width(old_tool) * m_filpar[old_tool].ramming_line_width_multiplicator; float width = m_wipe_tower_width - m_perimeter_width - 2 * ramming_lw; // Orca: For non-SEMM multi-toolhead, ramming_speed contains only flow (not speed), so 0.25f * flow is meaningless. // Use the actual multitool_ramming_volume instead. @@ -2470,7 +2482,7 @@ WipeTower2::WipeTowerInfo::ToolChange WipeTower2::set_toolchange(size_t old_tool float first_wipe_line = (do_ramming && !boundary_wipe_start) ? -(width * ((length_to_extrude / width) - int(length_to_extrude / width)) - width) : 0.f; - float first_wipe_volume = length_to_volume(first_wipe_line, m_perimeter_width * m_extra_flow, layer_height); + float first_wipe_volume = length_to_volume(first_wipe_line, tool_perimeter_width(new_tool) * m_extra_flow, layer_height); // ORCA: Keep wipe-depth planning consistent with toolchange_Wipe(). // ORCA: On the first layer, toolchange_Wipe() advances purge rows using @@ -2481,8 +2493,8 @@ WipeTower2::WipeTowerInfo::ToolChange WipeTower2::set_toolchange(size_t old_tool // ORCA: and first-layer purge segments do not leave visible gaps. const float planning_spacing = first_layer_plan ? m_extra_flow : m_extra_spacing_wipe; - float wiping_depth = get_wipe_depth(wipe_volume - first_wipe_volume, layer_height, m_perimeter_width, - m_extra_flow, planning_spacing, width); + float wiping_depth = get_wipe_depth(wipe_volume - first_wipe_volume, layer_height, tool_perimeter_width(new_tool), + m_perimeter_width, m_extra_flow, planning_spacing, width); return WipeTowerInfo::ToolChange(old_tool, new_tool, ramming_depth + wiping_depth, ramming_depth, first_wipe_line, wipe_volume); } @@ -2491,8 +2503,10 @@ void WipeTower2::plan_local_z_toolchange(float z_par, float layer_height_par, un { assert(m_plan.empty() || m_plan.back().z <= z_par + WT_EPSILON); - if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) + if (m_plan.empty() || m_plan.back().z + WT_EPSILON < z_par) { m_plan.push_back(WipeTowerInfo(z_par, layer_height_par)); + m_plan.back().start_tool = int(old_tool); + } if (m_first_layer_idx == size_t(-1) && (!m_no_sparse_layers || old_tool != new_tool || m_plan.size() == 1)) m_first_layer_idx = m_plan.size() - 1; @@ -2500,7 +2514,8 @@ void WipeTower2::plan_local_z_toolchange(float z_par, float layer_height_par, un if (old_tool == new_tool) return; - float ramming_lw = m_perimeter_width * m_filpar[old_tool].ramming_line_width_multiplicator; + // ramming uses the OLD tool's own line width and the wipe the NEW tool's (see plan_toolchange()). + float ramming_lw = tool_perimeter_width(old_tool) * m_filpar[old_tool].ramming_line_width_multiplicator; float width = m_wipe_tower_width - m_perimeter_width - 2 * ramming_lw; float ramming_volume = m_semm ? 0.25f * std::accumulate(m_filpar[old_tool].ramming_speed.begin(), m_filpar[old_tool].ramming_speed.end(), 0.f) @@ -2512,9 +2527,9 @@ void WipeTower2::plan_local_z_toolchange(float z_par, float layer_height_par, un m_extra_spacing_ramming; float first_wipe_line = -(width * ((length_to_extrude / width) - int(length_to_extrude / width)) - width); - float first_wipe_volume = length_to_volume(first_wipe_line, m_perimeter_width * m_extra_flow, layer_height_par); - float wiping_depth = get_wipe_depth(wipe_volume - first_wipe_volume, layer_height_par, m_perimeter_width, m_extra_flow, - m_extra_spacing_wipe, width); + float first_wipe_volume = length_to_volume(first_wipe_line, tool_perimeter_width(new_tool) * m_extra_flow, layer_height_par); + float wiping_depth = get_wipe_depth(wipe_volume - first_wipe_volume, layer_height_par, tool_perimeter_width(new_tool), + m_perimeter_width, m_extra_flow, m_extra_spacing_wipe, width); m_plan.back().local_z_tool_changes.push_back( WipeTowerInfo::ToolChange(old_tool, new_tool, ramming_depth + wiping_depth, ramming_depth, first_wipe_line, wipe_volume)); @@ -2532,9 +2547,15 @@ void WipeTower2::plan_local_z_reserve(float z_par, float layer_height_par, size_ const float mini_wipe_depth = m_local_z_wipe_tower_purge_lines * m_perimeter_width * m_extra_spacing_wipe; const float wipe_width = std::max(0.f, m_wipe_tower_width - 3.f * m_perimeter_width); + // The reserving slot does not know which tool will purge into it; plan the wipe length with the + // narrowest tool line width (worst case) while keeping the geometric row pitch (m_perimeter_width). + float min_tool_perimeter_width = m_perimeter_width; + for (const FilamentParameters& filament : m_filpar) + if (filament.perimeter_width > 0.f) + min_tool_perimeter_width = std::min(min_tool_perimeter_width, filament.perimeter_width); const float wiping_depth = wipe_width > WT_EPSILON ? - get_wipe_depth(std::max(0.f, wipe_volume), layer_height_par, m_perimeter_width, m_extra_flow, - m_extra_spacing_wipe, wipe_width) : + get_wipe_depth(std::max(0.f, wipe_volume), layer_height_par, min_tool_perimeter_width, + m_perimeter_width, m_extra_flow, m_extra_spacing_wipe, wipe_width) : 0.f; float max_ramming_depth = 0.f; @@ -2544,9 +2565,11 @@ void WipeTower2::plan_local_z_reserve(float z_par, float layer_height_par, size_ if (!do_ramming || filament.ramming_speed.empty()) continue; - const float line_width = m_perimeter_width * filament.ramming_line_width_multiplicator; + // Each tool rams with its own line width (see toolchange_Unload()). + const float tool_width = filament.perimeter_width > 0.f ? filament.perimeter_width : m_perimeter_width; + const float line_width = tool_width * filament.ramming_line_width_multiplicator; const float line_step = - (m_perimeter_width * filament.ramming_line_width_multiplicator * filament.ramming_step_multiplicator) * + (tool_width * filament.ramming_line_width_multiplicator * filament.ramming_step_multiplicator) * m_extra_spacing_ramming; if (line_width <= WT_EPSILON || line_step <= WT_EPSILON) continue; @@ -2612,8 +2635,9 @@ void WipeTower2::save_on_last_wipe() auto recompute_toolchange = [this, width](WipeTowerInfo::ToolChange& toolchange, float volume_to_save) { float volume_left_to_wipe = std::max(m_filpar[toolchange.new_tool].filament_minimal_purge_on_wipe_tower, toolchange.wipe_volume_total - volume_to_save); + // Snapmaker: the wipe is extruded by the new tool with its own line width. float volume_we_need_depth_for = std::max(0.f, volume_left_to_wipe - length_to_volume(toolchange.first_wipe_line, - m_perimeter_width * m_extra_flow, + tool_perimeter_width(toolchange.new_tool) * m_extra_flow, m_layer_info->height)); // ORCA: Keep wipe-depth planning consistent with toolchange_Wipe(). @@ -2626,7 +2650,8 @@ void WipeTower2::save_on_last_wipe() const bool first_layer_plan = size_t(m_layer_info - m_plan.begin()) == m_first_layer_idx; const float planning_spacing = first_layer_plan ? m_extra_flow : m_extra_spacing_wipe; - float depth_to_wipe = get_wipe_depth(volume_we_need_depth_for, m_layer_info->height, m_perimeter_width, + float depth_to_wipe = get_wipe_depth(volume_we_need_depth_for, m_layer_info->height, + tool_perimeter_width(toolchange.new_tool), m_perimeter_width, m_extra_flow, planning_spacing, width); toolchange.required_depth = toolchange.ramming_depth + depth_to_wipe; @@ -2638,7 +2663,9 @@ void WipeTower2::save_on_last_wipe() emit_planned_tool_change(&toolchange); if (i == idx) { - recompute_toolchange(toolchange, length_to_volume(finish_layer().total_extrusion_length_in_plane(), m_perimeter_width, + // ORCA: the finish layer is extruded by the new tool with its own line width. + recompute_toolchange(toolchange, length_to_volume(finish_layer().total_extrusion_length_in_plane(), + tool_perimeter_width(toolchange.new_tool), m_layer_info->height)); } else if (toolchange.wipe_volume < m_filpar[toolchange.new_tool].filament_minimal_purge_on_wipe_tower) { // Keep filament_minimal_purge_on_wipe_tower enforced for toolchanges that get @@ -2815,17 +2842,26 @@ void WipeTower2::generate(std::vector>& m_layer_info = m_plan.begin(); m_current_height = 0.f; - // We don't know which extruder to start with, so take the first actual toolchange on the tower. - for (const auto& layer : m_plan) { - if (!layer.local_z_tool_changes.empty()) { - m_current_tool = layer.local_z_tool_changes.front().old_tool; + // Start with the tool loaded at the first planned layer; fall back to the first + // actual toolchange on the tower for plans that did not record it. + bool start_tool_known = false; + for (const auto& layer : m_plan) + if (layer.start_tool >= 0) { + m_current_tool = size_t(layer.start_tool); + start_tool_known = true; break; } - if (!layer.tool_changes.empty()) { - m_current_tool = layer.tool_changes.front().old_tool; - break; + if (!start_tool_known) + for (const auto& layer : m_plan) { + if (!layer.local_z_tool_changes.empty()) { + m_current_tool = layer.local_z_tool_changes.front().old_tool; + break; + } + if (!layer.tool_changes.empty()) { + m_current_tool = layer.tool_changes.front().old_tool; + break; + } } - } m_used_filament_length.assign(m_used_filament_length.size(), 0.f); // reset used filament stats assert(m_used_filament_length_until_layer.empty()); @@ -2845,6 +2881,10 @@ void WipeTower2::generate(std::vector>& << " planned_depth=" << layer.planned_depth(); set_layer(layer.z, layer.height, 0, false /*layer.z == m_plan.front().z*/, layer.z == m_plan.back().z); m_internal_rotation += 180.f; + // Re-sync to the tool actually loaded at this layer: a filament change may have + // happened off the tower since the previous layer. + if (layer.start_tool >= 0 && size_t(layer.start_tool) != m_current_tool) + m_current_tool = size_t(layer.start_tool); if (m_layer_info->depth < m_wipe_tower_depth - m_perimeter_width) m_y_shift = (m_wipe_tower_depth - m_layer_info->depth - m_perimeter_width) / 2.f; diff --git a/src/libslic3r/GCode/WipeTower2.hpp b/src/libslic3r/GCode/WipeTower2.hpp index ae29b800eca..c099e751730 100644 --- a/src/libslic3r/GCode/WipeTower2.hpp +++ b/src/libslic3r/GCode/WipeTower2.hpp @@ -191,6 +191,8 @@ class WipeTower2 float max_e_speed = std::numeric_limits::max(); std::vector ramming_speed; float nozzle_diameter; + // ORCA: tower line width this tool extrudes (nozzle_diameter * Width_To_Nozzle_Ratio). + float perimeter_width = 0.f; float filament_area; bool multitool_ramming; float multitool_ramming_time = 0.f; @@ -220,6 +222,10 @@ class WipeTower2 float filament_area() const { return m_filpar[0].filament_area; // all extruders are assumed to have the same filament diameter at this point } + // Line width the given tool extrudes on the tower; m_perimeter_width (widest nozzle) keeps the geometric layout: line spacing, box sizes, depth planning. + float tool_perimeter_width(size_t tool) const { + return tool < m_filpar.size() && m_filpar[tool].perimeter_width > 0.f ? m_filpar[tool].perimeter_width : m_perimeter_width; + } bool m_change_pressure = true; float m_change_pressure_value = 0.0; @@ -350,12 +356,13 @@ class WipeTower2 return pos; } - // Calculates extrusion flow needed to produce required line width for given layer height + // Calculates extrusion flow needed to produce required line width for given layer height. + // ORCA: uses the current tool's own line width, matching its nozzle. float extrusion_flow(float layer_height = -1.f) const // negative layer_height - return current m_extrusion_flow { if ( layer_height < 0 ) return m_extrusion_flow; - return layer_height * ( m_perimeter_width - layer_height * (1.f-float(M_PI)/4.f)) / filament_area(); + return layer_height * ( tool_perimeter_width(m_current_tool) - layer_height * (1.f-float(M_PI)/4.f)) / filament_area(); } @@ -391,6 +398,10 @@ class WipeTower2 std::vector tool_changes; std::vector local_z_tool_changes; + // Tool loaded when this layer starts (-1 = unknown). Toolchanges may happen off + // the tower between layers (fractional support layers), so the tower cannot infer + // it from its own toolchange chain. + int start_tool = -1; WipeTowerInfo(float z_par, float layer_height_par) : z{z_par}, height{layer_height_par}, depth{0} {} diff --git a/src/libslic3r/Layer.cpp b/src/libslic3r/Layer.cpp index 7c11ca8869e..7b740149da9 100644 --- a/src/libslic3r/Layer.cpp +++ b/src/libslic3r/Layer.cpp @@ -74,6 +74,45 @@ LayerRegion* Layer::add_region(const PrintRegion *print_region) return m_regions.back(); } +// ORCA: per-extruder layer height, see PrintObject::apply_extruder_layer_heights(). +double LayerRegion::combined_height() const +{ + return m_combined_height > 0. ? m_combined_height : m_layer->height; +} + +static const Layer* nth_lower_layer(const Layer *layer, unsigned short count) +{ + for (unsigned short i = 0; layer != nullptr && i < count; ++ i) + layer = layer->lower_layer; + return layer; +} + +const Layer* LayerRegion::combined_lower_layer() const +{ + // count == 0 (layer combined away into a group top) is treated as 1; it produces no extrusions anyway. + return nth_lower_layer(m_layer, std::max(m_combined_layer_count, 1)); +} + +// ORCA: walls-only pitch, see PrintObject::wall_layer_height_multiplier(). +double LayerRegion::wall_combined_height() const +{ + return m_wall_combined_height > 0. ? m_wall_combined_height : this->combined_height(); +} + +const Layer* LayerRegion::wall_combined_lower_layer() const +{ + // count == 0 (walls extrude at the run top above) produces no wall extrusions anyway. + return m_wall_combined_count <= 1 ? this->combined_lower_layer() : + nth_lower_layer(m_layer, m_wall_combined_count); +} + +// ORCA: split wall layer heights, see PrintObject::wall_split_pitches(). +const Layer* LayerRegion::wall_split_lower_layer() const +{ + return m_wall_split_count <= 1 ? this->wall_combined_lower_layer() : + nth_lower_layer(m_layer, m_wall_split_count); +} + // merge all regions' slices to get islands void Layer::make_slices() { @@ -256,7 +295,14 @@ void Layer::make_perimeters() // this is a no-op for every other configuration. if (this_region.gradient_volume_id() != other_region.gradient_volume_id()) continue; - if (is_perimeter_compatible(*m_object->print(), this_region, other_region)) + // Regions combined to different extruder layer heights (whole-region groups or + // walls-only runs) extrude with different heights and must not share a make_perimeters() call. + if ((*layerm)->combined_layer_count() == other_layerm->combined_layer_count() && + (*layerm)->wall_combined_count() == other_layerm->wall_combined_count() && + std::abs((*layerm)->wall_combined_height() - other_layerm->wall_combined_height()) < EPSILON && + (*layerm)->wall_split_count() == other_layerm->wall_split_count() && + std::abs((*layerm)->wall_split_height() - other_layerm->wall_split_height()) < EPSILON && + is_perimeter_compatible(*m_object->print(), this_region, other_region)) { other_layerm->perimeters.clear(); other_layerm->fills.clear(); diff --git a/src/libslic3r/Layer.hpp b/src/libslic3r/Layer.hpp index cb1f8f85a6e..7ce48939be7 100644 --- a/src/libslic3r/Layer.hpp +++ b/src/libslic3r/Layer.hpp @@ -16,9 +16,16 @@ using LayerPtrs = std::vector; class LayerRegion; using LayerRegionPtrs = std::vector; class PrintRegion; +class PrintRegionConfig; class PrintObject; class Print; +// Snapmaker mixed filament: resolve a configured 1-based filament id to the physical filament +// actually printing on this layer (0 "Default" passes through unchanged). The infill variant +// additionally resolves grouped manual patterns like the innermost perimeter. +unsigned int effective_layer_filament_id(const Layer &layer, unsigned int filament_id); +unsigned int effective_infill_filament_id(const Layer &layer, const PrintRegionConfig &config, unsigned int filament_id); + namespace FillAdaptive { struct Octree; }; @@ -79,8 +86,11 @@ class LayerRegion unsigned int extruder(FlowRole role) const; Flow flow(FlowRole role) const; Flow flow(FlowRole role, double layer_height) const; - Flow flow(FlowRole role, double layer_height, bool use_initial_layer_width) const; - Flow bridging_flow(FlowRole role, bool thick_bridge = false) const; + // filament_id: 1-based filament actually printing this flow when it differs from the role's default mapping (e.g. top/bottom surface fills, external bridges), 0 to resolve from the role. + Flow flow(FlowRole role, double layer_height, unsigned int filament_id) const; + Flow flow(FlowRole role, double layer_height, bool use_initial_layer_width, unsigned int filament_id = 0) const; + // layer_height overrides m_layer->height for the non-thick flow (combined layer groups print thicker), 0 to use m_layer->height. + Flow bridging_flow(FlowRole role, bool thick_bridge = false, unsigned int filament_id = 0, double layer_height = 0.) const; void slices_to_fill_surfaces_clipped(); void prepare_fill_surfaces(); @@ -105,6 +115,43 @@ class LayerRegion //BBS void simplify_infill_extrusion_entity() { simplify_entity_collection(&fills); } void simplify_wall_extrusion_entity() { simplify_entity_collection(&perimeters); } + + // ORCA: per-extruder layer height. Number of object layers this region's extrusions cover here: + // > 1 on the top layer of a group combined by PrintObject::apply_extruder_layer_heights(), 0 on + // the combined-away layers below such a top (their slices are empty and print nothing; the 0 + // tells them apart from layers where the region's geometry is genuinely absent), 1 otherwise. + unsigned short combined_layer_count() const { return m_combined_layer_count; } + // Extrusion height at this layer (sum of the covered layer heights when combined, else layer height). + double combined_height() const; + // Layer right below the covered group; replaces Layer::lower_layer for overhang / bridge + // detection of combined regions. May be nullptr. + const Layer* combined_lower_layer() const; + // Shape of this layer that its combined group does not print; classifies exposed step faces. + const ExPolygons& combined_away_exposed() const { return m_combined_away_exposed; } + + // ORCA: walls-only pitch (PrintObject::wall_layer_height_multiplier()). Number of object + // layers whose walls this region's perimeters cover here: > 1 on the top layer of a wall run + // marked by PrintObject::apply_extruder_layer_heights(), 0 on the run layers below (they + // generate perimeters only to bound their fills and drop the wall extrusions), 1 otherwise. + unsigned short wall_combined_count() const { return m_wall_combined_count; } + // Height the walls are generated with at this layer: the wall run height on all its layers + // (the whole run's fill boundaries must line up with the walls printed at its top), else the + // region's combined height / layer height. + double wall_combined_height() const; + // Layer right below the wall run for overhang / bridge detection of the run's walls. + const Layer* wall_combined_lower_layer() const; + + // ORCA: split wall layer heights. Cadence of the COARSER wall class when the outer and + // inner walls print with their own heights: > 1 (in object layers) on the top layer of a + // coarse run, 0 on the other layers of a committed coarse run (the coarse class prints + // nothing there), 1 when no coarse run covers this layer (the coarse class follows the fine + // cadence). Which class is coarse follows from the two wall filaments' effective heights + // (see PrintObject::wall_split_pitches()). + unsigned short wall_split_count() const { return m_wall_split_count; } + // Extrusion height of the coarse class at a coarse-run top. + double wall_split_height() const { return m_wall_split_height; } + // Layer right below the coarse run for overhang / bridge detection of the coarse walls. + const Layer* wall_split_lower_layer() const; private: void simplify_entity_collection(ExtrusionEntityCollection* entity_collection); void simplify_path(ExtrusionPath* path); @@ -121,6 +168,16 @@ class LayerRegion private: Layer *m_layer; const PrintRegion *m_region; + // ORCA: set by PrintObject::apply_extruder_layer_heights(), see combined_layer_count() / combined_height(). + unsigned short m_combined_layer_count { 1 }; + double m_combined_height { 0. }; + ExPolygons m_combined_away_exposed; + // ORCA: set by PrintObject::apply_extruder_layer_heights(), see wall_combined_count() / wall_combined_height(). + unsigned short m_wall_combined_count { 1 }; + double m_wall_combined_height { 0. }; + // ORCA: set by PrintObject::apply_extruder_layer_heights(), see wall_split_count() / wall_split_height(). + unsigned short m_wall_split_count { 1 }; + double m_wall_split_height { 0. }; }; class Layer diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 4bd400d7582..51b96f00ac8 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -6,6 +6,7 @@ #include "PerimeterGenerator.hpp" #include "Point.hpp" #include "Print.hpp" +#include "GCode/ToolOrdering.hpp" #include "Surface.hpp" #include "BoundingBox.hpp" #include "SVG.hpp" @@ -21,8 +22,6 @@ namespace Slic3r { -namespace { - unsigned int effective_layer_filament_id(const Layer &layer, unsigned int filament_id) { if (filament_id == 0) @@ -82,17 +81,15 @@ unsigned int effective_infill_filament_id(const Layer &layer, const PrintRegionC object); } -} // namespace - unsigned int LayerRegion::extruder(FlowRole role) const { const PrintRegionConfig &config = this->region().config(); unsigned int filament_id = 0; if (role == frInfill) filament_id = config.sparse_infill_filament_id.value; - else if (role == frSolidInfill && std::abs(config.sparse_infill_density.value - 100.) < EPSILON) - filament_id = config.sparse_infill_filament_id.value; else + // Internal solid infill resolves to the internal solid filament at every density, + // including the 100% dense interior (PrintRegion::extruder()). filament_id = this->region().extruder(role); return (role == frInfill || role == frSolidInfill) ? @@ -110,7 +107,13 @@ Flow LayerRegion::flow(FlowRole role, double layer_height) const return this->flow(role, layer_height, m_layer->id() == 0); } -Flow LayerRegion::flow(FlowRole role, double layer_height, bool use_initial_layer_width) const +// filament_id: 1-based filament actually printing this flow when it differs from the role's default mapping (e.g. top/bottom surface fills, external bridges), 0 to resolve from the role. +Flow LayerRegion::flow(FlowRole role, double layer_height, unsigned int filament_id) const +{ + return this->flow(role, layer_height, m_layer->id() == 0, filament_id); +} + +Flow LayerRegion::flow(FlowRole role, double layer_height, bool use_initial_layer_width, unsigned int filament_id) const { const PrintConfig &print_config = m_layer->object()->print()->config(); ConfigOptionFloatOrPercent config_width; @@ -135,23 +138,28 @@ Flow LayerRegion::flow(FlowRole role, double layer_height, bool use_initial_laye if (config_width.value == 0) config_width = m_layer->object()->config().line_width; - const auto nozzle_diameter = float(print_config.nozzle_diameter.get_at(this->extruder(role) - 1)); + // Width resolves against the nozzle of the filament that actually prints (filament_id, when given), + // which may differ from the role's default filament mapping. + const auto nozzle_diameter = float(print_config.nozzle_diameter.get_at((filament_id > 0 ? filament_id : this->extruder(role)) - 1)); return Flow::new_from_config_width(role, config_width, nozzle_diameter, float(layer_height)); } -Flow LayerRegion::bridging_flow(FlowRole role, bool thick_bridge) const +Flow LayerRegion::bridging_flow(FlowRole role, bool thick_bridge, unsigned int filament_id, double layer_height) const { const PrintRegion ®ion = this->region(); const PrintRegionConfig ®ion_config = region.config(); const PrintObject &print_object = *this->layer()->object(); Flow bridge_flow; + // The nozzle resolves against the filament that actually prints (filament_id, when given), which may + // differ from the role's default filament mapping. // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will fall back to zero'th element, so everything is all right. - auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at(this->extruder(role) - 1)); + auto nozzle_diameter = float(print_object.print()->config().nozzle_diameter.get_at((filament_id > 0 ? filament_id : this->extruder(role)) - 1)); const ConfigOptionFloatOrPercent& bridge_width_opt = region_config.bridge_line_width; const double bridge_width = bridge_width_opt.get_abs_value(nozzle_diameter); const bool has_bridge_width = bridge_width > 0.; const double bridge_flow_ratio = region_config.bridge_flow; + if (thick_bridge) { // The old Slic3r way (different from all other slicers): Use rounded extrusions. // Get the configured nozzle_diameter for the extruder associated to the flow role requested. @@ -161,7 +169,8 @@ Flow LayerRegion::bridging_flow(FlowRole role, bool thick_bridge) const bridge_flow = Flow::bridging_flow(thread_diameter, nozzle_diameter); } else { // The same way as other slicers: Use normal extrusions. Apply bridge_flow while maintaining the original spacing. - Flow base_flow = this->flow(role); + // Combined layer groups stamp their full thickness on the surface; the base flow must be resolved at that height. + Flow base_flow = this->flow(role, layer_height > 0. ? layer_height : m_layer->height, filament_id); if (has_bridge_width) base_flow = Flow(float(bridge_width), base_flow.height(), nozzle_diameter); bridge_flow = base_flow.with_flow_ratio(bridge_flow_ratio); @@ -190,6 +199,28 @@ void LayerRegion::slices_to_fill_surfaces_clipped() } } +// ORCA: split wall layer heights - drop one wall class from freshly generated perimeters. +// Classification matches the G-code dispatch (perimeter_entity_uses_outer_wall_filament()), so +// the class printing at a cadence is exactly the class dispatched to its wall filament. +static void remove_wall_class(ExtrusionEntityCollection &collection, bool outer_class) +{ + ExtrusionEntitiesPtr &entities = collection.entities; + for (size_t i = 0; i < entities.size(); ) { + if (auto *sub = dynamic_cast(entities[i])) { + remove_wall_class(*sub, outer_class); + if (! sub->entities.empty()) { + ++ i; + continue; + } + } else if (perimeter_entity_uses_outer_wall_filament(*entities[i]) != outer_class) { + ++ i; + continue; + } + delete entities[i]; + entities.erase(entities.begin() + i); + } +} + void LayerRegion::make_perimeters(const SurfaceCollection &slices, const LayerRegionPtrs &compatible_regions, SurfaceCollection* fill_surfaces, ExPolygons* fill_no_overlap) { this->perimeters.clear(); @@ -200,8 +231,11 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, const LayerRe const PrintObjectConfig& object_config = this->layer()->object()->config(); PrintRegionConfig perimeter_config = region_config; perimeter_config.outer_wall_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.outer_wall_filament_id.value)))); + perimeter_config.inner_wall_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.inner_wall_filament_id.value)))); perimeter_config.sparse_infill_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.sparse_infill_filament_id.value)))); perimeter_config.internal_solid_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.internal_solid_filament_id.value)))); + perimeter_config.top_surface_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.top_surface_filament_id.value)))); + perimeter_config.bottom_surface_filament_id.value = int(effective_layer_filament_id(*this->layer(), unsigned(std::max(0, region_config.bottom_surface_filament_id.value)))); // This needs to be in sync with PrintObject::_slice() slicing_mode_normal_below_layer! bool spiral_mode = print_config.spiral_mode && //FIXME account for raft layers. @@ -215,46 +249,95 @@ void LayerRegion::make_perimeters(const SurfaceCollection &slices, const LayerRe model_rotation_rad = std::atan2((double)m(1, 0), (double)m(0, 0)); } - PerimeterGenerator g( - // input: - &slices, - &compatible_regions, - this->layer()->height, - this->layer()->slice_z, - this->flow(frPerimeter), - &perimeter_config, - &this->layer()->object()->config(), - &print_config, - spiral_mode, - model_rotation_rad, - - // output: - &this->perimeters, - &this->thin_fills, - fill_surfaces, - //BBS - fill_no_overlap - ); - - if (this->layer()->lower_layer != nullptr) - // Cummulative sum of polygons over all the regions. - g.lower_slices = &this->layer()->lower_layer->lslices; - if (this->layer()->upper_layer != NULL) - g.upper_slices = &this->layer()->upper_layer->lslices; - - int region_id = this->region().print_object_region_id(); - if (this->layer()->upper_layer != NULL) - g.upper_slices_same_region = &this->layer()->upper_layer->get_region(region_id)->slices; - - g.layer_id = (int)this->layer()->id(); - g.ext_perimeter_flow = this->flow(frExternalPerimeter); - g.overhang_flow = this->bridging_flow(frPerimeter, object_config.thick_bridges); - g.solid_infill_flow = this->flow(frSolidInfill); - - if (this->layer()->object()->config().wall_generator.value == PerimeterGeneratorType::Arachne && !spiral_mode) - g.process_arachne(); - else - g.process_classic(); + // ORCA: on the top layer of a combined group all perimeters extrude with the whole group's + // height. On layers of a walls-only run (wall_combined_count()) the walls are generated with + // the run height on every run layer - so the fill boundaries line up with the walls printed + // once at the run top - and the wall extrusions of the layers below the top are dropped below. + // Shared by the main pass and the coarse-wall pass of split wall layer heights below. + const int region_id = this->region().print_object_region_id(); + auto generate_perimeters = [&](double height, const Layer *lower_layer, ExtrusionEntityCollection *perimeters, + ExtrusionEntityCollection *thin_fills, SurfaceCollection *surfaces, ExPolygons *no_overlap) { + PerimeterGenerator g( + // input: + &slices, + &compatible_regions, + height, + this->layer()->slice_z, + this->flow(frPerimeter, height), + &perimeter_config, + &this->layer()->object()->config(), + &print_config, + spiral_mode, + model_rotation_rad, + + // output: + perimeters, + thin_fills, + surfaces, + //BBS + no_overlap + ); + + // Detect overhangs / bridges against the layer below the whole combined group or wall run + // (wall_combined_lower_layer() == lower_layer for regular regions). + if (lower_layer != nullptr) + // Cummulative sum of polygons over all the regions. + g.lower_slices = &lower_layer->lslices; + if (this->layer()->upper_layer != NULL) { + g.upper_slices = &this->layer()->upper_layer->lslices; + g.upper_slices_same_region = &this->layer()->upper_layer->get_region(region_id)->slices; + } + + g.layer_id = (int)this->layer()->id(); + g.ext_perimeter_flow = this->flow(frExternalPerimeter, height); + g.overhang_flow = this->bridging_flow(frPerimeter, object_config.thick_bridges, 0, height); + // Overhangs of external / fully overhanging loops dispatch to the outer wall filament (GCode::process_layer() splits mixed perimeters); resolve their width against its nozzle. + // The filament id comes from the resolved perimeter_config (mixed-filament aware), not the raw region config. + g.ext_overhang_flow = this->bridging_flow(frPerimeter, object_config.thick_bridges, + (unsigned int)std::max(0, perimeter_config.outer_wall_filament_id.value), height); + g.solid_infill_flow = this->flow(frSolidInfill, height); + // Gap fill dispatches to the outer wall filament (LayerTools::extruder()); resolve its width against its nozzle. + g.gap_fill_flow = this->flow(frSolidInfill, height, (unsigned int)std::max(0, perimeter_config.outer_wall_filament_id.value)); + + if (this->layer()->object()->config().wall_generator.value == PerimeterGeneratorType::Arachne && !spiral_mode) + g.process_arachne(); + else + g.process_classic(); + }; + generate_perimeters(this->wall_combined_height(), this->wall_combined_lower_layer(), + &this->perimeters, &this->thin_fills, fill_surfaces, fill_no_overlap); + + // ORCA: walls-only pitch. The run layers below the top only generated their perimeters to + // carve fill boundaries consistent with the run; the walls themselves (and their thin fills / + // gap fills, which print with the walls) extrude once at the run top. + if (this->wall_combined_count() == 0) { + this->perimeters.clear(); + this->thin_fills.clear(); + } + + // ORCA: split wall layer heights. Inside a coarse run the pass above laid out both wall + // classes at the fine cadence; the coarse class prints on its own runs instead: drop its + // loops here and, on the run top, regenerate them once at the full coarse height with the + // layer below the run as overhang reference (their space stays reserved - the fine pass + // placed the remaining loops around them). Thin / gap fills and the fill boundaries stay + // with the fine pass; the coarse pass's copies are scratch. Outside a committed coarse run + // the coarse class simply follows the fine cadence. + if (this->wall_split_height() > 0. && ! this->perimeters.empty()) { + unsigned int fine = 0, coarse = 0; + bool coarse_is_outer = false; + if (this->layer()->object()->wall_split_pitches(this->region(), fine, coarse, coarse_is_outer)) { + remove_wall_class(this->perimeters, coarse_is_outer); + if (this->wall_split_count() > 1) { + ExtrusionEntityCollection coarse_perimeters, scratch_thin_fills; + SurfaceCollection scratch_surfaces; + ExPolygons scratch_no_overlap; + generate_perimeters(this->wall_split_height(), this->wall_split_lower_layer(), + &coarse_perimeters, &scratch_thin_fills, &scratch_surfaces, &scratch_no_overlap); + remove_wall_class(coarse_perimeters, ! coarse_is_outer); + this->perimeters.append(std::move(coarse_perimeters.entities)); + } + } + } } #if 1 diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp index 1bc118fe6c0..ef5c1e6b54e 100644 --- a/src/libslic3r/PerimeterGenerator.cpp +++ b/src/libslic3r/PerimeterGenerator.cpp @@ -197,10 +197,14 @@ static ExtrusionEntityCollection traverse_loops(const PerimeterGenerator &perime // outside the grown lower slices (thus where the distance between // the loop centerline and original lower slices is >= half nozzle diameter if (remain_polines.size() != 0) { - extrusion_paths_append(paths, std::move(remain_polines), - erOverhangPerimeter, perimeter_generator.mm3_per_mm_overhang(), - perimeter_generator.overhang_flow.width(), - perimeter_generator.overhang_flow.height()); + // External / fully overhanging loops (no supported path at all) dispatch to the outer wall filament (GCode::process_layer()); their overhangs use that filament's flow. + const bool overhang_external = is_external || paths.empty(); + const Flow &loop_overhang_flow = overhang_external ? perimeter_generator.ext_overhang_flow : + perimeter_generator.overhang_flow; + extrusion_paths_append(paths, std::move(remain_polines), erOverhangPerimeter, + overhang_external ? perimeter_generator.ext_mm3_per_mm_overhang() : + perimeter_generator.mm3_per_mm_overhang(), + loop_overhang_flow.width(), loop_overhang_flow.height()); } // Reapply the nearest point search for starting point. @@ -481,8 +485,13 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p // get overhang paths by checking what parts of this loop fall // outside the grown lower slices (thus where the distance between // the loop centerline and original lower slices is >= half nozzle diameter + // External / fully overhanging extrusions (no supported path at all) dispatch to the outer + // wall filament (GCode::process_layer()); their overhangs use that filament's flow. Known + // corner: a fully overhanging fragment of the ExtrusionMultiPath split below keeps the inner + // flow, but widths come from the Arachne junctions either way; only thick-bridge height differs. + const bool overhang_external = is_external || paths.empty(); extrusion_paths_append(paths, clip_extrusion(extrusion_path, lower_slices_paths, ClipperLib_Z::ctDifference), erOverhangPerimeter, - perimeter_generator.overhang_flow); + overhang_external ? perimeter_generator.ext_overhang_flow : perimeter_generator.overhang_flow); // Reapply the nearest point search for starting point. // We allow polyline reversal because Clipper may have randomly reversed polylines during clipping. @@ -1274,8 +1283,9 @@ void PerimeterGenerator::apply_extra_perimeters(ExPolygons &infill_area) if (!m_spiral_vase && this->lower_slices != nullptr && this->config->detect_overhang_wall && this->config->extra_perimeters_on_overhangs && this->config->wall_loops > 0 && this->layer_id > this->object_config->raft_layers) { // Generate extra perimeters on overhang areas, and cut them to these parts only, to save print time and material + // Pure erOverhangPerimeter entities dispatch to the outer wall filament, so use its flow. auto [extra_perimeters, filled_area] = generate_extra_perimeters_over_overhangs(infill_area, this->lower_slices_polygons(), - this->config->wall_loops, this->overhang_flow, + this->config->wall_loops, this->ext_overhang_flow, this->m_scaled_resolution, *this->object_config, *this->print_config); if (!extra_perimeters.empty()) { @@ -1349,6 +1359,7 @@ void PerimeterGenerator::process_classic() // overhang perimeters m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm(); + m_ext_mm3_per_mm_overhang = this->ext_overhang_flow.mm3_per_mm(); // solid infill coord_t solid_infill_spacing = this->solid_infill_flow.scaled_spacing(); @@ -1857,7 +1868,8 @@ void PerimeterGenerator::process_classic() if (! polylines.empty()) { ExtrusionEntityCollection gap_fill; - variable_width(polylines, erGapFill, this->solid_infill_flow, gap_fill.entities); + // Gap fill prints with the outer wall filament (LayerTools::extruder()). + variable_width(polylines, erGapFill, this->gap_fill_flow, gap_fill.entities); /* Make sure we don't infill narrow parts that are already gap-filled (we only consider this surface's gaps to reduce the diff() complexity). Growing actual extrusions ensures that gaps not filled by medial axis @@ -2368,6 +2380,7 @@ void PerimeterGenerator::process_arachne() coord_t ext_perimeter_spacing2 = scaled(0.5f * (this->ext_perimeter_flow.spacing() + this->perimeter_flow.spacing())); // overhang perimeters m_mm3_per_mm_overhang = this->overhang_flow.mm3_per_mm(); + m_ext_mm3_per_mm_overhang = this->ext_overhang_flow.mm3_per_mm(); // solid infill coord_t solid_infill_spacing = this->solid_infill_flow.scaled_spacing(); diff --git a/src/libslic3r/PerimeterGenerator.hpp b/src/libslic3r/PerimeterGenerator.hpp index e4f918d8bd7..a8d989248ef 100644 --- a/src/libslic3r/PerimeterGenerator.hpp +++ b/src/libslic3r/PerimeterGenerator.hpp @@ -84,7 +84,11 @@ class PerimeterGenerator { Flow perimeter_flow; Flow ext_perimeter_flow; Flow overhang_flow; + // Overhangs of external / fully overhanging loops print with the outer wall filament (GCode::process_layer() splits mixed perimeters by filament), whose nozzle may differ. + Flow ext_overhang_flow; Flow solid_infill_flow; + // Gap fill prints with the outer wall filament (LayerTools::extruder()), whose nozzle may differ from the internal solid infill filament's. + Flow gap_fill_flow; const PrintRegionConfig *config; const PrintObjectConfig *object_config; const PrintConfig *print_config; @@ -129,13 +133,13 @@ class PerimeterGenerator { ExPolygons* fill_no_overlap) : slices(slices), compatible_regions(compatible_regions), upper_slices(nullptr), lower_slices(nullptr), layer_height(layer_height), slice_z(slice_z), layer_id(-1), perimeter_flow(flow), ext_perimeter_flow(flow), - overhang_flow(flow), solid_infill_flow(flow), + overhang_flow(flow), ext_overhang_flow(flow), solid_infill_flow(flow), gap_fill_flow(flow), config(config), object_config(object_config), print_config(print_config), m_spiral_vase(spiral_mode), m_scaled_resolution(scaled(print_config->resolution.value > EPSILON ? print_config->resolution.value : EPSILON)), m_model_rotation_rad(model_rotation_rad), loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces), fill_no_overlap(fill_no_overlap), - m_ext_mm3_per_mm(-1), m_mm3_per_mm(-1), m_mm3_per_mm_overhang(-1), m_ext_mm3_per_mm_smaller_width(-1) + m_ext_mm3_per_mm(-1), m_mm3_per_mm(-1), m_mm3_per_mm_overhang(-1), m_ext_mm3_per_mm_overhang(-1), m_ext_mm3_per_mm_smaller_width(-1) {} void process_classic(); @@ -146,6 +150,7 @@ class PerimeterGenerator { double ext_mm3_per_mm() const { return m_ext_mm3_per_mm; } double mm3_per_mm() const { return m_mm3_per_mm; } double mm3_per_mm_overhang() const { return m_mm3_per_mm_overhang; } + double ext_mm3_per_mm_overhang() const { return m_ext_mm3_per_mm_overhang; } //BBS double smaller_width_ext_mm3_per_mm() const { return m_ext_mm3_per_mm_smaller_width; } Polygons lower_slices_polygons() const { return m_lower_slices_polygons; } @@ -163,6 +168,7 @@ class PerimeterGenerator { double m_ext_mm3_per_mm; double m_mm3_per_mm; double m_mm3_per_mm_overhang; + double m_ext_mm3_per_mm_overhang; //BBS double m_ext_mm3_per_mm_smaller_width; Polygons m_lower_slices_polygons; diff --git a/src/libslic3r/Preset.cpp b/src/libslic3r/Preset.cpp index 6e594cdb6d6..9ddde1698ee 100644 --- a/src/libslic3r/Preset.cpp +++ b/src/libslic3r/Preset.cpp @@ -1195,7 +1195,7 @@ static std::vector s_Preset_print_options{ // BBS "print_extruder_id", "print_extruder_variant", - "independent_support_layer_height", + "independent_support_layer_height", "support_layer_height_step", "support_angle", "support_interface_top_layers", "support_interface_bottom_layers", @@ -1223,6 +1223,9 @@ static std::vector s_Preset_print_options{ "top_surface_filament_id", "bottom_surface_filament_id", "support_filament", + "support_nozzle_diameter", + "support_base_material", + "support_interface_material", "support_interface_filament", "support_interface_not_for_body", "ooze_prevention", @@ -1286,6 +1289,12 @@ static std::vector s_Preset_print_options{ "precise_z_height", "infill_combination", "infill_combination_max_layer_height", /*"adaptive_layer_height",*/ + // ORCA: per-extruder layer height ("extruder_layer_height"). + "extruder_layer_height_mode", + "extruder_layer_height_tolerance", + "split_wall_adjust", + "split_wall_adjust_filament", + "split_wall_adjust_direction", "support_bottom_interface_spacing", "enable_overhang_speed", "slowdown_for_curled_perimeters", @@ -4009,17 +4018,17 @@ std::vector PresetCollection::merge_presets(PresetCollection &&othe } m_presets.emplace(it, std::move(preset)); } else { + // Take the name first: the Snapmaker-wins branch moves the preset away. + std::string preset_name = preset.name; std::string default_vendor = std::string(PresetBundle::SM_BUNDLE); - if (preset.vendor->name == default_vendor) { - if (preset.vendor != nullptr) { - // Re-assign a pointer to the vendor structure in the new PresetBundle. - auto it = new_vendors.find(preset.vendor->id); - assert(it != new_vendors.end()); - preset.vendor = &it->second; - } + if (preset.vendor != nullptr && preset.vendor->name == default_vendor) { + // Re-assign a pointer to the vendor structure in the new PresetBundle. + auto it_vendor = new_vendors.find(preset.vendor->id); + assert(it_vendor != new_vendors.end()); + preset.vendor = &it_vendor->second; m_presets.emplace(it, std::move(preset)); } - duplicates.emplace_back(std::move(preset.name)); + duplicates.emplace_back(std::move(preset_name)); } } diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp index 1e83dc2baf2..df8dfa76ff8 100644 --- a/src/libslic3r/Print.cpp +++ b/src/libslic3r/Print.cpp @@ -754,6 +754,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "filament_shrinkage_compensation_z" || opt_key == "resolution" || opt_key == "precise_z_height" + // ORCA: layer combining for thicker extruder layer heights happens at the slicing step. + || opt_key == "extruder_layer_height" || opt_key == "dithering_z_step_size" || opt_key == "dithering_local_z_mode" || opt_key == "dithering_local_z_whole_objects" @@ -869,11 +871,24 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n ) { steps.emplace_back(psWipeTower); steps.emplace_back(psSkirtBrim); + if ((opt_key == "enable_prime_tower" || opt_key == "single_extruder_multi_material") && m_config.independent_support_layer_height.value) { + // The support layer height plan depends on both: supports align to the object + // grid under the tower and keep whole steps under single-extruder multi-material. + osteps.emplace_back(posSupportMaterial); + osteps.emplace_back(posSimplifySupportPath); + } + } else if (opt_key == "timelapse_type") { + // Print-level: everything (the key used to reach the catch-all below); object-level: + // the support layer plan gates fractional boundaries on smooth timelapse. + invalidated |= this->invalidate_all_steps(); + osteps.emplace_back(posSupportMaterial); + osteps.emplace_back(posSimplifySupportPath); } else if (opt_key == "filament_soluble" || opt_key == "filament_is_support" || opt_key == "filament_printable" || opt_key == "filament_change_length" - || opt_key == "independent_support_layer_height") { + || opt_key == "independent_support_layer_height" + || opt_key == "support_layer_height_step") { steps.emplace_back(psWipeTower); // Soluble support interface / non-soluble base interface produces non-soluble interface layers below soluble interface layers. // Thus switching between soluble / non-soluble interface layer material may require recalculation of supports. @@ -889,6 +904,9 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n || opt_key == "enable_arc_fitting" || opt_key == "print_order" || opt_key == "wall_sequence") { + // The min / max layer height limits gate layer combining at the slicing step (see region_layer_height_multiplier()), so re-slice while per-extruder layer heights are active. + if ((opt_key == "min_layer_height" || opt_key == "max_layer_height") && has_extruder_layer_heights(m_config)) + osteps.emplace_back(posSlice); osteps.emplace_back(posPerimeters); osteps.emplace_back(posEstimateCurledExtrusions); osteps.emplace_back(posInfill); @@ -993,20 +1011,19 @@ std::vector Print::support_material_extruders() const for (PrintObject *object : m_objects) { if (object->has_support_material()) { - assert(object->config().support_filament >= 0); - if (object->config().support_filament == 0) - support_uses_current_extruder = true; - else { - unsigned int i = (unsigned int)object->config().support_filament - 1; - extruders.emplace_back((i >= num_extruders) ? 0 : i); - } - assert(object->config().support_interface_filament >= 0); - if (object->config().support_interface_filament == 0) - support_uses_current_extruder = true; - else { - unsigned int i = (unsigned int)object->config().support_interface_filament - 1; - extruders.emplace_back((i >= num_extruders) ? 0 : i); - } + // Under support restrictions (nozzle diameter, material) a "default" (0) support filament resolves to a passing filament: one of the object's own or the deterministic fallback. + auto add_support_filament = [&](int configured, bool interface_role) { + assert(configured >= 0); + const unsigned int resolved_default = object->resolved_default_support_filament(interface_role); + if (configured == 0 && resolved_default == 0) { + support_uses_current_extruder = true; + } else { + unsigned int i = (configured > 0 ? (unsigned int)configured : resolved_default) - 1; + extruders.emplace_back((i >= num_extruders) ? 0 : i); + } + }; + add_support_filament(object->config().support_filament, false); + add_support_filament(object->config().support_interface_filament, true); } } @@ -2124,6 +2141,15 @@ StringObjectException Print::validate(std::vector *warnin } return true; }; + // ORCA: the per-extruder layer height / support nozzle diagnostics below report through the + // outer warn() helper. Orca replaced validate()'s single StringObjectException out-param with + // a std::vector, so each diagnostic is now a separate warning entry + // instead of being concatenated into one string. + // Flags for the per-extruder layer height / support nozzle warnings below. + bool warned_wall_pref_conflicts = false, warned_wall_adjustments = false; + bool warned_unhonored_heights = false, warned_support_mixed_nozzles = false, + warned_below_min_heights = false, warned_pitch_fallbacks = false, + warned_above_max_heights = false, warned_ignored_feature_prefs = false; for (PrintObject *object : m_objects) { if (object->has_support_material()) { // BBS: remove useless logics and L() @@ -2145,6 +2171,47 @@ StringObjectException Print::validate(std::vector *warnin } #endif + // ORCA: multi-nozzle support restriction ("support_nozzle_diameter"). + if (const double support_nozzle = object->config().support_nozzle_diameter.value; support_nozzle > 0.) { + if (std::none_of(m_config.nozzle_diameter.values.begin(), m_config.nozzle_diameter.values.end(), + [support_nozzle](double d) { return std::abs(d - support_nozzle) < EPSILON; })) + return {L("No extruder has a nozzle matching the support nozzle diameter."), object, "support_nozzle_diameter"}; + if (object->config().support_filament.value > 0 && + std::abs(m_config.nozzle_diameter.get_at(object->config().support_filament.value - 1) - support_nozzle) > EPSILON) + return {L("The support/raft base filament prints with a nozzle that does not match the support nozzle diameter."), object, "support_filament"}; + if (object->config().support_interface_filament.value > 0 && + std::abs(m_config.nozzle_diameter.get_at(object->config().support_interface_filament.value - 1) - support_nozzle) > EPSILON) + return {L("The support/raft interface filament prints with a nozzle that does not match the support nozzle diameter."), object, "support_interface_filament"}; + } else if (! warned_support_mixed_nozzles && max_nozzle_diameter - min_nozzle_diameter > EPSILON && + (object->config().support_filament.value == 0 || object->config().support_interface_filament.value == 0)) { + // Supports left on the "default" filament follow the active extruder, mixing nozzle sizes. + warn(L("Support may print with extruders of differing nozzle diameters. Set the support " + "nozzle diameter (or explicit support and interface filaments) to keep the support " + "on one nozzle size."), "support_nozzle_diameter", object); + warned_support_mixed_nozzles = true; + } + + // ORCA: support material selections ("support_base_material" / "support_interface_material") + // exclude filaments of other types; a selection must leave at least one usable filament and + // agree with an explicitly selected support filament. + for (const bool interface_role : {false, true}) { + if ((interface_role ? object->config().support_interface_material : + object->config().support_base_material).value.empty()) + continue; + if (object->resolved_default_support_filament(interface_role) == 0) + return {interface_role ? + L("No loaded filament matches the support/raft interface material (and the support nozzle diameter).") : + L("No loaded filament matches the support/raft base material (and the support nozzle diameter)."), + object, interface_role ? "support_interface_material" : "support_base_material"}; + if (const int configured = (interface_role ? object->config().support_interface_filament : + object->config().support_filament).value; + configured > 0 && ! object->support_filament_allowed((unsigned int)configured, interface_role)) + return {interface_role ? + L("The support/raft interface filament is not of the support/raft interface material.") : + L("The support/raft base filament is not of the support/raft base material."), + object, interface_role ? "support_interface_filament" : "support_filament"}; + } + // Prusa: Fixing crashes with invalid tip diameter or branch diameter // https://github.com/prusa3d/PrusaSlicer/commit/96b3ae85013ac363cd1c3e98ec6b7938aeacf46d if (is_tree(object->config().support_type.value)) { @@ -2201,9 +2268,13 @@ StringObjectException Print::validate(std::vector *warnin size_t first_layer_extruder = object->config().raft_layers == 1 ? object->config().support_interface_filament-1 : object->config().support_filament-1; - first_layer_min_nozzle_diameter = (first_layer_extruder == size_t(-1)) ? - min_nozzle_diameter : - m_config.nozzle_diameter.get_at(first_layer_extruder); + if (first_layer_extruder == size_t(-1) && object->config().support_nozzle_diameter.value > 0.) + // ORCA: a "default" support filament under the restriction prints the raft with the restricted nozzle. + first_layer_min_nozzle_diameter = object->config().support_nozzle_diameter.value; + else + first_layer_min_nozzle_diameter = (first_layer_extruder == size_t(-1)) ? + min_nozzle_diameter : + m_config.nozzle_diameter.get_at(first_layer_extruder); } else { // if we don't have raft layers, any nozzle diameter is potentially used in first layer first_layer_min_nozzle_diameter = min_nozzle_diameter; @@ -2229,6 +2300,477 @@ StringObjectException Print::validate(std::vector *warnin if (!validate_extrusion_width(region.config(), opt_key, layer_height, err_msg)) return {err_msg, object, opt_key}; + // ORCA: per-extruder layer height ("extruder_layer_height"). + if (layer_height > EPSILON) { + // Gates diagnostics that would otherwise fire for configurations not using the feature. + const bool heights_feature_active = has_extruder_layer_heights(m_config); + bool object_has_combined_regions = false; + for (const PrintRegion ®ion : object->all_regions()) { + const PrintRegionConfig ®ion_config = region.config(); + // Filaments allowed to define the part's layer pitch: its walls, or - when no wall + // filament carries an explicit preference - the region's other pitch-bound feature + // filaments. Must match the gating of PrintObject::region_layer_height_multiplier(). + std::vector lattice_filaments; // 0-based + bool pitch_from_features = false; + bool wall_prefs_disagree = false; + // false = a mixed (virtual) filament rotates physical extruders per layer, no pitch applies. + const bool no_mixed = object->collect_region_pitch_filaments(region_config, lattice_filaments, pitch_from_features); + // Multiple of the object layer height a preferred height conforms to, 0 when it does + // not conform (not an integer multiple, below the object layer height, or too tall + // for the extruder's bore). Min/max layer heights are soft profile limits - exceeding + // them keeps the pitch and warns below; with stock profiles the max layer height + // would otherwise reject every legal preference (the smallest being 2 * layer height). + auto conforming_multiplier = [&](double height, size_t extruder_idx) -> unsigned int { + const int n = int(std::lround(height / layer_height)); + return height >= layer_height - EPSILON && std::abs(height - n * layer_height) <= EPSILON && + height <= m_config.nozzle_diameter.get_at(extruder_idx) + EPSILON ? + (unsigned int)std::max(1, n) : 0; + }; + unsigned int region_multiplier = 0; + for (const unsigned int filament : lattice_filaments) { + const size_t extruder_idx = this->extruder_index_of(filament); + const double extruder_height = m_config.extruder_layer_height.get_at(extruder_idx); + if (extruder_height <= 0.) + continue; // no preference (0 = object layer height): follows the others + const unsigned int multiplier = conforming_multiplier(extruder_height, extruder_idx); + if (multiplier == 0) { + if (pitch_from_features) { + // Feature filaments only offer a pitch: a preference the part cannot print + // is skipped by the engine; tell the user why it has no effect. + if (! warned_ignored_feature_prefs) { + warned_ignored_feature_prefs = true; + warn(Slic3r::format(_u8L("The layer height of extruder %1% (%2% mm) is ignored for some object parts: it must be an " + "integer multiple of the object layer height (%3% mm), not below it, and must not exceed the " + "extruder's nozzle diameter."), + extruder_idx + 1, extruder_height, layer_height), + "extruder_layer_height", object); + } + continue; + } + // The wall filaments dictate the part's layer pitch, their preferences are strict. + if (extruder_height < layer_height - EPSILON) + return { Slic3r::format(_u8L("The layer height of extruder %1% (%2% mm) is smaller than the object layer height (%3% mm). " + "Lower the object layer height to the finest extruder layer height."), + extruder_idx + 1, extruder_height, layer_height), object, "extruder_layer_height" }; + if (std::abs(extruder_height - std::lround(extruder_height / layer_height) * layer_height) > EPSILON) + return { Slic3r::format(_u8L("The layer height of extruder %1% (%2% mm) must be an integer multiple of the object layer height (%3% mm)."), + extruder_idx + 1, extruder_height, layer_height), object, "extruder_layer_height" }; + return { Slic3r::format(_u8L("The layer height of extruder %1% (%2% mm) cannot exceed its nozzle diameter."), + extruder_idx + 1, extruder_height), object, "extruder_layer_height" }; + } + if (pitch_from_features && multiplier <= 1) + continue; // a preference equal to the object layer height offers nothing + if (region_multiplier == 0) + region_multiplier = multiplier; + else if (region_multiplier != multiplier) { + // These features print together; differing explicit preferences fall + // back from the whole-part pitch (the walls-only pitch below may still + // meet at the lower preference; warned after it is known). + if (! pitch_from_features) + wall_prefs_disagree = true; + region_multiplier = 1; + break; + } + } + if (region_multiplier == 0 || ! no_mixed) + region_multiplier = 1; + const bool solid_combined_infill = std::fabs(region_config.sparse_infill_density.value - 100.) < EPSILON; + auto selector_extruder_idx = [&](int filament_id) { return this->extruder_index_of(feature_filament_idx(filament_id)); }; + auto prints_nothing = [&](unsigned int filament) { return PrintObject::region_filament_prints_nothing(region_config, filament); }; + // Inner-wall loops can appear at a single wall loop too (alternate / extra walls, + // see PrintObject::region_prints_inner_walls()). + auto prints_outer_wall = [&](unsigned int filament) { + return region_config.wall_loops.value > 0 && + filament == feature_filament_idx(region_config.outer_wall_filament_id.value); + }; + auto prints_inner_wall = [&](unsigned int filament) { + return region_config.wall_loops.value > 0 && PrintObject::region_prints_inner_walls(region_config) && + filament == feature_filament_idx(region_config.inner_wall_filament_id.value); + }; + auto prints_walls = [&](unsigned int filament) { + return prints_outer_wall(filament) || prints_inner_wall(filament); + }; + auto prints_top = [&](unsigned int filament) { + return region_config.top_shell_layers.value > 0 && + filament == feature_filament_idx(region_config.top_surface_filament_id.value); + }; + auto prints_bottom = [&](unsigned int filament) { + return region_config.bottom_shell_layers.value > 0 && + filament == feature_filament_idx(region_config.bottom_surface_filament_id.value); + }; + auto prints_solid = [&](unsigned int filament) { + return ! solid_combined_infill && filament == feature_filament_idx(region_config.internal_solid_filament_id.value); + }; + // Mirrors PrintObject::combine_top_surfaces(): a conforming preferred pitch of a + // full-density top surface absorbs the solid layers below whenever the region itself + // prints at the object layer height. Geometry decides per area, so this gates + // warnings only. Mixed (virtual) filament ids never combine. + unsigned int top_candidate = 1; + if (region_config.top_shell_layers.value > 0 && + region_config.top_surface_density.value >= 100. - EPSILON && + std::max(0, region_config.top_surface_filament_id.value - 1) < (int)m_config.filament_diameter.size()) { + const size_t top_extruder_idx = selector_extruder_idx(region_config.top_surface_filament_id.value); + const unsigned int m = conforming_multiplier(m_config.extruder_layer_height.get_at(top_extruder_idx), top_extruder_idx); + if (m > 1) + top_candidate = m; + } + // Mirrors PrintObject::combine_internal_solid_infill(): a conforming preferred + // pitch of the internal solid filament combines the leftover solid interior + // whenever the region itself prints at the object layer height (at 100% density + // the solid interior is the combined infill instead). Geometry decides per + // area, so this gates warnings only. + unsigned int solid_candidate = 1; + if (! solid_combined_infill) { + const size_t solid_extruder_idx = selector_extruder_idx(region_config.internal_solid_filament_id.value); + const unsigned int m = conforming_multiplier(m_config.extruder_layer_height.get_at(solid_extruder_idx), solid_extruder_idx); + if (m > 1) + solid_candidate = m; + } + // Walls-only pitch (mirrors PrintObject::wall_layer_height_multiplier()): when the + // rest of the part vetoes the walls' pitch, the walls still combine to it on their + // own. Non-splittable effective preferences meet at the lower one; preference-less + // wall filaments follow, but every wall filament must fit the pitch through its bore. + unsigned int eff_outer = 0, eff_inner = 0; + object->wall_effective_multipliers(region, eff_outer, eff_inner); + // Which wall class prints an adjusted height ("split_wall_adjust") instead of its + // filament's own preference - the adjustment is deliberate, so the conflict and + // unhonored-heights warnings below stay silent about it. + auto raw_wall_multiplier = [&](int filament_id) -> unsigned int { + const unsigned int filament = (unsigned int)std::max(0, filament_id); + return object->extruder_preferred_layer_height(filament) > 0. ? + object->layer_height_multiplier_for_filament(filament) : 0; + }; + const bool adjusted_outer = eff_outer != 0 && + eff_outer != raw_wall_multiplier(region_config.outer_wall_filament_id.value); + const bool adjusted_inner = eff_inner != 0 && + eff_inner != raw_wall_multiplier(region_config.inner_wall_filament_id.value); + unsigned int wall_candidate = eff_outer == 0 || eff_inner == 0 ? std::max(eff_outer, eff_inner) : + std::min(eff_outer, eff_inner); + if (wall_candidate > 1) { + const double p = wall_candidate * layer_height; + if (p > m_config.nozzle_diameter.get_at(selector_extruder_idx(region_config.outer_wall_filament_id.value)) + EPSILON || + (PrintObject::region_prints_inner_walls(region_config) && + p > m_config.nozzle_diameter.get_at(selector_extruder_idx(region_config.inner_wall_filament_id.value)) + EPSILON)) + wall_candidate = 1; + } + if (wall_candidate == 0) + wall_candidate = 1; + // Split wall layer heights (mirrors PrintObject::wall_split_pitches()): each + // wall class prints at its own pitch, so the min-merge conflict warning stays + // silent and the per-class checks below use each class's real height. + unsigned int split_fine = 0, split_coarse = 0; + bool split_coarse_outer = false; + const bool wall_split = region_multiplier == 1 && + object->wall_split_pitches(region, split_fine, split_coarse, split_coarse_outer); + // 0-based indices of all filaments printing this region's features. + std::vector used_filaments; + PrintRegion::collect_object_printing_extruders(m_config, region_config, false /* has_brim */, used_filaments); + if (region_multiplier > 1) + // Only a nozzle that physically cannot extrude the part's pitch vetoes it; + // exceeding a max layer height keeps the pitch and is warned about below + // (mirrors PrintObject::region_layer_height_multiplier()). + for (const unsigned int filament : used_filaments) { + if (prints_nothing(filament)) + // The inert 100%-density sparse selector must not veto the pitch. + continue; + const size_t extruder_idx = this->extruder_index_of(filament); + const double pitch = region_multiplier * layer_height; + if (pitch > m_config.nozzle_diameter.get_at(extruder_idx) + EPSILON) { + // Stay silent when the pitch survives anyway - as the walls' own + // walls-only pitch or a combining top surface's pitch; the + // unhonored-heights warning covers the rest. + if (! warned_pitch_fallbacks && + (pitch_from_features ? top_candidate != region_multiplier : + wall_candidate != region_multiplier)) { + warned_pitch_fallbacks = true; + if (prints_walls(filament)) + // Blocked by the walls' own bore: outer and inner walls + // print together, both filaments must fit the pitch. + warn(Slic3r::format(_u8L("Some object parts prefer %1% mm layers, but the nozzle of wall " + "filament %2% is too small to extrude that height. Outer and inner " + "walls print together, so these walls keep the object layer height. " + "Assign both wall features to filaments with large enough nozzles."), + pitch, filament + 1), + "extruder_layer_height", object); + else + warn(Slic3r::format(_u8L("Some object parts prefer %1% mm layers, but the nozzle of filament %2% " + "printing other features of the part is too small to extrude that height. " + "These parts print with the object layer height instead."), + pitch, filament + 1), + "extruder_layer_height", object); + } + region_multiplier = 1; + break; + } + } + // The walls combine on their own only while the region prints at the object layer height. + const unsigned int wall_multiplier = region_multiplier == 1 ? wall_candidate : 1; + // Tell the user once what the "split_wall_adjust" adjustment settled on. + if ((adjusted_outer || adjusted_inner) && ! warned_wall_adjustments) { + warned_wall_adjustments = true; + const int adjusted_id = adjusted_outer ? region_config.outer_wall_filament_id.value : + region_config.inner_wall_filament_id.value; + warn(Slic3r::format(_u8L("The wall layer height of filament %1% was adjusted from the preferred %2% mm to " + "%3% mm so the outer and inner walls can print at compatible layer heights " + "(\"Adjust wall layer height\"). Only this filament's walls print the adjusted " + "height; its other features keep the preferred one."), + feature_filament_idx(adjusted_id) + 1, + object->extruder_preferred_layer_height((unsigned int)std::max(0, adjusted_id)), + (adjusted_outer ? eff_outer : eff_inner) * layer_height), + "split_wall_adjust", object); + } + // Disagreeing wall preferences: report what actually happens once the walls-only + // pitch is known - with every extruder carrying a preferred height, a wall + // selector left on "Default" resolves to the part's filament and its preference + // silently conflicts with the other wall's. An adjustment that made the heights + // compatible resolved the disagreement (reported above). + if (wall_prefs_disagree && ! wall_split && ! adjusted_outer && ! adjusted_inner && ! warned_wall_pref_conflicts) { + warned_wall_pref_conflicts = true; + if (wall_multiplier > 1) + warn(Slic3r::format(_u8L("The wall filaments of some object parts prefer different layer heights. " + "Outer and inner walls print together, so these walls print with the lower " + "height (%1% mm)."), + wall_multiplier * layer_height), + "extruder_layer_height", object); + else + warn(_u8L("The wall filaments of some object parts prefer different layer heights. " + "Outer and inner walls print together, so these walls keep the object layer " + "height. Assign both wall features to filaments preferring the same height " + "to print thicker walls."), + "extruder_layer_height", object); + } + // A pitch above a filament's max layer height keeps the pitch: max is a soft + // profile limit that the explicit preference overrides. Warn once. + auto warn_above_max = [&](double pitch, unsigned int filament0, double max_lh) { + if (warned_above_max_heights || max_lh <= EPSILON || pitch <= max_lh + EPSILON) + return; + warned_above_max_heights = true; + warn(Slic3r::format(_u8L("Some object parts print %1% mm layers with filament %2% whose maximum layer " + "height is %3% mm. Assign the part's features to filaments of the coarser " + "nozzle, raise the filament's maximum layer height, or accept printing above it."), + pitch, filament0 + 1, max_lh), + "extruder_layer_height", object); + }; + const double region_pitch = region_multiplier * layer_height; + // Heights the wall classes print at: the region pitch when the whole part + // combines, the walls-only pitch when the walls combine on their own, and + // each class's own pitch when the wall layer heights are split. + const double merged_wall_height = wall_multiplier > 1 ? wall_multiplier * layer_height : region_pitch; + const double outer_wall_height = wall_split ? (split_coarse_outer ? split_coarse : split_fine) * layer_height : merged_wall_height; + const double inner_wall_height = wall_split ? (split_coarse_outer ? split_fine : split_coarse) * layer_height : merged_wall_height; + if (region_multiplier > 1 || wall_multiplier > 1 || wall_split) + // With a walls-only or split pitch only the wall filaments print it, the + // others stay at the object layer height. + for (const unsigned int filament : used_filaments) { + double pitch = region_pitch; + if (region_multiplier == 1) { + if (! prints_walls(filament)) + continue; + pitch = prints_outer_wall(filament) ? outer_wall_height : inner_wall_height; + } + warn_above_max(pitch, filament, m_config.max_layer_height.get_at(this->extruder_index_of(filament))); + } + auto filament_nozzle = [&](int filament_id) { + return m_config.nozzle_diameter.get_at(selector_extruder_idx(filament_id)); + }; + // Explicit line width of a role resolved against its filament's nozzle; 0 = auto + // width, always considered valid (see validate_extrusion_width() above; the top + // surface auto width equals the nozzle diameter exactly, which must not hard-error + // an equal pitch). + auto resolve_line_width = [&](const char *width_key, double nozzle) -> double { + auto width_opt = *region_config.option(width_key); + if (width_opt.value == 0.) + width_opt = object->config().line_width; + return width_opt.value == 0. ? 0. : width_opt.get_abs_value(nozzle); + }; + // Infill combines up to the preferred height of its printing filament (sparse, or + // internal solid at 100% density; mirrors PrintObject::combine_infill()): groups + // are capped only by the bore of the printing nozzle, the max layer height is a + // soft limit the preference overrides. The width must cover the tallest group. + double combined_infill_height = 0.; + unsigned int combined_infill_filament = 0; // 0-based, only valid while combining + if (region_multiplier == 1 && region_config.sparse_infill_density.value > 0) { + const int filament_id = solid_combined_infill ? region_config.internal_solid_filament_id.value : + region_config.sparse_infill_filament_id.value; + const FlowRole role = solid_combined_infill ? frSolidInfill : frInfill; + const char *width_key = solid_combined_infill ? "internal_solid_infill_line_width" : "sparse_infill_line_width"; + const double preferred = object->extruder_preferred_layer_height((unsigned int)std::max(0, filament_id)); + if (preferred > layer_height + EPSILON) { + const unsigned int combine_filament0 = feature_filament_idx(filament_id); + const size_t combine_extruder_idx = this->extruder_index_of(combine_filament0); + const double combine_cap = std::min(preferred, m_config.nozzle_diameter.get_at(combine_extruder_idx)); + combined_infill_height = std::floor(combine_cap / layer_height + EPSILON) * layer_height; + combined_infill_filament = combine_filament0; + warn_above_max(combined_infill_height, combine_filament0, m_config.max_layer_height.get_at(combine_extruder_idx)); + const double infill_nozzle = filament_nozzle((int)region.extruder(role)); + double width = resolve_line_width(width_key, infill_nozzle); + if (width == 0.) + width = double(Flow::auto_extrusion_width(role, float(infill_nozzle))); + if (combined_infill_height > layer_height + EPSILON && width <= combined_infill_height + EPSILON) + return { Slic3r::format(_u8L("The %1% mm infill line width is too small for infill combined to %2% mm high layers. " + "Increase the line width or lower the preferred layer height of the infill filament."), + width, combined_infill_height), object, width_key }; + } + } + // The combined infill is not pitch-bound: a filament printing it AND a pitch-bound + // feature is not fully covered by the combined height (at 100% density the internal + // solid infill IS the combined infill). + auto prints_pitch_features = [&](unsigned int filament) { + return prints_walls(filament) || prints_top(filament) || prints_bottom(filament) || prints_solid(filament); + }; + // The top surfaces and the solid interior combine only while the region prints + // at the object layer height. + const unsigned int top_multiplier = region_multiplier == 1 ? top_candidate : 1; + if (top_multiplier > 1) + warn_above_max(top_multiplier * layer_height, + feature_filament_idx(region_config.top_surface_filament_id.value), + m_config.max_layer_height.get_at(selector_extruder_idx(region_config.top_surface_filament_id.value))); + const unsigned int solid_multiplier = region_multiplier == 1 ? solid_candidate : 1; + if (solid_multiplier > 1) + warn_above_max(solid_multiplier * layer_height, + feature_filament_idx(region_config.internal_solid_filament_id.value), + m_config.max_layer_height.get_at(selector_extruder_idx(region_config.internal_solid_filament_id.value))); + // Heights the filament's pitch-bound features print at: walls at their class's + // pitch when active, top surfaces at the top pitch when active, everything else + // at the region pitch (also used by the unhonored-heights check below). + const double top_print_height = top_multiplier > 1 ? top_multiplier * layer_height : region_pitch; + const double solid_print_height = solid_multiplier > 1 ? solid_multiplier * layer_height : region_pitch; + auto lowest_feature_height = [&](unsigned int filament) { + double h = std::numeric_limits::max(); + if (prints_outer_wall(filament)) + h = std::min(h, outer_wall_height); + if (prints_inner_wall(filament)) + h = std::min(h, inner_wall_height); + if (prints_top(filament)) + h = std::min(h, top_print_height); + if (prints_bottom(filament)) + h = std::min(h, region_pitch); + if (prints_solid(filament)) + h = std::min(h, solid_print_height); + // No pitch-bound feature (e.g. the sparse filament): prints at the region pitch. + return h == std::numeric_limits::max() ? region_pitch : h; + }; + // Warn once when a filament's minimum layer height is above the height its features + // print at (the combined infill prints above the minimum by construction). + if (! warned_below_min_heights && heights_feature_active) + for (const unsigned int filament : used_filaments) { + const double min_lh = m_config.min_layer_height.get_at(this->extruder_index_of(filament)); + if (min_lh <= EPSILON || prints_nothing(filament)) + continue; + const double lowest = lowest_feature_height(filament); + const bool pitch_below_min = lowest < min_lh - EPSILON; + // Areas of a combined region that cannot reach the pitch - and the first layer / + // fallback areas of a walls-only run or a combining top surface - fall back to + // the object layer height (see apply_extruder_layer_heights()), possibly below + // the minimum. + const bool fallback_below_min = (region_multiplier > 1 || + ((wall_multiplier > 1 || wall_split) && prints_walls(filament)) || + (top_multiplier > 1 && prints_top(filament)) || + (solid_multiplier > 1 && prints_solid(filament))) && + layer_height < min_lh - EPSILON; + if (! pitch_below_min && ! fallback_below_min) + continue; + if (combined_infill_height > 0. && filament == combined_infill_filament && + combined_infill_height >= min_lh - EPSILON && ! fallback_below_min && + ! prints_pitch_features(filament)) + continue; + warned_below_min_heights = true; + warn(Slic3r::format(_u8L("Some object parts print %1% mm layers with filament %2% whose minimum layer " + "height is %3% mm. Raise the object layer height, use a filament with a finer " + "nozzle for these features, or accept printing below the extruder's minimum."), + pitch_below_min ? lowest : layer_height, + filament + 1, min_lh), + "extruder_layer_height", object); + break; + } + // Warn once about preferred heights the part cannot honor: one pitch applies to the + // whole part, while walls, top surfaces and the infill can each combine to their own + // height. Walls and top surfaces rescued at their own pitches count as honored + // (geometry may still fall back per area; warned about is only what can never be + // honored). A filament also printing the combined infill is covered only when the + // infill reaches the preference too. + if (! warned_unhonored_heights) + for (const unsigned int filament : used_filaments) { + const double preferred = object->extruder_preferred_layer_height(filament + 1); + if (preferred <= 0. || prints_nothing(filament)) + continue; + const bool combined_covered = ! (combined_infill_height > 0. && filament == combined_infill_filament) || + combined_infill_height >= preferred - EPSILON; + if (prints_pitch_features(filament)) { + bool honored = combined_covered; + // An adjusted wall class prints its adjusted height on purpose + // (warned about above), not an unhonored preference. + if (prints_outer_wall(filament)) + honored &= adjusted_outer || std::abs(outer_wall_height - preferred) < EPSILON; + if (prints_inner_wall(filament)) + honored &= adjusted_inner || std::abs(inner_wall_height - preferred) < EPSILON; + if (prints_top(filament)) + honored &= std::abs(top_print_height - preferred) < EPSILON; + if (prints_bottom(filament)) + honored &= std::abs(region_pitch - preferred) < EPSILON; + if (prints_solid(filament)) + honored &= std::abs(solid_print_height - preferred) < EPSILON; + if (honored) + continue; + } else if (std::abs(preferred - region_pitch) < EPSILON || + (combined_infill_height > 0. && filament == combined_infill_filament && + combined_infill_height >= preferred - EPSILON)) { + // Not pitch-bound (the sparse filament): honored at the region pitch or + // by the combined infill reaching the preference. + continue; + } + warned_unhonored_heights = true; + warn(_u8L("Some object parts use filaments whose preferred layer heights cannot all be honored: " + "a part prints its features with one layer pitch (set by its wall filaments, or by the " + "other features' agreement when no wall filament has a preference); the walls, the top " + "surfaces and the infill can each combine to their own height when the rest of the part " + "cannot follow them, but the remaining features print with the part's pitch."), + "extruder_layer_height", object); + break; + } + if (region_multiplier > 1 || wall_multiplier > 1 || top_multiplier > 1 || solid_multiplier > 1 || wall_split) { + object_has_combined_regions = true; + // Combined extrusions are thicker: explicit line widths must stay above the + // height each feature prints at, resolved per role against the region's own + // nozzle (mirrors PrintRegion::flow(); validate_extrusion_width() above uses + // the object's smallest nozzle instead). Bottom surfaces print the solid + // infill width (Fill.cpp). Features the region does not print (e.g. sparse + // infill at 100% density) must not hard-error the pitch; features printing + // at the object layer height are skipped by the pitch test. + const std::tuple width_checks[] = { + { region_config.outer_wall_filament_id.value, "outer_wall_line_width", outer_wall_height, region_config.wall_loops.value > 0 }, + { region_config.inner_wall_filament_id.value, "inner_wall_line_width", inner_wall_height, region_config.wall_loops.value > 0 }, + { region_config.sparse_infill_filament_id.value, "sparse_infill_line_width", region_pitch, region_config.sparse_infill_density.value > 0 && ! solid_combined_infill }, + { region_config.internal_solid_filament_id.value, "internal_solid_infill_line_width", solid_print_height, true }, + { region_config.top_surface_filament_id.value, "top_surface_line_width", top_print_height, region_config.top_shell_layers.value > 0 }, + { region_config.bottom_surface_filament_id.value, "internal_solid_infill_line_width", region_pitch, region_config.bottom_shell_layers.value > 0 }, + }; + for (const auto &[filament_id, width_key, pitch, prints] : width_checks) { + if (! prints || pitch <= layer_height + EPSILON) + continue; + const double width = resolve_line_width(width_key, filament_nozzle(filament_id)); + if (width > 0. && width <= pitch + EPSILON) + return { Slic3r::format(_u8L("The %1% mm line width is too small for the %2% mm layer height of its extruder. " + "Increase the line width or lower the extruder layer height."), + width, pitch), object, width_key }; + } + } + } + if (object_has_combined_regions) { + if (m_config.spiral_mode) + return { _u8L("Per-extruder layer heights are not supported in spiral vase mode."), object, "extruder_layer_height" }; + if (object->config().interface_shells) + return { _u8L("Per-extruder layer heights are not supported together with interface shells."), object, "extruder_layer_height" }; + if (object->model_object()->has_custom_layering()) { + std::vector profile; + PrintObject::update_layer_height_profile(*object->model_object(), object->slicing_parameters(), profile, object); + if (! check_object_layers_fixed(object->slicing_parameters(), profile)) + return { _u8L("Per-extruder layer heights are not supported together with variable layer height."), + object, "extruder_layer_height" }; + } + } + } + // Orca: bridge line width sanity check. const bool allow_thin_bridge_width = object->config().thick_bridges && object->config().thick_internal_bridges; for (const PrintRegion ®ion : object->all_regions()) { @@ -3415,6 +3957,7 @@ 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 + // The result is optional (the CLI and tests pass none, see Slic3r::Test::gcode()). if (result != nullptr) { result->conflict_result = m_conflict_result; // Surface the slicer's per-filament nozzle grouping onto the post-slice result @@ -4693,13 +5236,31 @@ void Print::_make_wipe_tower() for (auto& layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers ++layer_idx; - if (!layer_tools.has_wipe_tower) continue; + if (!layer_tools.has_wipe_tower) { + // A layer without a tower slab (fractional support-only layer) still switches + // filaments through the plain toolchange path. Keep the plan's tool chain and + // filament bookkeeping in sync, so the next tower layer plans the switch back. + if (!layer_tools.extruders.empty()) { + used_filament_ids.insert(layer_tools.extruders.begin(), layer_tools.extruders.end()); + for (unsigned int filament_id : rotate_extruders_to_start_with(layer_tools.extruders, current_filament_id)) + if (auto nozzle = nozzle_group_result.get_nozzle_for_filament(filament_id, layer_idx)) + nozzle_recorder.set_nozzle_status(nozzle->group_id, filament_id, nozzle->extruder_id); + current_filament_id = rotate_extruders_to_start_with(layer_tools.extruders, current_filament_id).back(); + } + continue; + } bool first_layer = &layer_tools == &m_wipe_tower_data.tool_ordering.front(); wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, current_filament_id); + // Per-layer nozzle maps are indexed by this ordering's layer index, which no longer + // equals the tower's own layer index once fractional layers carry no slab. + wipe_tower.set_plan_layer_ordering_index(layer_idx); used_filament_ids.insert(layer_tools.extruders.begin(), layer_tools.extruders.end()); - for (const auto filament_id : layer_tools.extruders) { + // Mirrors GCode::process_layer, which rotates the layer's filaments to start with + // the one currently loaded (same as the Type2 branch below). + const std::vector layer_filaments = rotate_extruders_to_start_with(layer_tools.extruders, current_filament_id); + for (const auto filament_id : layer_filaments) { if (filament_id == current_filament_id) continue; @@ -4746,7 +5307,7 @@ void Print::_make_wipe_tower() wipe_volume_nc = 15.f; } - wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id, + wipe_tower.plan_toolchange((float)layer_tools.print_z, (float)layer_tools.wipe_tower_layer_height, current_filament_id, filament_id, wipe_volume_ec, wipe_volume_nc, volume_to_purge); current_filament_id = filament_id; } @@ -4851,8 +5412,14 @@ void Print::_make_wipe_tower() { unsigned int current_extruder_id = m_wipe_tower_data.tool_ordering.all_extruders().back(); for (auto &layer_tools : m_wipe_tower_data.tool_ordering.layer_tools()) { // for all layers - if (!layer_tools.has_wipe_tower) + if (!layer_tools.has_wipe_tower) { + // Keep the tool chain in sync across layers that switch filament without + // a tower slab (fractional support-only layers): emission rotates the + // layer to start with the loaded tool, so the last tool is the rotated back. + if (!layer_tools.extruders.empty()) + current_extruder_id = rotate_extruders_to_start_with(layer_tools.extruders, current_extruder_id).back(); continue; + } while (layers_to_print_idx + 1 < layers_to_print.size() && layers_to_print[layers_to_print_idx].first + EPSILON < layer_tools.print_z) { ++layers_to_print_idx; @@ -4893,6 +5460,8 @@ void Print::_make_wipe_tower() current_extruder_id = local_z_toolchanges.back().new_tool; } + // Mirrors GCode::process_layer, which rotates the layer's extruders to start + // with the tool currently loaded. const std::vector nominal_layer_extruders = rotate_extruders_to_start_with(layer_tools.extruders, current_extruder_id); diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp index 1d41fd8bf76..f0823d0f171 100644 --- a/src/libslic3r/Print.hpp +++ b/src/libslic3r/Print.hpp @@ -10,6 +10,7 @@ #include "Flow.hpp" #include "Point.hpp" #include "Slicing.hpp" +#include "Surface.hpp" #include "TriangleMeshSlicer.hpp" #include "GCode/ToolOrdering.hpp" #include "GCode/WipeTower.hpp" @@ -169,7 +170,9 @@ class PrintRegion ObjectID gradient_volume_id() const throw() { return m_gradient_volume_id; } // 1-based extruder identifier for this region and role. unsigned int extruder(FlowRole role) const; - Flow flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer = false) const; + // filament_id: 1-based filament actually printing this flow when it differs from the role's default + // mapping (top / bottom surface fills), 0 to resolve the filament from the role. + Flow flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer = false, unsigned int filament_id = 0) const; // Average diameter of nozzles participating on extruding this region. coordf_t nozzle_dmr_avg(const PrintConfig &print_config) const; // Average diameter of nozzles participating on extruding this region. @@ -510,6 +513,56 @@ class PrintObject : public PrintObjectBaseWithState object_extruders() const; + // ORCA: per-extruder layer height ("extruder_layer_height" printer option). + // Preferred layer height (mm) of the extruder printing the given 1-based filament id; 0 when unset or not reliably resolvable. + double extruder_preferred_layer_height(unsigned int filament_id) const; + // Object layers a region printing with the given 1-based filament id combines into one extrusion where its geometry allows it (1 = no combining). + unsigned int layer_height_multiplier_for_filament(unsigned int filament_id) const; + // 0-based filaments allowed to drive a region's layer pitch: its walls, or - when no wall filament carries an + // explicit layer height preference - its top/bottom/solid feature filaments. Returns false when the region + // involves a mixed (virtual) filament whose physical extruder varies per layer, in which case no pitch applies. + bool collect_region_pitch_filaments(const PrintRegionConfig &config, std::vector &filaments, bool &pitch_from_features) const; + // Layer pitch multiplier of a region, driven by its wall filaments; 1 when no combining is requested or possible. + unsigned int region_layer_height_multiplier(const PrintRegion ®ion) const; + // Do inner-wall loops print in this region? Besides wall_loops > 1, the alternating extra + // wall and the extra perimeters on overhangs add inner loops even at a single wall loop. + static bool region_prints_inner_walls(const PrintRegionConfig &config); + // Does the given 0-based filament print nothing in this region? True only for a sparse infill + // selector at 100% density (the solid interior belongs to the internal solid filament) that + // prints no other feature of the region. + static bool region_filament_prints_nothing(const PrintRegionConfig &config, unsigned int filament); + // Walls-only pitch multiplier: when the region as a whole cannot follow its wall filaments' + // preferred pitch (region_layer_height_multiplier() == 1, e.g. a finer-nozzle filament prints + // the region's other features), the walls alone combine to it while everything else keeps + // printing every layer. 1 when the walls print with the region's own pitch. + unsigned int wall_layer_height_multiplier(const PrintRegion ®ion) const; + // Effective wall pitch multipliers of the two wall classes: the conforming multipliers of + // their filaments' explicit preferred heights (0 = no explicit preference; inner_m is 0 when + // the region prints no inner walls), with the "split_wall_adjust" adjustment applied when the + // two do not divide evenly. Adjusted heights respect the filament's layer height limits. + // Returns false for mixed virtual wall filaments, which forbid wall combining. + bool wall_effective_multipliers(const PrintRegion ®ion, unsigned int &outer_m, unsigned int &inner_m) const; + // Split wall layer heights: true when the outer and inner walls print with their own pitches + // - both effective multipliers explicit, unequal, and the larger a whole multiple of the + // smaller. fine/coarse receive the two multipliers, coarse_is_outer which wall class prints + // the coarse one. Callers must only act on it while the region prints at the object layer + // height (region_layer_height_multiplier() == 1). + bool wall_split_pitches(const PrintRegion ®ion, unsigned int &fine, unsigned int &coarse, bool &coarse_is_outer) const; + // Any region of this object printing with a layer height multiplier > 1? + bool has_combined_layer_regions() const; + // Multi-nozzle support restrictions ("support_nozzle_diameter" plus the "support_base_material" / + // "support_interface_material" print options): may the given 1-based filament print this object's + // support / raft base (interface_role false) or interface (interface_role true)? A filament passes + // when its nozzle matches the support nozzle diameter and its type matches the role's material; + // an unset restriction does not exclude. Always true for the "default" filament 0. + bool support_filament_allowed(unsigned int filament_id, bool interface_role = false) const; + // Any support filament restriction configured (nozzle diameter or either material)? + bool has_support_filament_restriction() const; + // 1-based filament a "default" (0) support filament of the role resolves to when none of a layer's + // own filaments pass the restrictions: the first non-soluble passing filament, else the first + // passing one; 0 when the role is unrestricted or nothing passes. + unsigned int resolved_default_support_filament(bool interface_role = false) const; + // Called by make_perimeters() void slice(); @@ -587,6 +640,8 @@ class PrintObject : public PrintObjectBaseWithState> detect_extruder_geometric_unprintables() const; void slice_volumes(); + // Combine slices of regions configured with a thicker extruder layer height into every Nth layer where geometry allows. Called by slice(). + void apply_extruder_layer_heights(); //BBS ExPolygons _shrink_contour_holes(double contour_delta, double hole_delta, const ExPolygons& polys) const; // BBS @@ -603,6 +658,15 @@ class PrintObject : public PrintObjectBaseWithState prepare_adaptive_infill_data( const std::vector>& surfaces_w_bottom_z) const; @@ -1232,6 +1296,9 @@ class Print : public PrintBaseWithState //SoftFever bool &is_BBL_printer() { return m_isBBLPrinter; } const bool is_BBL_printer() const { return m_isBBLPrinter; } + // Per-extruder vector index of a 0-based filament: this fork's classic multi-tool printers + // index per-extruder options by the filament directly. + size_t extruder_index_of(unsigned int filament_idx) const { return size_t(filament_idx); } WipeTowerType wipe_tower_type() const { return is_BBL_printer() ? WipeTowerType::Type1 : m_config.wipe_tower_type.value; } CalibMode& calib_mode() { return m_calib_params.mode; } const CalibMode calib_mode() const { return m_calib_params.mode; } @@ -1377,7 +1444,9 @@ class Print : public PrintBaseWithState PrintRegionPtrs m_print_regions; //SoftFever - bool m_isBBLPrinter = false; + // Assigned by the GUI (BackgroundSlicingProcess) from the vendor; must not be read + // uninitialized by CLI/tests - BBL-only code paths key off it. + bool m_isBBLPrinter { false }; // Ordered collections of extrusion paths to build skirt loops and brim. ExtrusionEntityCollection m_skirt; diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp index 318f2b9dc9c..1525e2d86b4 100644 --- a/src/libslic3r/PrintConfig.cpp +++ b/src/libslic3r/PrintConfig.cpp @@ -410,6 +410,27 @@ static t_config_enum_values s_keys_map_EnsureVerticalShellThickness{ }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(EnsureVerticalShellThickness) +// ORCA: per-extruder layer height ("extruder_layer_height"). +static t_config_enum_values s_keys_map_ExtruderLayerHeightMode{ + { "consistent", int(ExtruderLayerHeightMode::elhmConsistent) }, + { "adaptive", int(ExtruderLayerHeightMode::elhmAdaptive) }, + { "fixed", int(ExtruderLayerHeightMode::elhmFixed) }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ExtruderLayerHeightMode) + +// ORCA: split wall layer heights ("split_wall_adjust"). +static t_config_enum_values s_keys_map_WallSplitFilament{ + { "outer_wall", int(WallSplitFilament::wsfOuterWall) }, + { "inner_wall", int(WallSplitFilament::wsfInnerWall) }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(WallSplitFilament) + +static t_config_enum_values s_keys_map_WallSplitDirection{ + { "decrease", int(WallSplitDirection::wsdDecrease) }, + { "increase", int(WallSplitDirection::wsdIncrease) }, +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(WallSplitDirection) + // Orca static t_config_enum_values s_keys_map_InternalBridgeFilter { { "disabled", ibfDisabled }, @@ -471,6 +492,13 @@ static const t_config_enum_values s_keys_map_TimelapseType = { }; CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TimelapseType) +static const t_config_enum_values s_keys_map_SupportLayerHeightStep = { + {"whole", slhsWholeLayer}, + {"half", slhsHalfLayer}, + {"quarter", slhsQuarterLayer} +}; +CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(SupportLayerHeightStep) + static const t_config_enum_values s_keys_map_SkirtType = { { "combined", stCombined }, { "perobject", stPerObject } @@ -5455,12 +5483,69 @@ void PrintConfigDef::init_fff_params() def = this->add("min_layer_height", coFloats); def->label = L("Min"); def->tooltip = L("The lowest printable layer height for the extruder. " - "Used to limit the minimum layer height when enable adaptive layer height."); + "Used to limit the minimum layer height when enable adaptive layer height. " + "Parts printed with a thicker preferred extruder layer height never fall back " + "below this height either (the first layer excepted)."); def->sidetext = L("mm"); // millimeters, CIS languages need translation def->min = 0; def->mode = comAdvanced; def->set_default_value(new ConfigOptionFloats { 0.07 }); + def = this->add("extruder_layer_height", coFloats); + def->label = L("Preferred layer height"); + def->tooltip = L("Layer height this extruder should print with, used for printers whose extruders have " + "different nozzle sizes. It must be an integer multiple of the object layer height. " + "A part whose features all follow this extruder prints only on every Nth layer with " + "correspondingly thicker extrusions, wherever its geometry allows it; elsewhere it " + "falls back to the object layer height. When the rest of the part cannot follow, " + "walls assigned to this extruder still combine to this height on their own, " + "full-density top surfaces absorb the solid layers below them, and sparse or 100% " + "dense infill combines to this height independently. 0 means to use the object " + "layer height."); + def->sidetext = "mm"; // milimeters, don't need translation + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloats { 0. }); + + def = this->add("extruder_layer_height_mode", coEnum); + def->label = L("Thick layer regions"); + def->category = L("Quality"); + def->tooltip = L("How aggressively object parts assigned to an extruder with a thicker preferred layer " + "height are combined into thick layers.\n" + "Consistent: parts print with at most two layer heights, the extruder layer height " + "wherever whole runs of layers fit and the object layer height everywhere else. This " + "gives the most uniform walls.\n" + "Adaptive: runs may also be combined at intermediate multiples of the object layer " + "height, so more of the part prints with thicker layers, at the price of bands of " + "varying layer heights on curved part boundaries.\n" + "Fixed: parts always print at the extruder layer height, even where the shape changes " + "across the combined layers or overhangs; curved boundaries turn into steps and detail " + "finer than the thick layers is lost. Only geometry too short for a whole thick layer " + "(part tops and the first layer) prints thinner."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("consistent"); + def->enum_values.push_back("adaptive"); + def->enum_values.push_back("fixed"); + def->enum_labels.push_back(L("Consistent")); + def->enum_labels.push_back(L("Adaptive")); + def->enum_labels.push_back(L("Fixed")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(elhmFixed)); + + def = this->add("extruder_layer_height_tolerance", coPercent); + def->label = L("Thick layer tolerance"); + def->category = L("Quality"); + def->tooltip = L("How far the outline of an object part assigned to an extruder with a thicker preferred " + "layer height may drift sideways across the layers of one thick run and still be combined, " + "as a percentage of that extruder's nozzle diameter. Higher values combine more of curved " + "part boundaries into thick layers, at the price of rougher boundary walls: deviations up " + "to this fraction of the nozzle diameter are swallowed by the thick extrusions."); + def->sidetext = "%"; + def->min = 0; + def->max = 100; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionPercent(80)); + def = this->add("slow_down_min_speed", coFloats); def->label = L("Min print speed"); def->tooltip = L("The minimum print speed to which the printer slows down to maintain the minimum layer time defined above " @@ -5661,6 +5746,54 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionInt(0)); + // ORCA: split wall layer heights. When the outer and inner wall filaments print at their own + // preferred layer heights and one is an integer multiple of the other, the walls always split: + // the finer walls print every time their height is reached and the coarser walls once per + // multiple, so their tops stay flush. The options below additionally allow adjusting one wall + // filament's wall-only layer height so the split also happens when the preferred heights do + // not divide evenly. + def = this->add("split_wall_adjust", coBool); + def->label = L("Adjust wall layer height"); + def->category = L("Extruders"); + def->tooltip = L("Outer and inner walls automatically print at their own preferred layer heights when " + "one height is an integer multiple of the other. When the heights do not divide evenly, " + "this option adjusts the wall layer height of one of the two wall filaments (chosen " + "below) to the nearest multiple or divisor of the other, so the walls can still split. " + "The adjusted height only applies to that filament's walls; other features keep the " + "preferred layer height. Adjustments never leave the filament's layer height limits: " + "if no allowed height exists in the chosen direction, the walls print together at the " + "lower height as usual."); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionBool(false)); + + def = this->add("split_wall_adjust_filament", coEnum); + def->label = L("Adjusted walls"); + def->category = L("Extruders"); + def->tooltip = L("Which of the two wall filaments gets its wall layer height adjusted when the " + "preferred layer heights do not divide evenly."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("outer_wall"); + def->enum_values.push_back("inner_wall"); + def->enum_labels.push_back(L("Outer walls")); + def->enum_labels.push_back(L("Inner walls")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(wsfOuterWall)); + + def = this->add("split_wall_adjust_direction", coEnum); + def->label = L("Adjustment direction"); + def->category = L("Extruders"); + def->tooltip = L("Whether the adjusted wall filament's wall layer height is decreased or increased to " + "reach a height compatible with the other wall filament. Heights outside the adjusted " + "filament's layer height limits are never used: if no allowed height exists in this " + "direction, the walls print together at the lower height as usual."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.push_back("decrease"); + def->enum_values.push_back("increase"); + def->enum_labels.push_back(L("Decrease")); + def->enum_labels.push_back(L("Increase")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(wsdDecrease)); + def = this->add("inner_wall_line_width", coFloatOrPercent); def->label = L("Inner wall"); def->category = L("Quality"); @@ -7164,6 +7297,45 @@ void PrintConfigDef::init_fff_params() def->mode = comSimple; def->set_default_value(new ConfigOptionBool(true)); + def = this->add("support_nozzle_diameter", coFloat); + def->label = L("Support nozzle diameter"); + def->category = L("Support"); + def->tooltip = L("On printers whose extruders have different nozzle diameters, only filaments of this " + "nozzle diameter are used to print support, raft and support interface. This keeps " + "filaments of other nozzle sizes - with their different line widths and layer height " + "limits - out of the support. Support filaments set to a non-default value must match " + "this diameter. Value 0 allows any filament to print support."); + def->sidetext = "mm"; // milimeters, don't need translation + def->min = 0; + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionFloat(0.)); + + def = this->add("support_base_material", coString); + def->label = L("Support/raft base material"); + def->category = L("Support"); + def->tooltip = L("Print the support and raft base only with filaments of this material type; " + "extruders loaded with other types are not used for it. Combines with the " + "support nozzle diameter restriction. Leave empty for no restriction; an " + "explicitly selected support/raft base filament still takes precedence."); + def->gui_type = ConfigOptionDef::GUIType::select_open; + def->mode = comSimple; + for (const char *material : { "PLA", "PETG", "ABS", "ASA", "TPU", "PC", "PA", "PVA", "HIPS" }) + def->enum_values.emplace_back(material); + def->set_default_value(new ConfigOptionString("")); + + def = this->add("support_interface_material", coString); + def->label = L("Support/raft interface material"); + def->category = L("Support"); + def->tooltip = L("Print the support and raft interface only with filaments of this material " + "type; extruders loaded with other types are not used for it. Combines with " + "the support nozzle diameter restriction. Leave empty for no restriction; an " + "explicitly selected support/raft interface filament still takes precedence."); + def->gui_type = ConfigOptionDef::GUIType::select_open; + def->mode = comSimple; + for (const char *material : { "PLA", "PETG", "ABS", "ASA", "TPU", "PC", "PA", "PVA", "HIPS" }) + def->enum_values.emplace_back(material); + def->set_default_value(new ConfigOptionString("")); + def = this->add("support_line_width", coFloatOrPercent); def->label = L("Support"); def->category = L("Quality"); @@ -7353,11 +7525,35 @@ void PrintConfigDef::init_fff_params() def->mode = comAdvanced; def->set_default_value(new ConfigOptionEnum(smsDefault)); + def = this->add("support_layer_height_step", coEnum); + def->label = L("Support layer height step"); + def->category = L("Support"); + def->tooltip = L("Step granularity for independent support layer heights while the prime tower is enabled. " + "With whole layers, support layer heights are multiples of the object layer height. " + "Half or quarter steps also allow multiples like 1.5x or 1.25x, which helps when the support " + "nozzle's maximum layer height sits between two whole multiples. Support boundaries may then " + "fall between object layers; such support-only layers print without a prime tower layer: the " + "switch to the support filament happens directly (any residue ends up in the support) and the " + "switch back purges on the next full prime tower layer. With smooth timelapse the sub-layer " + "boundaries get their own prime tower layers instead and are only used where those stay at or " + "above the nozzles' minimum layer height. Not used with single-extruder multi-material, which " + "keeps whole layers."); + def->enum_keys_map = &ConfigOptionEnum::get_enum_values(); + def->enum_values.emplace_back("whole"); + def->enum_values.emplace_back("half"); + def->enum_values.emplace_back("quarter"); + def->enum_labels.emplace_back(L("100% (whole layers)")); + def->enum_labels.emplace_back(L("50%")); + def->enum_labels.emplace_back(L("25%")); + def->mode = comAdvanced; + def->set_default_value(new ConfigOptionEnum(slhsWholeLayer)); + def = this->add("independent_support_layer_height", coBool); def->label = L("Independent support layer height"); def->category = L("Support"); def->tooltip = L("Support layer uses layer height independent with object layer. This is to support customizing Z-gap and save print time. " - "This option will be invalid when the prime tower is enabled."); + "With the prime tower enabled, support layer heights stay aligned to the object layer grid " + "(see Support layer height step)."); def->mode = comAdvanced; // Mainline default. The Snapmaker process profiles either set this to 1 // explicitly or (U1) leave it unset; with the old false default, loading a @@ -8571,6 +8767,7 @@ void PrintConfigDef::init_extruder_option_keys() "default_nozzle_volume_type", "deretraction_speed", "extruder_colour", + "extruder_layer_height", "extruder_offset", "extruder_printable_height", "extruder_type", @@ -9897,24 +10094,11 @@ void DynamicPrintConfig::normalize_fdm(int used_filaments) this->option("wipe_tower_filament")->setInt(0); } - if (this->has("sparse_infill_filament_id")) { - int sparse_infill_filament_id = this->option("sparse_infill_filament_id")->getInt(); - if (sparse_infill_filament_id > 0 && (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0)) - this->option("internal_solid_filament_id", true)->setInt(sparse_infill_filament_id); - } - - const int internal_solid = this->has("internal_solid_filament_id") ? this->option("internal_solid_filament_id")->getInt() : 0; - const int top_surface = this->has("top_surface_filament_id") ? this->option("top_surface_filament_id")->getInt() : 0; - const int bottom_surface = this->has("bottom_surface_filament_id") ? this->option("bottom_surface_filament_id")->getInt() : 0; - - if (internal_solid == 0 && top_surface > 0) - this->option("internal_solid_filament_id", true)->setInt(top_surface); - if (internal_solid == 0 && bottom_surface > 0) - this->option("internal_solid_filament_id", true)->setInt(bottom_surface); - if (top_surface == 0 && internal_solid > 0) - this->option("top_surface_filament_id", true)->setInt(internal_solid); - if (bottom_surface == 0 && internal_solid > 0) - this->option("bottom_surface_filament_id", true)->setInt(internal_solid); + // Note: no cross-propagation between the per-feature filament selectors here. Filling one + // selector from another (sparse -> internal solid, internal solid <-> top/bottom) silently + // overwrote "Default" (0), which means "use the part's filament", with an unrelated feature's + // explicit filament - e.g. assigning internal solid infill dragged the top/bottom surfaces along. + // Each selector resolves its own "Default" at slicing time (PrintRegion::extruder()). if (this->has("spiral_mode") && this->opt("spiral_mode", true)->value) { { @@ -9950,12 +10134,11 @@ void DynamicPrintConfig::normalize_fdm(int used_filaments) ept_opt->value = false; } - if (ept_opt->value) { - if (islh_opt) - islh_opt->value = false; - //if (alh_opt) - // alh_opt->value = false; - } + // With the prime tower enabled, independent support layer heights are no longer + // forced off: tree supports plan grid-aligned thick layers (whole multiples of + // object layers) so every toolchange still lands on a tower layer, and the + // classic support generator falls back to synchronized layers on its own. + (void) islh_opt; /* BBS: MusangKing - not sure if this is still valid, just comment it out cause "Independent support layer height" is re-opened. else { if (islh_opt) @@ -9994,24 +10177,7 @@ void DynamicPrintConfig::normalize_fdm_1() } } - if (this->has("sparse_infill_filament_id")) { - int sparse_infill_filament_id = this->option("sparse_infill_filament_id")->getInt(); - if (sparse_infill_filament_id > 0 && (!this->has("internal_solid_filament_id") || this->option("internal_solid_filament_id")->getInt() == 0)) - this->option("internal_solid_filament_id", true)->setInt(sparse_infill_filament_id); - } - - const int internal_solid = this->has("internal_solid_filament_id") ? this->option("internal_solid_filament_id")->getInt() : 0; - const int top_surface = this->has("top_surface_filament_id") ? this->option("top_surface_filament_id")->getInt() : 0; - const int bottom_surface = this->has("bottom_surface_filament_id") ? this->option("bottom_surface_filament_id")->getInt() : 0; - - if (internal_solid == 0 && top_surface > 0) - this->option("internal_solid_filament_id", true)->setInt(top_surface); - if (internal_solid == 0 && bottom_surface > 0) - this->option("internal_solid_filament_id", true)->setInt(bottom_surface); - if (top_surface == 0 && internal_solid > 0) - this->option("top_surface_filament_id", true)->setInt(internal_solid); - if (bottom_surface == 0 && internal_solid > 0) - this->option("bottom_surface_filament_id", true)->setInt(internal_solid); + // No cross-propagation between the per-feature filament selectors (see normalize_fdm() above). if (this->has("spiral_mode") && this->opt("spiral_mode", true)->value) { { @@ -10069,13 +10235,9 @@ t_config_option_keys DynamicPrintConfig::normalize_fdm_2(int num_objects, int us } if (ept_opt->value) { - if (islh_opt) { - if (islh_opt->value) { - islh_opt->value = false; - changed_keys.push_back("independent_support_layer_height"); - } - //islh_opt->value = false; - } + // Independent support layer heights stay enabled with the prime tower (see + // normalize_fdm()); supports print grid-aligned thick layers instead. + (void) islh_opt; //if (alh_opt) { // if (alh_opt->value) { // alh_opt->value = false; diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp index 6e5721e1457..e852d3abe96 100644 --- a/src/libslic3r/PrintConfig.hpp +++ b/src/libslic3r/PrintConfig.hpp @@ -313,6 +313,24 @@ enum EnsureVerticalShellThickness { evstAll, }; +// ORCA: per-extruder layer height ("extruder_layer_height"). +enum ExtruderLayerHeightMode { + elhmConsistent, + elhmAdaptive, + elhmFixed, +}; + +// ORCA: split wall layer heights - which wall class gets its wall-only layer height adjusted +// when the two wall filaments' preferred heights do not divide evenly, and in which direction. +enum WallSplitFilament { + wsfOuterWall, + wsfInnerWall, +}; +enum WallSplitDirection { + wsdDecrease, + wsdIncrease, +}; + //Orca enum InternalBridgeFilter { ibfDisabled, ibfLimited, ibfNofilter @@ -369,6 +387,15 @@ enum TimelapseType : int { tlSmooth }; +// Step granularity for grid-aligned independent support layer heights (prime +// tower enabled): support boundaries may land on whole object layers or on +// half / quarter subdivisions of them. +enum SupportLayerHeightStep : int { + slhsWholeLayer = 0, + slhsHalfLayer, + slhsQuarterLayer, +}; + enum SkirtType { stCombined, stPerObject }; @@ -671,6 +698,9 @@ extern std::vector save_extruder_nozzle_stats_to_string(const std:: template<> const t_config_enum_values& ConfigOptionEnum::get_enum_values(); CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrinterTechnology) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ExtruderLayerHeightMode) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WallSplitFilament) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WallSplitDirection) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeFlavor) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinMode) @@ -691,6 +721,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLADisplayOrientation) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SLAPillarConnectionMode) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(BrimType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TimelapseType) +CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SupportLayerHeightStep) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(BedType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(SkirtType) CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InputShaperType) @@ -1129,6 +1160,12 @@ PRINT_CONFIG_CLASS_DEFINE( // Force the generation of solid shells between adjacent materials/volumes. ((ConfigOptionBool, interface_shells)) ((ConfigOptionFloat, layer_height)) + // ORCA: per-extruder layer height ("extruder_layer_height"). + ((ConfigOptionEnum, extruder_layer_height_mode)) + ((ConfigOptionPercent, extruder_layer_height_tolerance)) + ((ConfigOptionBool, split_wall_adjust)) + ((ConfigOptionEnum, split_wall_adjust_filament)) + ((ConfigOptionEnum, split_wall_adjust_direction)) ((ConfigOptionFloat, mmu_segmented_region_max_width)) ((ConfigOptionFloat, mmu_segmented_region_interlocking_depth)) ((ConfigOptionFloat, raft_contact_distance)) @@ -1152,6 +1189,10 @@ PRINT_CONFIG_CLASS_DEFINE( ((ConfigOptionFloat, support_bottom_z_distance)) ((ConfigOptionInt, enforce_support_layers)) ((ConfigOptionInt, support_filament)) + // ORCA: restrict support/raft/interface printing to filaments of this nozzle diameter (0 = no restriction). + ((ConfigOptionFloat, support_nozzle_diameter)) + ((ConfigOptionString, support_base_material)) + ((ConfigOptionString, support_interface_material)) ((ConfigOptionFloatOrPercent, support_line_width)) ((ConfigOptionBool, support_interface_not_for_body)) ((ConfigOptionBool, support_interface_loop_pattern)) @@ -1832,6 +1873,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionFloats, max_layer_height)) ((ConfigOptionFloats, fan_min_speed)) ((ConfigOptionFloats, min_layer_height)) + ((ConfigOptionFloats, extruder_layer_height)) ((ConfigOptionFloat, printable_height)) ((ConfigOptionFloatsNullable, extruder_printable_height)) ((ConfigOptionPoint, best_object_pos)) @@ -1949,6 +1991,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE( ((ConfigOptionString, thumbnails)) // BBS: move from PrintObjectConfig ((ConfigOptionBool, independent_support_layer_height)) + ((ConfigOptionEnum, support_layer_height_step)) ((ConfigOptionBool, combine_brims)) // SoftFever ((ConfigOptionPercents, filament_shrink)) @@ -2448,6 +2491,17 @@ class ModelConfig static uint64_t s_last_timestamp; }; +// 0-based filament of a 1-based feature filament selector ("Default" = 0 falls back to filament 1). +inline unsigned int feature_filament_idx(int filament_id) { return filament_id > 1 ? (unsigned int)(filament_id - 1) : 0u; } + +// True when any extruder carries a per-extruder preferred layer height. +inline bool has_extruder_layer_heights(const PrintConfig &config) { + for (double h : config.extruder_layer_height.values) + if (h > 0.) + return true; + return false; +} + // const std::vector &fv_matrix: origin matrix from json // size_t extruder_id: -1 means single-nozzle for old file, 0 means the 1st extruder, 1 means the 2nd extruder template diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index 084aaf2774a..6bb2896ed22 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -678,10 +678,33 @@ void PrintObject::prepare_infill() this->bridge_over_infill(); m_print->throw_if_canceled(); + // Per-extruder layer height: top surfaces absorb the solid layers right below them up to + // their filament's preferred height. Runs before combine_infill() so the interior can still + // combine around the absorbed areas. + this->combine_top_surfaces(); + m_print->throw_if_canceled(); + + // Per-extruder layer height: the solid interior the top surfaces did not absorb combines to + // its own filament's preferred height. + this->combine_internal_solid_infill(); + m_print->throw_if_canceled(); + // combine fill surfaces to honor the "infill every N layers" option this->combine_infill(); m_print->throw_if_canceled(); + // Per-extruder layer height. Stamp the group height onto fill surfaces of combined LayerRegions (Fill uses Surface::thickness when set); must run last, earlier steps re-create surfaces. + if (this->has_combined_layer_regions()) { + for (Layer *layer : m_layers) + for (LayerRegion *layerm : layer->m_regions) + if (layerm->combined_layer_count() > 1) + for (Surface &surface : layerm->fill_surfaces.surfaces) { + surface.thickness = layerm->combined_height(); + surface.thickness_layers = layerm->combined_layer_count(); + } + m_print->throw_if_canceled(); + } + #ifdef SLIC3R_DEBUG_SLICE_PROCESSING for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { for (const Layer *layer : m_layers) { @@ -1171,6 +1194,21 @@ bool PrintObject::invalidate_state_by_config_options( std::vector steps; bool invalidated = false; for (const t_config_option_key &opt_key : opt_keys) { + // Per-extruder layer height: these options feed region_layer_height_multiplier(), which decides layer combination at the slicing step. + if (opt_key == "support_nozzle_diameter" && m_config.raft_layers.value > 0) + // Feeds SlicingParameters::create_from_config(): the support / raft extruder bore sets + // the raft layer heights and object_print_z_min, which the object layers bake in at + // the slicing step - a raft must re-slice (plain supports regenerate via the support + // branch below). + steps.emplace_back(posSlice); + if (opt_key == "outer_wall_filament_id" || opt_key == "inner_wall_filament_id" + || opt_key == "sparse_infill_filament_id" || opt_key == "internal_solid_filament_id" + || opt_key == "top_surface_filament_id" || opt_key == "bottom_surface_filament_id" + || opt_key == "wall_loops" || opt_key == "sparse_infill_density" + || opt_key == "top_shell_layers" || opt_key == "bottom_shell_layers") { + if (has_extruder_layer_heights(m_print->config())) + steps.emplace_back(posSlice); + } if ( opt_key == "brim_width" || opt_key == "brim_object_gap" || opt_key == "brim_use_efc_outline" @@ -1242,6 +1280,12 @@ bool PrintObject::invalidate_state_by_config_options( steps.emplace_back(posPerimeters); } else if ( opt_key == "layer_height" + // ORCA: per-extruder layer height: the layer combining happens at the slicing step. + || opt_key == "extruder_layer_height_mode" + || opt_key == "extruder_layer_height_tolerance" + || opt_key == "split_wall_adjust" + || opt_key == "split_wall_adjust_filament" + || opt_key == "split_wall_adjust_direction" || opt_key == "dithering_z_step_size" || opt_key == "dithering_local_z_mode" || opt_key == "dithering_local_z_whole_objects" @@ -1316,6 +1360,9 @@ bool PrintObject::invalidate_state_by_config_options( || opt_key == "support_remove_small_overhang" || opt_key == "enforce_support_layers" || opt_key == "support_filament" + || opt_key == "support_nozzle_diameter" + || opt_key == "support_base_material" + || opt_key == "support_interface_material" || opt_key == "support_line_width" || opt_key == "support_interface_top_layers" || opt_key == "support_interface_bottom_layers" @@ -1709,6 +1756,16 @@ void PrintObject::detect_surfaces_type() layerm_slices_surfaces = union_ex(layerm_slices_surfaces, to_expolygons(layerm->fill_surfaces.surfaces)); } + // ORCA: per-extruder layer height: a neighbor's combined group prints only its + // common shape; anything of this layer over the remainder is an exposed step face. + // Every region of the neighbor counts: at a painted or per-part filament boundary + // the remainder under this region's geometry belongs to another region. + auto add_exposed_steps = [&layerm_slices_surfaces](ExPolygons &dst, const Layer *neighbor) { + for (const LayerRegion *neighbor_layerm : neighbor->m_regions) + if (const ExPolygons &exposed = neighbor_layerm->combined_away_exposed(); ! exposed.empty()) + dst = union_ex(dst, intersection_ex(layerm_slices_surfaces, exposed)); + }; + // find top surfaces (difference between current surfaces // of current layer and upper one) Surfaces top; @@ -1716,6 +1773,7 @@ void PrintObject::detect_surfaces_type() ExPolygons upper_slices = interface_shells ? diff_ex(layerm_slices_surfaces, upper_layer->m_regions[region_id]->slices.surfaces, ApplySafetyOffset::Yes) : diff_ex(layerm_slices_surfaces, upper_layer->lslices, ApplySafetyOffset::Yes); + add_exposed_steps(upper_slices, upper_layer); surfaces_append(top, opening_ex(upper_slices, offset), stTop); } else { // if no upper layer, all surfaces of this one are solid @@ -1738,12 +1796,15 @@ void PrintObject::detect_surfaces_type() surface_type_bottom_other); #else // Any surface lying on the void is a true bottom bridge (an overhang) - surfaces_append( - bottom, - opening_ex( - diff_ex(layerm_slices_surfaces, lower_layer->lslices, ApplySafetyOffset::Yes), - offset), - surface_type_bottom_other); + ExPolygons unsupported = diff_ex(layerm_slices_surfaces, lower_layer->lslices, ApplySafetyOffset::Yes); + add_exposed_steps(unsupported, lower_layer); + // A combined group's own bridges hang over the layer below the whole group. + if (const unsigned short count = layerm->combined_layer_count(); count > 1 && idx_layer >= size_t(count)) { + const Layer *below_group = m_layers[idx_layer - count]; + unsupported = union_ex(unsupported, diff_ex(layerm_slices_surfaces, below_group->lslices, ApplySafetyOffset::Yes)); + add_exposed_steps(unsupported, below_group); + } + surfaces_append(bottom, opening_ex(unsupported, offset), surface_type_bottom_other); // if user requested internal shells, we need to identify surfaces // lying on other slices not belonging to this region if (interface_shells) { @@ -2181,11 +2242,17 @@ void PrintObject::process_external_surfaces() for (size_t layer_idx = range.begin(); layer_idx < range.end(); ++ layer_idx) { m_print->throw_if_canceled(); // BOOST_LOG_TRIVIAL(trace) << "Processing external surface, layer" << m_layers[layer_idx]->print_z; - m_layers[layer_idx]->get_region(int(region_id))->process_external_surfaces( + LayerRegion *layerm = m_layers[layer_idx]->get_region(int(region_id)); + // Per-extruder layer height: a combined group's external surfaces relate to the layer below the whole group (lower_idx == layer_idx - 1 for regular regions; + // count == 0 on combined-away layers, hence the max(..., 1)). + const size_t combined_layers = std::max(layerm->combined_layer_count(), 1); + const bool has_lower = layer_idx >= combined_layers; + const size_t lower_idx = has_lower ? layer_idx - combined_layers : 0; + layerm->process_external_surfaces( // lower layer - (layer_idx == 0) ? nullptr : m_layers[layer_idx - 1], + has_lower ? m_layers[lower_idx] : nullptr, // lower layer polygons with density > 0% - (layer_idx == 0 || surfaces_covered.empty() || surfaces_covered[layer_idx - 1].empty()) ? nullptr : &surfaces_covered[layer_idx - 1]); + (! has_lower || surfaces_covered.empty() || surfaces_covered[lower_idx].empty()) ? nullptr : &surfaces_covered[lower_idx]); } } ); @@ -2302,6 +2369,9 @@ void PrintObject::discover_vertical_shells() if (region.config().ensure_vertical_shell_thickness.value != evstAll ) // This region will be handled by discover_horizontal_shells(). continue; + if (this->region_layer_height_multiplier(region) > 1) + // Per-extruder layer height. Combined regions extrude on group tops only; their shells are ensured by discover_horizontal_shells() stepping over the groups instead. + continue; //FIXME Improve the heuristics for a grain size. size_t grain_size = std::max(num_layers / 16, size_t(1)); @@ -3750,6 +3820,9 @@ static void clamp_exturder_to_default(ConfigOptionInt &opt, size_t num_total_fil opt.value = 1; } +// ORCA: feature filament selectors use 0 = "Default" (inherit the active object/part filament). +// Once the object/part/layer-range overrides are resolved, any remaining "Default" or invalid +// value falls back to filament 1. static void clamp_feature_filament_to_valid(ConfigOptionInt &opt, size_t num_extruders) { if (opt.value <= 0 || opt.value > (int)num_extruders) @@ -3782,19 +3855,23 @@ static constexpr const std::initializer_list keys_extrud struct FeatureFilamentOverrideMask { - bool sparse_infill_filament_id = false; - bool internal_solid_filament_id = false; - bool top_surface_filament_id = false; - bool bottom_surface_filament_id = false; - bool outer_wall_filament_id = false; - bool inner_wall_filament_id = false; + bool sparse_infill_filament_id = false; + bool internal_solid_filament_id = false; + bool top_surface_filament_id = false; + bool bottom_surface_filament_id = false; + bool outer_wall_filament_id = false; + bool inner_wall_filament_id = false; }; -static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPrintConfig &in, FeatureFilamentOverrideMask &feature_overrides, std::vector& variant_index) +static void apply_to_print_region_config(PrintRegionConfig &out, const DynamicPrintConfig &in, FeatureFilamentOverrideMask &feature_overrides, int &base_extruder_through_scopes, std::vector& variant_index) { // 1) Explicit feature filament values take precedence over base extruder fallback. auto *opt_extruder = in.opt(key_extruder); int base_extruder = (opt_extruder != nullptr) ? opt_extruder->value : 0; + if (base_extruder > 0) + // The innermost "extruder" assignment seen so far - the part's filament an explicit + // "Default" (0) selector resets to. + base_extruder_through_scopes = base_extruder; // 2) Copy the rest of the values. for (auto it = in.cbegin(); it != in.cend(); ++ it) @@ -3818,6 +3895,12 @@ 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 = true; } else { + // Reset the inherited value too: an explicit "Default" at this scope must + // undo an earlier scope's explicit filament, not silently keep it. It + // resets to the part's filament (the innermost "extruder" seen so far, or + // 0 for the first filament) - a literal 0 would clamp to filament 1 even + // when the part prints with another filament. + my_opt->setInt(base_extruder_through_scopes); if (it->first == "sparse_infill_filament_id") feature_overrides.sparse_infill_filament_id = false; else if (it->first == "internal_solid_filament_id") @@ -3869,28 +3952,35 @@ PrintRegionConfig region_config_from_model_volume(const PrintRegionConfig &defau // For model parts, non-zero values coming from the print defaults should stay explicit. if (volume.is_model_part()) { - feature_overrides.sparse_infill_filament_id = (config.sparse_infill_filament_id.value > 0); - feature_overrides.internal_solid_filament_id = (config.internal_solid_filament_id.value > 0); - feature_overrides.top_surface_filament_id = (config.top_surface_filament_id.value > 0); - feature_overrides.bottom_surface_filament_id = (config.bottom_surface_filament_id.value > 0); - feature_overrides.outer_wall_filament_id = (config.outer_wall_filament_id.value > 0); - feature_overrides.inner_wall_filament_id = (config.inner_wall_filament_id.value > 0); + feature_overrides.sparse_infill_filament_id = (config.sparse_infill_filament_id.value > 0); + feature_overrides.internal_solid_filament_id = (config.internal_solid_filament_id.value > 0); + feature_overrides.top_surface_filament_id = (config.top_surface_filament_id.value > 0); + feature_overrides.bottom_surface_filament_id = (config.bottom_surface_filament_id.value > 0); + feature_overrides.outer_wall_filament_id = (config.outer_wall_filament_id.value > 0); + feature_overrides.inner_wall_filament_id = (config.inner_wall_filament_id.value > 0); } + // The part's filament as resolved so far, for explicit "Default" (0) selector resets. Seeded + // from the object for modifiers too (their parent part's own extruder is already folded into + // default_or_parent_region_config and not recoverable here). + int base_extruder_through_scopes = 0; + if (const auto *opt = volume.get_object()->config.get().opt("extruder"); opt != nullptr && opt->value > 0) + base_extruder_through_scopes = opt->value; + 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, variant_index); + apply_to_print_region_config(config, volume.get_object()->config.get(), feature_overrides, base_extruder_through_scopes, 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, variant_index); + apply_to_print_region_config(config, volume.config.get(), feature_overrides, base_extruder_through_scopes, variant_index); if (! volume.material_id().empty()) - apply_to_print_region_config(config, volume.material()->config.get(), feature_overrides, variant_index); + apply_to_print_region_config(config, volume.material()->config.get(), feature_overrides, base_extruder_through_scopes, 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, variant_index); + apply_to_print_region_config(config, *layer_range_config, feature_overrides, base_extruder_through_scopes, variant_index); } // Resolve feature defaults and clamp invalid extruders to index 1. clamp_feature_filament_to_valid(config.sparse_infill_filament_id, num_extruders); @@ -4003,6 +4093,342 @@ std::vector PrintObject::object_extruders() const return extruders; } +// Per-extruder layer height ("extruder_layer_height" printer option). +// Raw preferred layer height (mm) of the extruder printing the given 1-based filament id, 0 when unset or not reliably resolvable. +double PrintObject::extruder_preferred_layer_height(unsigned int filament_id) const +{ + const PrintConfig &print_config = m_print->config(); + if (print_config.extruder_layer_height.empty()) + return 0.; + // Region filament ids are 1-based, 0 ("Default") falls back to the first filament. + if (filament_id == 0) + filament_id = 1; + // Snapmaker mixed filament: virtual mixed ids (beyond the physical filaments) resolve to a + // different physical extruder on every layer, so no stable preferred height exists for them. + if (filament_id > print_config.filament_diameter.values.size()) + return 0.; + return std::max(0., print_config.extruder_layer_height.get_at(m_print->extruder_index_of(filament_id - 1))); +} + +// Returns the number of object layers a region printing with the given 1-based filament id combines into one extrusion (1 = no combining). +// The configured height must be a (near) integer multiple of the object layer height, otherwise it is ignored here and rejected by Print::validate(). +unsigned int PrintObject::layer_height_multiplier_for_filament(unsigned int filament_id) const +{ + const double extruder_height = this->extruder_preferred_layer_height(filament_id); + if (extruder_height <= 0.) + return 1; + const double layer_height = m_config.layer_height.value; + if (layer_height <= EPSILON) + return 1; + const int multiplier = int(std::lround(extruder_height / layer_height)); + if (multiplier <= 1 || std::abs(extruder_height - multiplier * layer_height) > EPSILON) + // Not combining, or not an integer multiple (the latter is rejected by Print::validate()). + return 1; + const PrintConfig &print_config = m_print->config(); + const size_t extruder_idx = m_print->extruder_index_of((filament_id == 0 ? 1 : filament_id) - 1); + if (extruder_height > print_config.nozzle_diameter.get_at(extruder_idx) + EPSILON) + // Taller than the nozzle can print, rejected by Print::validate(). + return 1; + return (unsigned int)multiplier; +} + +// Inner-wall loops can also come from the alternating extra wall or from extra perimeters on +// overhangs, even at a single wall loop (mirrors PerimeterGenerator's loop count). +bool PrintObject::region_prints_inner_walls(const PrintRegionConfig &config) +{ + return config.wall_loops.value > 1 || + (config.alternate_extra_wall.value && config.sparse_infill_density.value > 0) || + config.extra_perimeters_on_overhangs.value; +} + +// At 100% sparse infill density the solid interior belongs to the internal solid filament +// (PrintRegion::extruder()), so a sparse infill selector that prints no other feature of the +// region prints nothing at all. +bool PrintObject::region_filament_prints_nothing(const PrintRegionConfig &config, unsigned int filament) +{ + return std::abs(config.sparse_infill_density.value - 100.) < EPSILON && + filament == feature_filament_idx(config.sparse_infill_filament_id.value) && + filament != feature_filament_idx(config.internal_solid_filament_id.value) && + filament != feature_filament_idx(config.top_surface_filament_id.value) && + filament != feature_filament_idx(config.bottom_surface_filament_id.value) && + filament != feature_filament_idx(config.outer_wall_filament_id.value) && + filament != feature_filament_idx(config.inner_wall_filament_id.value); +} + +// Collects the 0-based filaments whose explicit preferred layer heights define the region's +// pitch: the wall filaments when any of them carries a preference, otherwise the other +// pitch-bound feature filaments (top / bottom / internal solid; sparse infill always combines +// separately in combine_infill(), including at 100% density). pitch_from_features tells the +// caller which case applies. Returns false when a mixed (virtual) filament forbids combining +// altogether: mixed rows rotate physical extruders per layer and need every layer. +bool PrintObject::collect_region_pitch_filaments(const PrintRegionConfig &config, std::vector &filaments, bool &pitch_from_features) const +{ + pitch_from_features = false; + const int num_filaments = (int)m_print->config().filament_diameter.size(); + bool has_mixed = false; + auto emplace_filament = [num_filaments, &filaments, &has_mixed](int filament_id) { + int i = std::max(0, filament_id - 1); + if (i >= num_filaments) { + // Snapmaker mixed filament: virtual mixed ids resolve to a different physical + // extruder per layer (matches extruder_preferred_layer_height()). + has_mixed = true; + return; + } + filaments.emplace_back(i); + }; + auto emplace_feature_filaments = [&]() { + if (config.top_shell_layers.value > 0) + emplace_filament(config.top_surface_filament_id.value); + if (config.bottom_shell_layers.value > 0) + emplace_filament(config.bottom_surface_filament_id.value); + if ((config.sparse_infill_density.value > 0 || config.top_shell_layers.value > 0 || config.bottom_shell_layers.value > 0) && + std::abs(config.sparse_infill_density.value - 100.) >= EPSILON) + emplace_filament(config.internal_solid_filament_id.value); + }; + if (config.wall_loops.value > 0) { + emplace_filament(config.outer_wall_filament_id.value); + if (region_prints_inner_walls(config)) + emplace_filament(config.inner_wall_filament_id.value); + if (has_mixed) + return false; + const bool walls_explicit = std::any_of(filaments.begin(), filaments.end(), + [this](unsigned int f) { return this->extruder_preferred_layer_height(f + 1) > 0.; }); + if (! walls_explicit) { + // Walls without an explicit preference follow the agreement of the part's other + // pitch-bound features, so assigning e.g. the top surface to a coarse extruder + // takes effect even when the walls stay on the part's filament. + pitch_from_features = true; + emplace_feature_filaments(); + } else { + // Even a walls-driven pitch prints the region's other features on the group tops: a + // mixed (virtual) feature filament needs every layer and forbids combining, whether + // or not it participates in the lattice. + const size_t lattice_size = filaments.size(); + emplace_feature_filaments(); + filaments.resize(lattice_size); + if (has_mixed) + return false; + } + } else { + // No walls to dictate a pitch: the other pitch-bound features offer one. The brim is not + // considered, it prints on the first layer which is never combined. + pitch_from_features = true; + emplace_feature_filaments(); + } + return ! has_mixed; +} + +unsigned int PrintObject::region_layer_height_multiplier(const PrintRegion ®ion) const +{ + const PrintRegionConfig &config = region.config(); + // Filaments whose explicit preferences define the pitch; disagreeing explicit preferences + // keep the object layer height (Print::validate() warns). + std::vector filaments; // 0-based filament indices + bool pitch_from_features = false; + if (! this->collect_region_pitch_filaments(config, filaments, pitch_from_features)) + return 1; + unsigned int multiplier = 0; + for (unsigned int filament : filaments) { + // A filament without a preference (0 = object layer height) follows the pitch of the + // filaments that have one instead of vetoing it; only explicit preferences must agree. + if (this->extruder_preferred_layer_height(filament + 1) <= 0.) + continue; + unsigned int m = this->layer_height_multiplier_for_filament(filament + 1); + if (pitch_from_features && m <= 1) + // Feature filaments only OFFER a pitch: a non-conforming preference is skipped here + // (Print::validate() warns) instead of blocking the remaining features' agreement. + continue; + if (multiplier == 0) + multiplier = m; + else if (m != multiplier) + return 1; + } + if (multiplier <= 1) + return 1; + // Only a nozzle that physically cannot extrude the pitch vetoes it; the softer per-extruder + // min/max layer height limits keep the pitch and Print::validate() warns instead - with stock + // profiles the fine extruder's max_layer_height would otherwise veto almost any thick pitch. + const PrintConfig &print_config = m_print->config(); + const double pitch = multiplier * m_config.layer_height.value; + std::vector used_filaments; // 0-based filament indices + PrintRegion::collect_object_printing_extruders(print_config, config, false /* has_brim */, used_filaments); + for (unsigned int filament : used_filaments) { + // An inert 100%-density sparse infill selector must not veto the pitch. + if (region_filament_prints_nothing(config, filament)) + continue; + if (pitch > print_config.nozzle_diameter.get_at(m_print->extruder_index_of(filament)) + EPSILON) + return 1; + } + return multiplier; +} + +// When the region cannot follow its wall filaments' preferred pitch as a whole (vetoed in +// region_layer_height_multiplier()), the walls still combine on their own: they extrude once per +// group of N layers while the other features keep printing every layer. Only the wall filaments' +// nozzles matter here. +unsigned int PrintObject::wall_layer_height_multiplier(const PrintRegion ®ion) const +{ + const PrintRegionConfig &config = region.config(); + if (config.wall_loops.value <= 0) + return 1; + if (this->region_layer_height_multiplier(region) > 1) + // The whole region follows the pitch, walls included. + return 1; + unsigned int outer_m = 0, inner_m = 0; + if (! this->wall_effective_multipliers(region, outer_m, inner_m)) + return 1; + // A preference-less wall filament (0) follows the other one's pitch. Outer and inner walls + // that cannot split print together at one height: disagreeing effective preferences meet at + // the LOWER one (Print::validate() reports the unhonored higher preference). With split + // pitches this minimum is the finer class's pitch, the run cadence of both classes. + const unsigned int multiplier = outer_m == 0 || inner_m == 0 ? std::max(outer_m, inner_m) : + std::min(outer_m, inner_m); + if (multiplier <= 1) + return 1; + // Every wall filament must fit the pitch through its own bore, including preference-less + // ones following the pitch - they print these very walls. + const PrintConfig &print_config = m_print->config(); + const double pitch = multiplier * m_config.layer_height.value; + auto nozzle_too_small = [&](int filament_id) { + return pitch > print_config.nozzle_diameter.get_at(m_print->extruder_index_of(feature_filament_idx(filament_id))) + EPSILON; + }; + if (nozzle_too_small(config.outer_wall_filament_id.value)) + return 1; + if (region_prints_inner_walls(config) && nozzle_too_small(config.inner_wall_filament_id.value)) + return 1; + return multiplier; +} + +// ORCA: split wall layer heights. Effective wall pitch multipliers of the two wall classes: the +// conforming multipliers of their filaments' explicit preferred heights (0 = no explicit +// preference; inner_m is 0 when the region prints no inner walls). When both are explicit but do +// not divide evenly, the "split_wall_adjust" option moves the selected class's wall-only height +// to the nearest divisor or multiple of the other one in the selected direction, so the walls +// can still split (or merge, when the adjustment lands on the other class's height). Unlike the +// preferred heights themselves, an adjusted height is hard-bounded by the adjusted filament's +// min/max layer heights and bore: without a legal candidate in the chosen direction the +// multipliers stay unadjusted and the walls merge at the lower height as usual. +// Returns false when a mixed (virtual) wall filament forbids wall combining altogether. +bool PrintObject::wall_effective_multipliers(const PrintRegion ®ion, unsigned int &outer_m, unsigned int &inner_m) const +{ + const PrintRegionConfig &config = region.config(); + outer_m = inner_m = 0; + const int num_filaments = (int)m_print->config().filament_diameter.size(); + if (config.wall_loops.value > 0 && + (std::max(0, config.outer_wall_filament_id.value - 1) >= num_filaments || + (region_prints_inner_walls(config) && std::max(0, config.inner_wall_filament_id.value - 1) >= num_filaments))) + // Snapmaker mixed filament: virtual mixed ids resolve to a different physical extruder + // per layer, no stable pitch exists for the walls. + return false; + auto conforming_multiplier = [this](int filament_id) -> unsigned int { + if (this->extruder_preferred_layer_height((unsigned int)std::max(0, filament_id)) <= 0.) + return 0; + return this->layer_height_multiplier_for_filament((unsigned int)std::max(0, filament_id)); + }; + outer_m = config.wall_loops.value > 0 ? conforming_multiplier(config.outer_wall_filament_id.value) : 0; + inner_m = config.wall_loops.value > 0 && region_prints_inner_walls(config) ? + conforming_multiplier(config.inner_wall_filament_id.value) : 0; + if (! m_config.split_wall_adjust.value || outer_m == 0 || inner_m == 0 || + std::max(outer_m, inner_m) % std::min(outer_m, inner_m) == 0) + return true; + const bool adjust_outer = m_config.split_wall_adjust_filament.value == wsfOuterWall; + unsigned int &adjusted = adjust_outer ? outer_m : inner_m; + const unsigned int other = adjust_outer ? inner_m : outer_m; + const int filament_id = adjust_outer ? config.outer_wall_filament_id.value : config.inner_wall_filament_id.value; + const PrintConfig &print_config = m_print->config(); + const size_t extruder_idx = m_print->extruder_index_of(feature_filament_idx(filament_id)); + const double h = m_config.layer_height.value; + const double min_lh = print_config.min_layer_height.get_at(extruder_idx); + const double max_lh = print_config.max_layer_height.get_at(extruder_idx); + const double bore = print_config.nozzle_diameter.get_at(extruder_idx); + auto legal = [&](unsigned int m) { + // A candidate height divides the other class's pitch or is a whole multiple of it (equal + // merges the walls at that height), and it honors the adjusted filament's limits. + if (other % m != 0 && m % other != 0) + return false; + const double height = m * h; + return height <= bore + EPSILON && height >= min_lh - EPSILON && + (max_lh <= EPSILON || height <= max_lh + EPSILON); + }; + if (m_config.split_wall_adjust_direction.value == wsdIncrease) { + for (unsigned int m = adjusted + 1, limit = (unsigned int)std::floor(bore / h + EPSILON); m <= limit; ++m) + if (legal(m)) { adjusted = m; return true; } + } else { + for (unsigned int m = adjusted - 1; m >= 1; --m) + if (legal(m)) { adjusted = m; return true; } + } + // No legal height in the chosen direction: leave the preferences unadjusted. + return true; +} + +// ORCA: split wall layer heights. The finer wall class prints on every fine-run top, the coarser +// once per coarse/fine fine runs, so their tops stay flush. Splitting happens whenever both wall +// classes' effective heights are explicit, unequal and divide evenly; otherwise the walls keep +// printing together at the lower height (wall_layer_height_multiplier()'s min-merge). +bool PrintObject::wall_split_pitches(const PrintRegion ®ion, unsigned int &fine, unsigned int &coarse, bool &coarse_is_outer) const +{ + unsigned int outer_m = 0, inner_m = 0; + if (! this->wall_effective_multipliers(region, outer_m, inner_m)) + return false; + // Split needs an explicit preference on both wall classes; a preference-less wall filament + // follows the other one at a single merged pitch as usual. + if (outer_m == 0 || inner_m == 0 || outer_m == inner_m) + return false; + fine = std::min(outer_m, inner_m); + coarse = std::max(outer_m, inner_m); + if (coarse % fine != 0) + return false; + coarse_is_outer = outer_m > inner_m; + return true; +} + +bool PrintObject::has_combined_layer_regions() const +{ + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) + if (this->region_layer_height_multiplier(this->printing_region(region_id)) > 1) + return true; + return false; +} + +bool PrintObject::support_filament_allowed(unsigned int filament_id, bool interface_role) const +{ + if (filament_id == 0) + return true; + if (const double nozzle = m_config.support_nozzle_diameter.value; nozzle > 0. && + std::abs(m_print->config().nozzle_diameter.get_at(filament_id - 1) - nozzle) > EPSILON) + return false; + const std::string &material = (interface_role ? m_config.support_interface_material : + m_config.support_base_material).value; + return material.empty() || m_print->config().filament_type.get_at(filament_id - 1) == material; +} + +bool PrintObject::has_support_filament_restriction() const +{ + return m_config.support_nozzle_diameter.value > 0. || + ! m_config.support_base_material.value.empty() || + ! m_config.support_interface_material.value.empty(); +} + +unsigned int PrintObject::resolved_default_support_filament(bool interface_role) const +{ + if (m_config.support_nozzle_diameter.value <= 0. && + (interface_role ? m_config.support_interface_material : + m_config.support_base_material).value.empty()) + return 0; + const PrintConfig &print_config = m_print->config(); + const size_t num_filaments = std::max(print_config.nozzle_diameter.values.size(), + print_config.filament_diameter.values.size()); + unsigned int soluble_fallback = 0; + for (size_t i = 0; i < num_filaments; ++ i) + if (this->support_filament_allowed((unsigned int)(i + 1), interface_role)) { + if (! print_config.filament_soluble.get_at(i)) + return (unsigned int)(i + 1); + if (soluble_fallback == 0) + soluble_fallback = (unsigned int)(i + 1); + } + return soluble_fallback; +} + namespace { struct LayerHeightRangeOverride { @@ -4686,6 +5112,9 @@ void PrintObject::clip_fill_surfaces() for (LayerRegion *layerm : lower_layer->m_regions) { if (layerm->region().config().sparse_infill_density.value == 0) continue; + if (layerm->combined_layer_count() > 1) + // Per-extruder layer height: a combined group's infill supports the whole group, don't clip it against the single layer above. + continue; Polygons internal; for (Surface &surface : layerm->fill_surfaces.surfaces) if (surface.surface_type == stInternal || surface.surface_type == stInternalVoid) @@ -4709,6 +5138,9 @@ void PrintObject::discover_horizontal_shells() BOOST_LOG_TRIVIAL(trace) << "discover_horizontal_shells()"; for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + // ORCA: per-extruder layer height. Combined regions extrude only on the top layers of their + // groups; the empty layers in between must neither receive shells nor count as shell layers. + const bool region_combined = this->region_layer_height_multiplier(this->printing_region(region_id)) > 1; for (size_t i = 0; i < m_layers.size(); ++ i) { m_print->throw_if_canceled(); Layer *layer = m_layers[i]; @@ -4724,7 +5156,8 @@ void PrintObject::discover_horizontal_shells() } // If ensure_vertical_shell_thickness, then the rest has already been performed by discover_vertical_shells(). - if (region_config.ensure_vertical_shell_thickness.value == evstAll) + // ORCA: combined regions are skipped by discover_vertical_shells() and handled here instead. + if (region_config.ensure_vertical_shell_thickness.value == evstAll && ! region_combined) continue; coordf_t print_z = layer->print_z; @@ -4761,17 +5194,26 @@ void PrintObject::discover_horizontal_shells() // Slic3r::debugf "Layer %d has %s surfaces\n", $i, ($type == stTop) ? 'top' : 'bottom'; // Scatter top / bottom regions to other layers. Scattering process is inherently serial, it is difficult to parallelize without locking. + // ORCA: per-extruder layer height. n_region_layers counts only layers the region + // prints on (equals the int(i) - n index distance when nothing is skipped), so + // shells of combined regions propagate across group tops. + int n_region_layers = 0; for (int n = (type == stTop) ? int(i) - 1 : int(i) + 1; (type == stTop) ? - (n >= 0 && (int(i) - n < num_solid_layers || + (n >= 0 && (n_region_layers + 1 < num_solid_layers || print_z - m_layers[n]->print_z < region_config.top_shell_thickness.value - EPSILON)) : - (n < int(m_layers.size()) && (n - int(i) < num_solid_layers || + (n < int(m_layers.size()) && (n_region_layers + 1 < num_solid_layers || m_layers[n]->bottom_z() - bottom_z < region_config.bottom_shell_thickness.value - EPSILON)); (type == stTop) ? -- n : ++ n) { // Slic3r::debugf " looking for neighbors on layer %d...\n", $n; // Reference to the lower layer of a TOP surface, or an upper layer of a BOTTOM surface. LayerRegion *neighbor_layerm = m_layers[n]->regions()[region_id]; + // ORCA: combined-away layers (count == 0) print nothing here: no shells, not + // counted. Genuinely absent geometry (count == 1, empty slices) still counts. + if (region_combined && neighbor_layerm->combined_layer_count() == 0) + continue; + ++ n_region_layers; // find intersection between neighbor and current layer's surfaces // intersections have contours and holes @@ -4912,6 +5354,245 @@ void PrintObject::discover_horizontal_shells() #endif /* SLIC3R_DEBUG_SLICE_PROCESSING */ } // void PrintObject::discover_horizontal_shells() +// Drop expolygons too small to be worth combining (see LayerRegion::infill_area_threshold()). +static void remove_small_expolygons(ExPolygons &expolygons, double area_threshold) +{ + if (! expolygons.empty() && area_threshold > 0.) + expolygons.erase(std::remove_if(expolygons.begin(), expolygons.end(), + [area_threshold](const ExPolygon &expoly) { return expoly.area() <= area_threshold; }), + expolygons.end()); +} + +// Per-extruder layer height: print top surfaces with the preferred layer height of their filament +// by absorbing the internal solid shell layers right below them. The top surface then extrudes +// once at N times the object layer height - replacing itself and N-1 solid layers underneath - +// while everything else keeps printing every layer. Only areas backed by plain internal solid +// infill through the whole group combine (no bridge, sparse infill or another surface may hide +// inside the group); the rest keeps the object layer height. Like combine_infill(), the removed +// areas stay behind as VOID surfaces to preserve the fill boundaries. +void PrintObject::combine_top_surfaces() +{ + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = this->printing_region(region_id); + const PrintRegionConfig &config = region.config(); + if (config.top_shell_layers.value <= 0) + continue; + // A reduced-density (textured) top surface relies on the solid layers below it; absorbing + // them would replace solid backing with a sparse pass. Combine full-density tops only. + if (config.top_surface_density.value < 100. - EPSILON) + continue; + // Only for regions printing at the object layer height: combined regions already extrude + // everything - top surfaces included - once per group over their group tops. + if (this->region_layer_height_multiplier(region) > 1) + continue; + const unsigned int mult = this->layer_height_multiplier_for_filament( + (unsigned int)std::max(0, config.top_surface_filament_id.value)); + if (mult <= 1) + continue; + // Top-down, so the uppermost (most visible) top surfaces absorb first where columns are + // less than a group apart. + for (size_t layer_idx = m_layers.size(); layer_idx-- > 0; ) { + m_print->throw_if_canceled(); + if (layer_idx + 1 < size_t(mult)) + break; + // Never absorb the first print layer: it keeps its own height for bed adhesion. + if (m_layers[layer_idx - mult + 1]->id() == 0) + continue; + LayerRegion *top_layerm = m_layers[layer_idx]->regions()[region_id]; + ExPolygons combined = to_expolygons(top_layerm->fill_surfaces.filter_by_type(stTop)); + if (combined.empty()) + continue; + // Uniform layer heights only (mirrors apply_extruder_layer_heights()). + bool uniform = true; + for (size_t i = layer_idx - mult + 1; uniform && i < layer_idx; ++ i) + uniform = std::abs(m_layers[i]->height - m_layers[layer_idx]->height) < EPSILON; + if (! uniform) + continue; + std::vector absorbed; // the mult-1 layers right below, bottom-up + for (size_t i = layer_idx - mult + 1; i < layer_idx; ++ i) + absorbed.emplace_back(m_layers[i]->regions()[region_id]); + for (LayerRegion *layerm : absorbed) { + combined = intersection_ex(layerm->fill_surfaces.filter_by_type(stInternalSolid), combined); + if (combined.empty()) + break; + } + remove_small_expolygons(combined, top_layerm->infill_area_threshold()); + if (combined.empty()) + continue; + // Clearance against the absorbed layers' remaining solid infill, which is grown later + // to overlap perimeters (mirrors combine_infill()'s clearance). + Polygons combined_with_clearance; + combined_with_clearance.reserve(combined.size()); + const float clearance_offset = 0.5f * top_layerm->flow(frPerimeter).scaled_width() + + 1.5f * top_layerm->flow(frSolidInfill).scaled_width(); + for (const ExPolygon &expoly : combined) + polygons_append(combined_with_clearance, offset(expoly, clearance_offset)); + for (LayerRegion *layerm : absorbed) { + Polygons internal = to_polygons(std::move(layerm->fill_surfaces.filter_by_type(stInternalSolid))); + layerm->fill_surfaces.remove_type(stInternalSolid); + layerm->fill_surfaces.append(diff_ex(internal, combined_with_clearance), stInternalSolid); + layerm->fill_surfaces.append(intersection_ex(internal, combined_with_clearance), stInternalVoid); + } + { + Polygons top_polys = to_polygons(std::move(top_layerm->fill_surfaces.filter_by_type(stTop))); + top_layerm->fill_surfaces.remove_type(stTop); + top_layerm->fill_surfaces.append(diff_ex(top_polys, to_polygons(combined)), stTop); + // The absorbed areas extrude once with the whole group's thickness (Fill resolves + // the flow from Surface::thickness). + Surface templ(stTop, ExPolygon()); + templ.thickness = 0.; + for (size_t i = layer_idx - mult + 1; i <= layer_idx; ++ i) + templ.thickness += m_layers[i]->height; + templ.thickness_layers = (unsigned short)mult; + top_layerm->fill_surfaces.append(std::move(combined), templ); + } + } + } +} + +// Per-extruder layer height: combine runs of a region's not-yet-combined fill surfaces of the +// given type into one thick pass extruding at the run top (Fill resolves the flow from +// Surface::thickness), leaving VOID surfaces behind like combine_infill(). grid_aligned anchors +// the full-height runs on one global grid so a contiguous field extrudes on the same layers +// (bands whose tops differ would combine phase-shifted, stepping one course at the seam); +// without it runs anchor at each column's top (solid shell bands rarely fit the grid). Leftover +// bands re-group over ever shorter runs down to min_mult, the smallest count reaching the +// extruder's min layer height; one-layer lookaheads at both band ends split off pairs instead +// of stranding a single below-minimum layer (a true single layer between other features stays +// at the object layer height and Print::validate() warns). +void PrintObject::combine_surface_runs(size_t region_id, SurfaceType surface_type, unsigned int mult, unsigned int min_mult, float fill_clearance_factor, bool grid_aligned) +{ + // Surfaces not combined yet (groups formed by an earlier sweep have their thickness set). + auto leftover = [surface_type, region_id](const Layer *layer) { + ExPolygons out; + for (const Surface &surface : layer->regions()[region_id]->fill_surfaces.surfaces) + if (surface.surface_type == surface_type && surface.thickness < 0.) + out.emplace_back(surface.expolygon); + return out; + }; + // One combined pass over the run [layer_idx - m + 1, layer_idx] limited to the given areas. + auto commit_run = [&](size_t layer_idx, size_t m, ExPolygons &&combined) { + if (combined.empty()) + return; + LayerRegion *top_layerm = m_layers[layer_idx]->regions()[region_id]; + // Clearance against the run's remaining fills, which are grown later to overlap + // perimeters (mirrors combine_infill()'s clearance). + Polygons combined_with_clearance; + combined_with_clearance.reserve(combined.size()); + const float clearance_offset = 0.5f * top_layerm->flow(frPerimeter).scaled_width() + + fill_clearance_factor * top_layerm->flow(frSolidInfill).scaled_width(); + for (const ExPolygon &expoly : combined) + polygons_append(combined_with_clearance, offset(expoly, clearance_offset)); + for (size_t i = layer_idx + 1 - m; i <= layer_idx; ++ i) { + LayerRegion *layerm = m_layers[i]->regions()[region_id]; + // Take out only the uncombined surfaces; earlier runs keep their heights. + Polygons pieces; + Surfaces kept; + kept.reserve(layerm->fill_surfaces.surfaces.size()); + for (Surface &surface : layerm->fill_surfaces.surfaces) { + if (surface.surface_type == surface_type && surface.thickness < 0.) + polygons_append(pieces, to_polygons(std::move(surface.expolygon))); + else + kept.emplace_back(std::move(surface)); + } + layerm->fill_surfaces.surfaces = std::move(kept); + layerm->fill_surfaces.append(diff_ex(pieces, combined_with_clearance), surface_type); + if (i == layer_idx) { + // The combined areas extrude once with the whole run's thickness. + Surface templ(surface_type, ExPolygon()); + templ.thickness = 0.; + for (size_t j = layer_idx + 1 - m; j <= layer_idx; ++ j) + templ.thickness += m_layers[j]->height; + templ.thickness_layers = (unsigned short)m; + layerm->fill_surfaces.append(std::move(combined), templ); + } else { + layerm->fill_surfaces.append(intersection_ex(pieces, combined_with_clearance), stInternalVoid); + } + } + }; + auto combine_runs = [&](size_t m, bool aligned) { + for (size_t layer_idx = m_layers.size(); layer_idx-- > 0; ) { + m_print->throw_if_canceled(); + if (layer_idx + 1 < m) + break; + if (aligned && layer_idx % m != 0) + continue; + // Never absorb the first print layer: it keeps its own height for bed adhesion. + if (m_layers[layer_idx - m + 1]->id() == 0) + continue; + ExPolygons combined = leftover(m_layers[layer_idx]); + if (combined.empty()) + continue; + // Uniform layer heights only (mirrors apply_extruder_layer_heights()). + bool uniform = true; + for (size_t i = layer_idx - m + 1; uniform && i < layer_idx; ++ i) + uniform = std::abs(m_layers[i]->height - m_layers[layer_idx]->height) < EPSILON; + if (! uniform) + continue; + for (size_t i = layer_idx - m + 1; i < layer_idx && ! combined.empty(); ++ i) + combined = intersection_ex(leftover(m_layers[i]), combined); + remove_small_expolygons(combined, m_layers[layer_idx]->regions()[region_id]->infill_area_threshold()); + if (combined.empty()) + continue; + // Where a band ends exactly one layer above an aligned run (free runs anchor at band + // tops), committing would strand that layer below the minimum: leave the area to the + // shorter runs, which split the m + 1 layers into printable groups. + if (aligned && min_mult > 1 && mult > min_mult && layer_idx + 1 < m_layers.size()) { + ExPolygons above = intersection_ex(leftover(m_layers[layer_idx + 1]), combined); + if (! above.empty() && layer_idx + 2 < m_layers.size()) + above = diff_ex(above, leftover(m_layers[layer_idx + 2])); + if (! above.empty()) { + combined = diff_ex(combined, above); + if (combined.empty()) + continue; + } + } + // Where the band continues exactly one layer below the run, take one layer less so + // the leftover pair re-groups instead of stranding below the minimum. + ExPolygons shrunk; + if (min_mult > 1 && m > min_mult && layer_idx >= m && m_layers[layer_idx - m]->id() != 0) { + shrunk = intersection_ex(leftover(m_layers[layer_idx - m]), combined); + if (! shrunk.empty() && layer_idx > m) + shrunk = diff_ex(shrunk, leftover(m_layers[layer_idx - m - 1])); + if (! shrunk.empty()) + combined = diff_ex(combined, shrunk); + } + commit_run(layer_idx, m, std::move(combined)); + commit_run(layer_idx, m - 1, std::move(shrunk)); + } + }; + combine_runs(mult, grid_aligned); + if (min_mult > 1) + for (unsigned int m = mult - 1; m >= min_mult; -- m) + combine_runs(m, false); +} + +// Per-extruder layer height: print the internal solid infill left over after +// combine_top_surfaces() - shell backing and other solid interior - with the preferred layer +// height of its filament. +void PrintObject::combine_internal_solid_infill() +{ + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + const PrintRegion ®ion = this->printing_region(region_id); + const PrintRegionConfig &config = region.config(); + // At 100% sparse density the whole interior is solid and combine_infill() owns it. + if (std::fabs(config.sparse_infill_density.value - 100.) < EPSILON) + continue; + // Only for regions printing at the object layer height: combined regions already extrude + // everything - solid infill included - once per group over their group tops. + if (this->region_layer_height_multiplier(region) > 1) + continue; + const unsigned int mult = this->layer_height_multiplier_for_filament( + (unsigned int)std::max(0, config.internal_solid_filament_id.value)); + if (mult <= 1) + continue; + const double min_layer_height = m_print->config().min_layer_height.get_at( + m_print->extruder_index_of(feature_filament_idx(config.internal_solid_filament_id.value))); + const auto min_mult = (unsigned int)std::ceil(min_layer_height / m_config.layer_height.value - EPSILON); + this->combine_surface_runs(region_id, stInternalSolid, mult, min_mult, 1.5f, false); + } +} + // combine fill surfaces across layers to honor the "infill every N layers" option // Idempotence of this method is guaranteed by the fact that we don't remove things from // fill_surfaces but we only turn them into VOID surfaces, thus preserving the boundaries. @@ -4922,11 +5603,25 @@ void PrintObject::combine_infill() const PrintRegion ®ion = this->printing_region(region_id); //BBS const bool enable_combine_infill = region.config().infill_combination.value; - if (enable_combine_infill == false || region.config().sparse_infill_density == 0.) + // Per-extruder layer height: infill whose filament prefers a taller layer height is combined up to it, with or without the infill_combination option. + // Only for regions printing at the object layer height; combined-wall regions already print everything over their runs. + if (this->region_layer_height_multiplier(region) > 1) + continue; + // At 100% density the combined surfaces are internal solid infill (see use_solid_infill + // below) and print with the internal solid filament (PrintRegion::extruder()), so that + // filament's preference and limits decide there; the sparse filament's below 100%. + const bool combine_solid = std::abs(region.config().sparse_infill_density.value - 100.) < EPSILON; + const int combine_filament_id = std::max(1, combine_solid ? region.config().internal_solid_filament_id.value : + region.config().sparse_infill_filament_id.value); + const size_t combine_extruder_idx = this->print()->extruder_index_of((unsigned int)(combine_filament_id - 1)); + double preferred_infill_height = this->extruder_preferred_layer_height((unsigned int)combine_filament_id); + if (preferred_infill_height <= m_config.layer_height.value + EPSILON) + preferred_infill_height = 0.; + if ((enable_combine_infill == false && preferred_infill_height == 0.) || region.config().sparse_infill_density == 0.) continue; // Support internal solid infill when sparse_infill_density is 100% - const bool use_solid_infill = fabs(region.config().sparse_infill_density.value - 100.) < EPSILON; + const bool use_solid_infill = combine_solid; const SurfaceType surface_type = use_solid_infill ? stInternalSolid : stInternal; const InfillPattern infill_pattern = use_solid_infill ? region.config().internal_solid_infill_pattern : region.config().sparse_infill_pattern; @@ -4941,7 +5636,32 @@ void PrintObject::combine_infill() //Orca: Limit combination of infill to up to infill_combination_max_layer_height const double infill_combination_max_layer_height = region.config().infill_combination_max_layer_height.get_abs_value(nozzle_diameter); nozzle_diameter = infill_combination_max_layer_height > 0 ? std::min(infill_combination_max_layer_height, nozzle_diameter) : nozzle_diameter; - + + // Per-extruder layer height: the preferred height is an explicit target overriding the + // caps above, limited only by the bore of the nozzle extruding it (max_layer_height is a + // soft limit, Print::validate() warns). Plain infill_combination keeps its own cap. + if (preferred_infill_height > 0.) { + nozzle_diameter = std::min(preferred_infill_height, + this->print()->config().nozzle_diameter.get_at(combine_extruder_idx)); + // An explicit preference combines through combine_surface_runs() instead of the + // fixed window grid below, honoring the extruder's min layer height at the band + // edges the grid would strand at the object layer height. + const auto mult = (unsigned int)std::max(1, int(std::floor(nozzle_diameter / m_config.layer_height.value + EPSILON))); + const auto min_mult = (unsigned int)std::ceil( + this->print()->config().min_layer_height.get_at(combine_extruder_idx) / m_config.layer_height.value - EPSILON); + if (mult > 1) + this->combine_surface_runs(region_id, surface_type, mult, min_mult, + (infill_pattern == ipRectilinear || + infill_pattern == ipMonotonic || + infill_pattern == ipGrid || + infill_pattern == ipLateralLattice|| + infill_pattern == ipLine || + infill_pattern == ipHoneycomb || + infill_pattern == ipLateralHoneycomb) ? 1.5f : 0.5f, + true); + continue; + } + // define the combinations std::vector combine(m_layers.size(), 0); { @@ -4987,11 +5707,7 @@ void PrintObject::combine_infill() // Start looping from the second layer and intersect the current intersection with it. for (size_t i = 1; i < layerms.size(); ++ i) intersection = intersection_ex(layerms[i]->fill_surfaces.filter_by_type(surface_type), intersection); - double area_threshold = layerms.front()->infill_area_threshold(); - if (! intersection.empty() && area_threshold > 0.) - intersection.erase(std::remove_if(intersection.begin(), intersection.end(), - [area_threshold](const ExPolygon &expoly) { return expoly.area() <= area_threshold; }), - intersection.end()); + remove_small_expolygons(intersection, layerms.front()->infill_area_threshold()); if (intersection.empty()) continue; // Slic3r::debugf " combining %d %s regions from layers %d-%d\n", diff --git a/src/libslic3r/PrintObjectSlice.cpp b/src/libslic3r/PrintObjectSlice.cpp index 12a5c153698..79e5b5c4aaa 100644 --- a/src/libslic3r/PrintObjectSlice.cpp +++ b/src/libslic3r/PrintObjectSlice.cpp @@ -892,6 +892,11 @@ void PrintObject::slice() // BBS: the actual first layer slices stored in layers are re-sorted by volume group and will be used to generate brim groupingVolumesForBrim(this, m_layers, firstLayerReplacedBy); + // Per-extruder layer height: combine region slices into every Nth layer where geometry allows. + // Must run before backup_untyped_slices() below so the combined slices survive the restore_untyped_slices*() calls in make_perimeters() / prepare_infill(). + this->apply_extruder_layer_heights(); + m_print->throw_if_canceled(); + // Update bounding boxes, back up raw slices of complex models. tbb::parallel_for( tbb::blocked_range(0, m_layers.size()), @@ -913,6 +918,400 @@ void PrintObject::slice() this->set_done(posSlice); } +// ORCA: per-extruder layer height ("extruder_layer_height" printer option). +// For every region whose extruder prefers an integer multiple N (> 1) of the object layer height, +// greedily combine bottom-up runs of up to N layers on which the region keeps a (nearly) identical +// shape, merging the run's slices into its top layer to be extruded once at the run's full height +// (see LayerRegion::combined_height()); combined-away layers carry no slices for the region and +// trigger no toolchange. A run requires near-identical slices, uniform layer heights and full support +// from below (no overhang / bridge hidden inside a run). Only full runs plus the clean cap of a +// column ending above are committed, so each region prints at two consistent heights rather than +// ever-changing intermediate bands. Region tops / bottoms and overhangs keep the finer base layers. +void PrintObject::apply_extruder_layer_heights() +{ + if (m_layers.size() < 2 || this->num_printing_regions() == 0) + return; + std::vector multipliers(this->num_printing_regions(), 1); + // Walls-only pitch (see wall_layer_height_multiplier()): the region prints every layer, only + // its walls combine. Mutually exclusive with a whole-region multiplier > 1. + std::vector wall_multipliers(this->num_printing_regions(), 1); + // Split wall layer heights (see wall_split_pitches()): the wall min-merge above already + // equals the fine class's pitch; the coarse class additionally combines to its own runs. + std::vector split_coarses(this->num_printing_regions(), 1); + bool any_combined = false; + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + multipliers[region_id] = this->region_layer_height_multiplier(this->printing_region(region_id)); + if (multipliers[region_id] <= 1) { + wall_multipliers[region_id] = this->wall_layer_height_multiplier(this->printing_region(region_id)); + unsigned int fine = 0, coarse = 0; + bool coarse_is_outer = false; + if (this->wall_split_pitches(this->printing_region(region_id), fine, coarse, coarse_is_outer)) + split_coarses[region_id] = coarse; + } + any_combined |= multipliers[region_id] > 1 || wall_multipliers[region_id] > 1 || split_coarses[region_id] > 1; + } + if (! any_combined) + return; + if (m_print->config().spiral_mode || m_config.interface_shells) + // These combinations are rejected by Print::validate(), fail safe here. + return; + + BOOST_LOG_TRIVIAL(debug) << "Combining region slices to extruder layer heights for " << this->model_object()->name; + + // Never combine the first printed layer: it keeps its own height for bed adhesion (mirrors the + // id() == 0 exclusion in PrintObject::combine_infill()), and with a raft detect_surfaces_type() + // needs its slices to seed the object's bottom surfaces. + const size_t first_idx = 1; + if (m_layers.size() <= first_idx + 1) + return; + + // Adaptive mode commits runs cut short by shape drift at intermediate heights instead of + // falling back to the object layer height. Fixed mode has no drift concept at all: runs grow + // to the full pitch wherever the region exists with a common shape, ignoring the tolerance + // and overhangs, so the extruder never drops to finer layers (boundaries become steps). + const bool adaptive = m_config.extruder_layer_height_mode.value == elhmAdaptive; + const bool fixed = m_config.extruder_layer_height_mode.value == elhmFixed; + const PrintConfig &print_config = m_print->config(); + for (size_t region_id = 0; region_id < this->num_printing_regions(); ++ region_id) { + // Walls-only mode marks the runs on the LayerRegions for make_perimeters() instead of + // moving any slices: every layer keeps its geometry, fills and surfaces. + const bool split = split_coarses[region_id] > 1; + const bool walls_only = wall_multipliers[region_id] > 1 || split; + const size_t mult = walls_only ? wall_multipliers[region_id] : multipliers[region_id]; + if (mult <= 1 && ! split) + continue; + // Shapes deviating by less than this fraction of the region's nozzle diameter are considered + // identical; the deviations swallowed stay below what printing N layers at once causes anyway. + const double nozzle_diameter = print_config.nozzle_diameter.get_at(m_print->extruder_index_of( + feature_filament_idx(this->printing_region(region_id).config().outer_wall_filament_id.value))); + const float tolerance = float(scale_(m_config.extruder_layer_height_tolerance.get_abs_value(nozzle_diameter))); + // Where geometry would fall back below the extruders' minimum layer height, runs of at least + // min_run layers are forced instead, ignoring the shape tolerance (the nozzle cannot print + // finer). All the region's pitch filaments print fallback runs, so the coarsest minimum decides + // (with a feature-derived pitch the coarse feature filament matters, not just the walls). + const PrintRegionConfig ®ion_config = this->printing_region(region_id).config(); + double min_layer_height = 0.; + { + std::vector pitch_filaments; // 0-based filament indices + if (walls_only) { + // Only the wall filaments print the combined runs here. + pitch_filaments.emplace_back(feature_filament_idx(region_config.outer_wall_filament_id.value)); + if (region_prints_inner_walls(region_config)) + pitch_filaments.emplace_back(feature_filament_idx(region_config.inner_wall_filament_id.value)); + } else { + bool pitch_from_features = false; + this->collect_region_pitch_filaments(region_config, pitch_filaments, pitch_from_features); + } + for (unsigned int filament : pitch_filaments) + min_layer_height = std::max(min_layer_height, print_config.min_layer_height.get_at(m_print->extruder_index_of(filament))); + } + size_t min_run = 1; + if (min_layer_height > m_config.layer_height.value + EPSILON) + min_run = std::min(mult, (size_t)std::ceil(min_layer_height / m_config.layer_height.value - EPSILON)); + // With a fine multiplier of 1 (split with the finer wall at the object layer height) + // there are no fine runs to walk; only the coarse pass below applies. + size_t idx = mult > 1 ? first_idx : m_layers.size(); + while (idx < m_layers.size()) { + m_print->throw_if_canceled(); + ExPolygons merged = to_expolygons(m_layers[idx]->regions()[region_id]->slices.surfaces); + if (merged.empty()) { + // The region does not exist at this layer. + ++ idx; + continue; + } + // Grow the run upwards while nothing sticks out of the run's common shape by more than + // the tolerance. Uniform layer heights only (variable heights are rejected by Print::validate()). + Polygons unioned = to_polygons(merged); + size_t top_idx = idx; + bool shape_drifted = false; + while (top_idx + 1 < m_layers.size() && top_idx + 1 - idx < mult) { + const size_t next = top_idx + 1; + if (std::abs(m_layers[next]->height - m_layers[idx]->height) > EPSILON) + break; + const ExPolygons expolys = to_expolygons(m_layers[next]->regions()[region_id]->slices.surfaces); + if (expolys.empty()) + // The region ends above, the run is the clean cap of its column. + break; + ExPolygons next_merged = intersection_ex(expolys, merged); + if (next_merged.empty()) + // Laterally displaced (a painted-boundary step): this column ends, the next anchors above. + break; + if (fixed) { + // Even fixed mode ends a column where the shape displaces so far sideways that + // the surviving intersection cannot carry a bead of the region's nozzle anymore: + // committing such a sliver would erase the layers' real geometry, not step it. + if (opening_ex(next_merged, 0.25f * float(scale_(nozzle_diameter))).empty()) + break; + } else { + Polygons next_unioned = unioned; + polygons_append(next_unioned, to_polygons(expolys)); + if (! opening(diff(union_(next_unioned), offset(next_merged, tolerance)), 0.5f * tolerance).empty()) { + shape_drifted = true; + break; + } + unioned = std::move(next_unioned); + } + merged = std::move(next_merged); + top_idx = next; + } + // Full runs and clean caps commit as grown; a run cut short by shape drift falls back to + // the object layer height (unless adaptive) to avoid bands of ever-changing heights on + // curved boundaries. The fallback is raised to min_run where required. + const size_t grown = top_idx + 1 - idx; + size_t commit_length; + if (grown == mult || ! shape_drifted) + commit_length = grown; + else if (adaptive) + commit_length = std::max(grown, min_run); + else + commit_length = min_run; + if (commit_length >= 2 && min_run > 1) { + // Don't leave a remainder shorter than min_run above: shorten so the next run can reach it. + size_t above = 0; + for (size_t i = idx + commit_length; i < m_layers.size() && above < min_run; ++ i) { + if (m_layers[i]->regions()[region_id]->slices.empty()) + break; + ++ above; + } + if (above > 0 && above < min_run) { + const size_t shift = min_run - above; + if (commit_length >= min_run + shift && commit_length - shift >= 2) + commit_length -= shift; + } + } + if (commit_length < 2) { + // Print this layer with the object layer height. + ++ idx; + continue; + } + size_t commit_top = std::min(idx + commit_length - 1, m_layers.size() - 1); + if (commit_top != top_idx) { + // Forced or shortened run: recompute its shape without the tolerance check, + // shrinking the range where the region ends or jumps. + merged = to_expolygons(m_layers[idx]->regions()[region_id]->slices.surfaces); + for (size_t i = idx + 1; i <= commit_top; ++ i) { + if (std::abs(m_layers[i]->height - m_layers[idx]->height) > EPSILON) { + commit_top = i - 1; + break; + } + const ExPolygons expolys = to_expolygons(m_layers[i]->regions()[region_id]->slices.surfaces); + ExPolygons next_merged = expolys.empty() ? ExPolygons() : intersection_ex(expolys, merged); + if (next_merged.empty()) { + commit_top = i - 1; + break; + } + merged = std::move(next_merged); + } + if (commit_top + 1 - idx < 2) { + // Nothing to force here, the object layer height is the last resort. + ++ idx; + continue; + } + } + // The run must rest on the object below, else the finer per-layer bridge / overhang path + // is needed. Skipped when min_run > 1 or in fixed mode: no finer path is allowed then, + // overhangs are detected against the layer below the whole run instead. + if (min_run <= 1 && ! fixed) + if (const Layer *below = m_layers[idx]->lower_layer; below != nullptr && + ! opening_ex(diff_ex(merged, below->lslices, ApplySafetyOffset::Yes), 0.5f * tolerance).empty()) { + ++ idx; + continue; + } + double combined_height = 0.; + for (size_t i = idx; i <= commit_top; ++ i) + combined_height += m_layers[i]->height; + if (walls_only) { + // Commit: mark the run for LayerRegion::make_perimeters(). The run's top layer + // extrudes all its walls at once at the full run height; the layers below keep + // their slices, fills and surfaces but drop their wall extrusions (count 0). All + // run layers carry the run height so their perimeters are generated with the same + // flow and the fill boundaries line up with the walls actually printed at the top. + for (size_t i = idx; i <= commit_top; ++ i) { + LayerRegion *layerm = m_layers[i]->regions()[region_id]; + layerm->m_wall_combined_count = i == commit_top ? (unsigned short)(commit_top - idx + 1) : 0; + layerm->m_wall_combined_height = combined_height; + } + idx = commit_top + 1; + continue; + } + // Commit: move the common shape to the top layer of the run, drop the layers below. + LayerRegion *top_layerm = m_layers[commit_top]->regions()[region_id]; + ExPolygons top_remainder = to_expolygons(top_layerm->slices.surfaces); + top_layerm->slices.set(std::move(merged), stInternal); + top_layerm->m_combined_layer_count = (unsigned short)(commit_top - idx + 1); + top_layerm->m_combined_height = combined_height; + const ExPolygons committed = to_expolygons(top_layerm->slices.surfaces); + top_layerm->m_combined_away_exposed = diff_ex(top_remainder, committed); + for (size_t i = idx; i < commit_top; ++ i) { + LayerRegion *combined_away = m_layers[i]->regions()[region_id]; + // The run prints only its common shape; this layer's own geometry outside it is + // approximated by the run's step. Surface detection classifies the step faces it + // exposes via this remainder (lslices still carry the uncombined shape). + combined_away->m_combined_away_exposed = diff_ex(to_expolygons(combined_away->slices.surfaces), committed); + combined_away->slices.clear(); + // 0 marks "extrudes at the run top above", as opposed to genuinely absent geometry. + combined_away->m_combined_layer_count = 0; + } + // Do not touch Layer::lslices here: they describe the final object and keep driving + // top / bottom detection of the other regions, brim, supports and overhang handling. + idx = commit_top + 1; + } + // ORCA: split wall layer heights - group the fine cadence into coarse runs of + // split_coarses[region_id] layers and mark them for LayerRegion::make_perimeters(): the + // coarse wall class extrudes once per coarse run at the full run height and follows the + // fine cadence wherever no coarse run forms (both walls then print at the lower pitch, + // like the min-merge fallback). + if (split) { + const size_t coarse = split_coarses[region_id]; + const size_t fine = std::max(1, mult); + size_t bottom = first_idx; + while (bottom + coarse <= m_layers.size()) { + m_print->throw_if_canceled(); + // When the fine class combines, a coarse run must span whole fine runs so both + // classes' tops stay flush: every expected fine-run top must carry a full run. + bool aligned = true; + if (fine > 1) + for (size_t top = bottom + fine - 1; aligned && top < bottom + coarse; top += fine) + aligned = m_layers[top]->regions()[region_id]->wall_combined_count() == fine; + if (! aligned) { + ++ bottom; + continue; + } + // Uniform layer heights, the region present everywhere, and the whole span's + // shape within the run tolerance (mirrors the fine walk above). + ExPolygons merged = to_expolygons(m_layers[bottom]->regions()[region_id]->slices.surfaces); + Polygons unioned = to_polygons(merged); + bool valid = ! merged.empty(); + for (size_t i = bottom + 1; valid && i < bottom + coarse; ++ i) { + const ExPolygons expolys = to_expolygons(m_layers[i]->regions()[region_id]->slices.surfaces); + merged = expolys.empty() ? ExPolygons() : intersection_ex(expolys, merged); + polygons_append(unioned, to_polygons(expolys)); + valid = ! merged.empty() && std::abs(m_layers[i]->height - m_layers[bottom]->height) <= EPSILON; + } + if (valid) + valid = fixed ? ! opening_ex(merged, 0.25f * float(scale_(nozzle_diameter))).empty() + : opening(diff(union_(unioned), offset(merged, tolerance)), 0.5f * tolerance).empty(); + // The coarse walls must rest on the object below the whole run, like the fine walk. + if (valid && ! fixed) + if (const Layer *below = m_layers[bottom]->lower_layer; below != nullptr && + ! opening_ex(diff_ex(merged, below->lslices, ApplySafetyOffset::Yes), 0.5f * tolerance).empty()) + valid = false; + if (! valid) { + bottom += fine; + continue; + } + const size_t top = bottom + coarse - 1; + double split_height = 0.; + for (size_t i = bottom; i <= top; ++ i) + split_height += m_layers[i]->height; + for (size_t i = bottom; i <= top; ++ i) { + LayerRegion *layerm = m_layers[i]->regions()[region_id]; + layerm->m_wall_split_count = i == top ? (unsigned short)coarse : 0; + layerm->m_wall_split_height = split_height; + } + bottom = top + 1; + } + } + m_print->throw_if_canceled(); + } + + // ORCA: floating pieces at region boundaries. Combining defers or drops a region's layer + // geometry (cleared run members extrude at their run top; remainders outside the committed + // shape never print), so a neighboring region's per-layer geometry can lose both its support + // below and its same-layer lateral anchor: it would extrude into thin air before the covering + // pass exists. Unanchored pieces are dropped (recorded as exposed step faces) and the column + // resumes - bridging - on the first layer with a printed anchor; a piece whose only anchor is + // a run committing at its own layer is filled by that run instead and resumes fully supported + // on top of the pass. Pieces away from any deferred neighbor geometry are genuine model + // overhangs and print as usual. + const size_t num_regions = this->num_printing_regions(); + const float anchor_dist = float(scale_(0.1)); + auto printed_at = [this, num_regions](size_t layer_idx) { + Polygons printed; + for (size_t region_id = 0; region_id < num_regions; ++ region_id) + polygons_append(printed, to_polygons(m_layers[layer_idx]->regions()[region_id]->slices.surfaces)); + return printed; + }; + for (size_t idx = first_idx; idx < m_layers.size(); ++ idx) { + m_print->throw_if_canceled(); + // Only layers around active combining can need work. + bool combining_nearby = false; + for (size_t region_id = 0; region_id < num_regions && ! combining_nearby; ++ region_id) + combining_nearby = m_layers[idx]->regions()[region_id]->combined_layer_count() != 1 || + m_layers[idx - 1]->regions()[region_id]->combined_layer_count() != 1; + if (! combining_nearby) + continue; + const Polygons printed_below = printed_at(idx - 1); + const Polygons printed_now = printed_at(idx); + // Object areas of this layer nothing extrudes at: deferred to a run top above, or dropped. + // The opening removes hairline residue along region boundaries (lslices are safety-offset + // unions of the region slices), keeping only real deferred geometry. + const Polygons unprinted_now = to_polygons(opening_ex(diff_ex(m_layers[idx]->lslices, printed_now), anchor_dist)); + for (size_t region_id = 0; region_id < num_regions; ++ region_id) { + LayerRegion *layerm = m_layers[idx]->regions()[region_id]; + // Only plain per-layer regions: run members print at their run top, and wall-combined + // and split runs delegate their walls to the run top and must not be trimmed. + if (layerm->combined_layer_count() != 1 || layerm->wall_combined_count() != 1 || + layerm->wall_split_count() != 1 || layerm->slices.empty()) + continue; + const ExPolygons own = to_expolygons(layerm->slices.surfaces); + ExPolygons floating = diff_ex(own, printed_below); + if (floating.empty()) + continue; + const Polygons anchors = diff(printed_now, to_polygons(floating)); + // An anchored piece is normally a legitimate flush bridge. But when its anchor is a + // run committing at this very layer and nothing below that run's whole span carries + // the piece, the bridge would hang beside the pass over the run's full height of air; + // object volume exists through the pass height, so the run fills it instead. + LayerRegion *fill_target = nullptr; + ExPolygons filled; + auto fill_by_covering_run = [&](const ExPolygon &piece, const Polygons &nearby) { + for (size_t other = 0; other < num_regions; ++ other) { + LayerRegion *neighbor = m_layers[idx]->regions()[other]; + if (other == region_id || neighbor->combined_layer_count() < 2 || + intersection(nearby, to_polygons(neighbor->slices.surfaces)).empty()) + continue; + const size_t run_bottom = idx + 1 - size_t(neighbor->combined_layer_count()); + if (run_bottom > 0 && ! intersection(to_polygons(piece), printed_at(run_bottom - 1)).empty()) + return; // carried below the covering run: the flush bridge is fine + ExPolygons fill { piece }; + for (size_t i = run_bottom; i <= idx && ! fill.empty(); ++ i) + fill = intersection_ex(fill, m_layers[i]->lslices); + if (! fill.empty()) { + fill_target = neighbor; + append(filled, std::move(fill)); + } + return; + } + }; + ExPolygons dropped; + for (ExPolygon &piece : floating) { + const Polygons nearby = offset(piece, anchor_dist); + if (! intersection(nearby, anchors).empty()) + fill_by_covering_run(piece, nearby); + else if (! intersection(nearby, unprinted_now).empty()) + // Beside or over deferred geometry, with no anchor: would extrude into thin air. + dropped.emplace_back(std::move(piece)); + } + if (dropped.empty() && filled.empty()) + continue; + ExPolygons removed = dropped; + append(removed, filled); + layerm->slices.set(diff_ex(own, removed), stInternal); + // Dropped pieces never print and classify the surfaces around them; filled ones DO + // print (as the neighbor's pass), so they must not count as exposed remainders. + layerm->m_combined_away_exposed = union_ex(layerm->m_combined_away_exposed, std::move(dropped)); + if (fill_target != nullptr) { + // Safety-offset union: the filled pieces must weld into the committed shape, or + // they stay separate islands walled off by their own mid-air perimeters. + Polygons merged = to_polygons(fill_target->slices.surfaces); + polygons_append(merged, to_polygons(filled)); + fill_target->slices.set(union_safety_offset_ex(merged), stInternal); + } + } + } +} + static bool bool_from_full_config(const DynamicPrintConfig &full_cfg, const char *key, bool fallback) { if (!full_cfg.has(key)) diff --git a/src/libslic3r/PrintRegion.cpp b/src/libslic3r/PrintRegion.cpp index c97634903ef..1e8c0a4d02e 100644 --- a/src/libslic3r/PrintRegion.cpp +++ b/src/libslic3r/PrintRegion.cpp @@ -5,15 +5,6 @@ namespace Slic3r { -namespace { - -bool internal_solid_infill_uses_sparse_filament(const PrintRegionConfig &config, FlowRole role) -{ - return role == frSolidInfill && std::abs(config.sparse_infill_density.value - 100.) < EPSILON; -} - -} // namespace - // 1-based extruder identifier for this region and role. unsigned int PrintRegion::extruder(FlowRole role) const { @@ -25,7 +16,10 @@ unsigned int PrintRegion::extruder(FlowRole role) const else if (role == frInfill) extruder = m_config.sparse_infill_filament_id; else if (role == frSolidInfill) - extruder = internal_solid_infill_uses_sparse_filament(m_config, role) ? m_config.sparse_infill_filament_id : m_config.internal_solid_filament_id; + // The internal solid filament owns internal solid infill at every density, including the + // solid interior at 100% sparse density (matches mainline Orca; this fork used to hand + // the 100% interior to the sparse filament, hiding the internal solid selector entirely). + extruder = m_config.internal_solid_filament_id; else if (role == frTopSolidInfill) extruder = m_config.top_surface_filament_id; else @@ -33,7 +27,7 @@ unsigned int PrintRegion::extruder(FlowRole role) const return extruder; } -Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer) const +Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_height, bool first_layer, unsigned int filament_id) const { const PrintConfig &print_config = object.print()->config(); ConfigOptionFloatOrPercent config_width; @@ -58,9 +52,10 @@ Flow PrintRegion::flow(const PrintObject &object, FlowRole role, double layer_he if (config_width.value == 0) config_width = object.config().line_width; - // Get the configured nozzle_diameter for the extruder associated to the flow role requested. + // Get the configured nozzle_diameter for the extruder associated to the flow role requested, + // or for the explicitly given filament when it differs from the role's default mapping (top / bottom surface fills). // Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right. - auto nozzle_diameter = float(print_config.nozzle_diameter.get_at(this->extruder(role) - 1)); + auto nozzle_diameter = float(print_config.nozzle_diameter.get_at((filament_id > 0 ? filament_id : this->extruder(role)) - 1)); return Flow::new_from_config_width(role, config_width, nozzle_diameter, float(layer_height)); } diff --git a/src/libslic3r/Slicing.cpp b/src/libslic3r/Slicing.cpp index c8c37a5a793..38193867131 100644 --- a/src/libslic3r/Slicing.cpp +++ b/src/libslic3r/Slicing.cpp @@ -74,8 +74,16 @@ SlicingParameters SlicingParameters::create_from_config( // which is consistent with the requirement that if support_filament == 0 resp. support_interface_filament == 0, // support will not trigger tool change, but it will use the current nozzle instead. // In that case all the nozzles have to be of the same diameter. - coordf_t support_material_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_filament.value - 1); - coordf_t support_material_interface_extruder_dmr = print_config.nozzle_diameter.get_at(object_config.support_interface_filament.value - 1); + // Support_nozzle_diameter restricts which extruders / nozzle diameter may print support ("default" = no restriction) + auto restricted_default = [&object_config](int configured) { + return configured == 0 && object_config.support_nozzle_diameter.value > 0.; + }; + coordf_t support_material_extruder_dmr = restricted_default(object_config.support_filament.value) ? + object_config.support_nozzle_diameter.value : + print_config.nozzle_diameter.get_at(object_config.support_filament.value - 1); + coordf_t support_material_interface_extruder_dmr = restricted_default(object_config.support_interface_filament.value) ? + object_config.support_nozzle_diameter.value : + print_config.nozzle_diameter.get_at(object_config.support_interface_filament.value - 1); // ORCA: store Z distance const coordf_t support_top_z_gap = object_config.support_top_z_distance.value; @@ -123,13 +131,49 @@ SlicingParameters SlicingParameters::create_from_config( params.max_layer_height = std::numeric_limits::max(); if (object_config.enable_support.value || params.base_raft_layers > 0 || object_config.enforce_support_layers > 0) { // Has some form of support. Add the support layers to the minimum / maximum layer height limits. + auto support_layer_height_limit = [&print_config, &object_config, &object_extruders, &restricted_default](int configured, bool min_limit) -> coordf_t { + auto from_nozzle = [&print_config, min_limit](int filament) { + return min_limit ? min_layer_height_from_nozzle(print_config, filament) : max_layer_height_from_nozzle(print_config, filament); + }; + if (restricted_default(configured)) { + // Combine the limits of all filaments the restriction allows. + coordf_t limit = min_limit ? 0. : std::numeric_limits::max(); + bool found = false; + for (size_t i = 0; i < print_config.nozzle_diameter.values.size(); ++ i) + if (std::abs(print_config.nozzle_diameter.values[i] - object_config.support_nozzle_diameter.value) < EPSILON) { + coordf_t l = from_nozzle(int(i + 1)); + limit = min_limit ? std::max(limit, l) : std::min(limit, l); + found = true; + } + if (found) + return limit; + } + if (configured == 0 && !object_extruders.empty()) { + // Unrestricted "default" support filament: supports print with the object's own + // extruder(s), so combine those limits. from_nozzle(0) would read the FIRST + // extruder's limits instead, capping support heights by an unrelated fine nozzle + // on mixed-diameter machines. + coordf_t limit = min_limit ? 0. : std::numeric_limits::max(); + for (unsigned int extruder_id : object_extruders) { + coordf_t l = from_nozzle(int(extruder_id + 1)); + limit = min_limit ? std::max(limit, l) : std::min(limit, l); + } + return limit; + } + return from_nozzle(configured); + }; params.min_layer_height = std::max( - min_layer_height_from_nozzle(print_config, object_config.support_filament), - min_layer_height_from_nozzle(print_config, object_config.support_interface_filament)); + support_layer_height_limit(object_config.support_filament.value, true), + support_layer_height_limit(object_config.support_interface_filament.value, true)); params.max_layer_height = std::min( - max_layer_height_from_nozzle(print_config, object_config.support_filament), - max_layer_height_from_nozzle(print_config, object_config.support_interface_filament)); + support_layer_height_limit(object_config.support_filament.value, false), + support_layer_height_limit(object_config.support_interface_filament.value, false)); params.max_suport_layer_height = params.max_layer_height; + // The support extruders' own (unclamped) minimum matters only when supports are pinned + // to their own filaments or nozzle; with the object's filaments the object's clamped + // minimum applies as before. + if (object_config.support_filament.value != 0 || object_config.support_interface_filament.value != 0 || restricted_default(0)) + params.min_suport_layer_height = params.min_layer_height; } if (object_extruders.empty()) { @@ -137,8 +181,9 @@ SlicingParameters SlicingParameters::create_from_config( params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, 0)); } else { for (unsigned int extruder_id : object_extruders) { - params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, extruder_id)); - params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, extruder_id)); + // object_extruders holds zero based extruder indices, from_nozzle indices are one based. + params.min_layer_height = std::max(params.min_layer_height, min_layer_height_from_nozzle(print_config, int(extruder_id + 1))); + params.max_layer_height = std::min(params.max_layer_height, max_layer_height_from_nozzle(print_config, int(extruder_id + 1))); } } @@ -154,7 +199,7 @@ SlicingParameters SlicingParameters::create_from_config( params.gap_raft_object = 0.0; } else { params.gap_raft_object = raft_z_gap; - if (!print_config.independent_support_layer_height) { + if (!print_config.independent_support_layer_height || print_config.enable_prime_tower) { params.gap_raft_object = std::round(params.gap_raft_object / object_config.layer_height + EPSILON) * object_config.layer_height; @@ -167,7 +212,7 @@ SlicingParameters SlicingParameters::create_from_config( } else { params.gap_object_support = support_bottom_z_gap; - if (!print_config.independent_support_layer_height) { + if (!print_config.independent_support_layer_height || print_config.enable_prime_tower) { params.gap_object_support = std::round(params.gap_object_support / object_config.layer_height + EPSILON) * object_config.layer_height; @@ -180,7 +225,7 @@ SlicingParameters SlicingParameters::create_from_config( } else { params.gap_support_object = support_top_z_gap; - if (!print_config.independent_support_layer_height) { + if (!print_config.independent_support_layer_height || print_config.enable_prime_tower) { params.gap_support_object = std::round(params.gap_support_object / object_config.layer_height + EPSILON) * object_config.layer_height; diff --git a/src/libslic3r/Slicing.hpp b/src/libslic3r/Slicing.hpp index f735ec55186..3557aeb2c97 100644 --- a/src/libslic3r/Slicing.hpp +++ b/src/libslic3r/Slicing.hpp @@ -71,6 +71,8 @@ struct SlicingParameters coordf_t min_layer_height { 0 }; coordf_t max_layer_height { 0 }; coordf_t max_suport_layer_height { 0 }; + // The support extruders' own minimum, not clamped to the object layer height. + coordf_t min_suport_layer_height { 0 }; // First layer height of the print, this may be used for the first layer of the raft // or for the first layer of the print. diff --git a/src/libslic3r/Support/SupportMaterial.cpp b/src/libslic3r/Support/SupportMaterial.cpp index cd60489e755..900dacd4549 100644 --- a/src/libslic3r/Support/SupportMaterial.cpp +++ b/src/libslic3r/Support/SupportMaterial.cpp @@ -1748,7 +1748,7 @@ static inline std::pair new_cont } else { // BBS: need to consider adaptive layer heights - if (print_config.independent_support_layer_height) { + if (support_layer_heights_free(print_config)) { print_z = layer.bottom_z() - slicing_params.gap_support_object; height = 0; } @@ -1781,13 +1781,13 @@ static inline std::pair new_cont // Contact layer will be printed with a normal flow, but // it will support layers printed with a bridging flow. - if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer) && print_config.independent_support_layer_height) { + if (object_config.thick_bridges && SupportMaterialInternal::has_bridging_extrusions(layer) && support_layer_heights_free(print_config)) { coordf_t bridging_height = 0.; for (const LayerRegion* region : layer.regions()) bridging_height += region->region().bridging_height_avg(print_config); bridging_height /= coordf_t(layer.regions().size()); // BBS: align bridging height - if (!print_config.independent_support_layer_height) + if (!support_layer_heights_free(print_config)) bridging_height = std::ceil(bridging_height / object_config.layer_height - EPSILON) * object_config.layer_height; coordf_t bridging_print_z = layer.print_z - bridging_height - slicing_params.gap_support_object; if (bridging_print_z >= min_print_z) { @@ -1807,7 +1807,7 @@ static inline std::pair new_cont } else { // BBS: if independent_support_layer_height is not enabled, the support layer_height should be the same as layer height. // Note that for this case, adaptive layer height must be disabled. - bridging_layer->height = print_config.independent_support_layer_height ? 0. : object_config.layer_height; + bridging_layer->height = support_layer_heights_free(print_config) ? 0. : object_config.layer_height; // Don't know the height yet. bridging_layer->bottom_z = bridging_print_z - bridging_layer->height; } @@ -2150,7 +2150,7 @@ SupportGeneratorLayersPtr PrintObjectSupportMaterial::top_contact_layers( // check if the sharp tails should be extended higher bool detect_first_sharp_tail_only = false; - const coordf_t extrusion_width = m_object_config->line_width.get_abs_value(object.print()->config().nozzle_diameter.get_at(object.config().support_interface_filament-1)); + const coordf_t extrusion_width = m_object_config->line_width.get_abs_value(support_material_nozzle_diameter(&object, object.config().support_interface_filament)); const coordf_t extrusion_width_scaled = scale_(extrusion_width); if (is_auto(m_object_config->support_type.value) && g_config_support_sharp_tails && !detect_first_sharp_tail_only) { for (size_t layer_nr = layer_id_start; layer_nr < num_layers; layer_nr++) { @@ -2419,7 +2419,7 @@ static inline SupportGeneratorLayer* detect_bottom_contacts( // with some spacing from object - it looks we don't need the actual // top shapes so this can be done here Layer* upper_layer = layer.upper_layer; - if (object.print()->config().independent_support_layer_height) { + if (support_layer_heights_free(object.print()->config())) { // If the layer is extruded with no bridging flow, support just the normal extrusions. layer_new.height = slicing_params.zero_gap_interface_bottom ? // Align the interface layer with the object's layer height. diff --git a/src/libslic3r/Support/SupportMaterial.hpp b/src/libslic3r/Support/SupportMaterial.hpp index 50b8256c4a3..024f7e0dceb 100644 --- a/src/libslic3r/Support/SupportMaterial.hpp +++ b/src/libslic3r/Support/SupportMaterial.hpp @@ -28,7 +28,9 @@ class PrintObjectSupportMaterial bool has_support() const { return m_object_config->enable_support.value || m_object_config->enforce_support_layers; } bool build_plate_only() const { return this->has_support() && m_object_config->support_on_build_plate_only.value; } // BBS - bool synchronize_layers() const { return /*m_slicing_params.zero_gap_interface_top && */!m_print_config->independent_support_layer_height.value; } + // Free-form support heights only without the prime tower: with the tower on, the classic + // generator keeps every support layer on the object grid (see support_layer_heights_free()). + bool synchronize_layers() const { return !m_print_config->independent_support_layer_height.value || m_print_config->enable_prime_tower.value; } bool has_contact_loops() const { return m_object_config->support_interface_loop_pattern.value; } // Generate support material for the object. diff --git a/src/libslic3r/Support/SupportParameters.hpp b/src/libslic3r/Support/SupportParameters.hpp index dc0e94ed03b..68d7d430f54 100644 --- a/src/libslic3r/Support/SupportParameters.hpp +++ b/src/libslic3r/Support/SupportParameters.hpp @@ -14,6 +14,13 @@ inline int number_of_support_interface_bottom_layers(const PrintObjectConfig& ob object_config.support_interface_bottom_layers.value; } +// Free-form (off-grid) support layer heights are only allowed without the prime tower; +// with the tower enabled the classic generator synchronizes with the object layers and +// tree supports plan grid-aligned thick layers instead. +inline bool support_layer_heights_free(const PrintConfig &print_config) { + return print_config.independent_support_layer_height && !print_config.enable_prime_tower; +} + struct SupportParameters { SupportParameters() = delete; SupportParameters(const PrintObject& object) @@ -179,12 +186,26 @@ struct SupportParameters { assert(slicing_params.raft_layers() == 0); } - const auto nozzle_diameter = print_config.nozzle_diameter.get_at(object_config.support_interface_filament - 1); + // ORCA: honors the support nozzle diameter restriction for "default" support filaments. + const auto nozzle_diameter = support_material_nozzle_diameter(&object, object_config.support_interface_filament); const coordf_t extrusion_width = object_config.line_width.get_abs_value(nozzle_diameter); support_extrusion_width = object_config.support_line_width.get_abs_value(nozzle_diameter); support_extrusion_width = support_extrusion_width > 0 ? support_extrusion_width : extrusion_width; independent_layer_height = print_config.independent_support_layer_height; + // The prime tower is built on the object layer grid, so toolchanges must land on + // grid Zs: independent support heights stay enabled but snap to whole multiples + // of object layers (tree supports; the classic generator synchronizes instead). + grid_aligned_layer_height = independent_layer_height && print_config.enable_prime_tower; + // Sub-layer step for grid-aligned heights: 1 = whole object layers, 2/4 allow + // boundaries on half/quarter subdivisions (thin tower layers appear there). + grid_height_step = 1; + if (grid_aligned_layer_height && !print_config.single_extruder_multi_material) { + if (print_config.support_layer_height_step.value == slhsHalfLayer) + grid_height_step = 2; + else if (print_config.support_layer_height_step.value == slhsQuarterLayer) + grid_height_step = 4; + } // force double walls everywhere if wall count is larger than 1 tree_branch_diameter_double_wall_area_scaled = object_config.tree_support_wall_count.value > 1 ? 0.1 : @@ -315,6 +336,9 @@ struct SupportParameters { } bool independent_layer_height = false; + bool grid_aligned_layer_height = false; + // 1 = whole object layers; 2/4 = half/quarter sub-layer boundaries allowed. + int grid_height_step = 1; const double thresh_big_overhang = Slic3r::sqr(scale_(10)); bool ironing; diff --git a/src/libslic3r/Support/TreeSupport.cpp b/src/libslic3r/Support/TreeSupport.cpp index de088702160..82509540276 100644 --- a/src/libslic3r/Support/TreeSupport.cpp +++ b/src/libslic3r/Support/TreeSupport.cpp @@ -1356,7 +1356,7 @@ void TreeSupport::generate_toolpaths() { const PrintObjectConfig &object_config = m_object->config(); coordf_t support_extrusion_width = m_support_params.support_extrusion_width; - coordf_t nozzle_diameter = m_print_config->nozzle_diameter.get_at(object_config.support_filament - 1); + coordf_t nozzle_diameter = support_material_nozzle_diameter(m_object, object_config.support_filament); coordf_t layer_height = object_config.layer_height.value; const size_t wall_count = object_config.tree_support_wall_count.value; @@ -3259,6 +3259,154 @@ std::vector TreeSupport::plan_layer_heights() z_heights[m_object->get_layer(layer_nr)->print_z] = m_object->get_layer(layer_nr)->height; layer_heights[layer_nr] = {m_object->get_layer(layer_nr)->print_z, m_object->get_layer(layer_nr)->height, size_t(layer_nr)}; } + } else if (m_support_params.grid_aligned_layer_height) { + // Grid-aligned independent heights: support boundaries land on object layers or, + // with a finer configured step, on half/quarter subdivisions of them. Boundaries + // on the object grid keep every toolchange on an existing prime tower layer; + // sub-layer boundaries get their own (thinner) tower layers, which costs extra + // purge there but lets support heights exceed whole multiples (e.g. 1.5x) when + // the support nozzle's maximum lies between two whole multiples. + const int height_step = std::max(1, m_support_params.grid_height_step); + // The support extruder's own minimum is not clamped to the object layer height: a + // coarse support nozzle under a fine object grid must not get sub-minimum tails. + const coordf_t min_layer_height = std::max(m_slicing_params.min_layer_height, m_slicing_params.min_suport_layer_height); + // Floor the maximum at one sub-step: a support nozzle with a maximum below the object + // pitch then closes its pieces on sub-grid positions instead of whole object layers. + const coordf_t max_layer_height = std::max({m_slicing_params.max_suport_layer_height, m_object->config().layer_height.value / height_step, min_layer_height}); + const size_t n = m_object->layer_count(); + // Fractional support-only layers normally get no prime tower layer (their + // toolchange goes straight to the support filament), so they impose nothing on + // the tower. Smooth timelapse is the exception: it needs a tower layer on every + // print layer, so there a fractional boundary splits an object layer into two + // tower slabs and both must stay printable by every filament - gate sub-positions + // on the strictest configured minimum layer height (0 = the 0.07 mm default). + coordf_t tower_min_slab = 0.; + if (m_object->print()->config().timelapse_type.value == TimelapseType::tlSmooth) + for (unsigned int extruder_id : m_object->print()->extruders()) { + coordf_t min_h = m_object->print()->config().min_layer_height.get_at(extruder_id); + tower_min_slab = std::max(tower_min_slab, min_h == 0. ? 0.07 : min_h); + } + // Sub-positions of an object layer usable as piece boundaries. Fractional positions + // keep a quantum comfortably above the tower plan's 1e-3 mm Z-merge epsilon, or the + // layer is left unsplittable. + auto sub_positions = [&](const Layer *layer, std::vector &out) { + out.clear(); + const coordf_t h = layer->height; + const int steps = h / height_step > 0.002 ? height_step : 1; + for (int k = 1; k < steps; ++k) { + const coordf_t below = h * k / steps; + if (below < tower_min_slab - EPSILON || h - below < tower_min_slab - EPSILON) + continue; // a tower slab on either side of this boundary would be too thin + out.push_back(layer->print_z - h + below); + } + }; + // A run must end exactly at a top-contact layer so the support tops keep their + // contact Z (mirrors the boundaries the free-form planner inserts), and the contact + // layer itself prints at the object layer height for interface quality. + std::vector boundary(n + 1, 0); + std::vector forced_close_zs; // exact support tops between object layers + std::vector layer_subs; + for (size_t layer_nr = 1; layer_nr < contact_nodes.size() && layer_nr < n; ++layer_nr) + if (!contact_nodes[layer_nr].empty()) { + boundary[layer_nr] = 1; + boundary[layer_nr + 1] = 1; + // The support top sits support_top_z_distance below the contact (the contact + // node's height is that gap, as the free-form planner uses it). Close a piece + // exactly there: on a sub-position of the object layer containing it when the + // step allows, otherwise at the nearest object layer below - or the gap rounds + // up to a whole support piece. + const SupportNode *node = contact_nodes[layer_nr].front(); + if (node->height > EPSILON) { + const coordf_t gap_bottom = node->print_z - node->height; + for (size_t j = layer_nr; j-- > 0;) + if (m_object->get_layer(j)->print_z <= gap_bottom + EPSILON) { + bool on_sub_position = false; + if (j + 1 < n) { + sub_positions(m_object->get_layer(j + 1), layer_subs); + for (coordf_t z : layer_subs) + if (std::abs(z - gap_bottom) < EPSILON) { on_sub_position = true; break; } + } + if (on_sub_position) + forced_close_zs.push_back(gap_bottom); + else + boundary[j + 1] = 1; + break; + } + } + } + auto forced_close = [&forced_close_zs](coordf_t z) { + for (coordf_t f : forced_close_zs) + if (std::abs(f - z) < EPSILON) + return true; + return false; + }; + layer_heights.reserve(n); + layer_heights.push_back({m_object->get_layer(0)->print_z, m_object->get_layer(0)->height, 0}); + // A candidate boundary: a sub-position of an object layer. + struct SubPos { coordf_t z; size_t obj_layer_nr; }; + std::vector subs; + size_t i = 1; + while (i < n) { + size_t span_end = i + 1; + while (span_end < n && !boundary[span_end]) ++span_end; + // Sub-position ladder over object layers i..span_end-1. Grid positions use the + // layer's print_z verbatim so they stay bit-exact. + subs.clear(); + for (size_t l = i; l < span_end; ++l) { + const Layer *layer = m_object->get_layer(l); + sub_positions(layer, layer_subs); + for (coordf_t z : layer_subs) + subs.push_back({z, l}); + subs.push_back({layer->print_z, l}); + } + // Pieces are laid out per segment: the ladder up to each forced close (an exact + // support top) and the remainder get the same closing and rebalancing. + coordf_t piece_start = m_object->get_layer(i)->print_z - m_object->get_layer(i)->height; + size_t seg_begin = 0; + while (seg_begin < subs.size()) { + size_t seg_end = seg_begin; // index of the last ladder position of this segment + while (seg_end + 1 < subs.size() && !forced_close(subs[seg_end].z)) ++seg_end; + const size_t pieces_begin = layer_heights.size(); + for (size_t s = seg_begin; s <= seg_end; ++s) { + // Close the piece at the segment end, or right before the sub-position that + // would push it past the maximum support layer height. + if (s == seg_end || subs[s + 1].z - piece_start > max_layer_height + EPSILON) { + layer_heights.push_back({subs[s].z, subs[s].z - piece_start, subs[s].obj_layer_nr}); + piece_start = subs[s].z; + } + } + // Rebalance a trailing piece thinner than the support minimum. + if (layer_heights.size() - pieces_begin >= 2 && layer_heights.back().height < min_layer_height - EPSILON) { + LayerHeightData tail = layer_heights.back(); layer_heights.pop_back(); + LayerHeightData prev = layer_heights.back(); layer_heights.pop_back(); + const coordf_t combined_start = prev.print_z - prev.height; + const coordf_t combined = tail.print_z - combined_start; + if (combined <= max_layer_height + EPSILON) { + layer_heights.push_back({tail.print_z, combined, tail.obj_layer_nr}); + } else { + // Cannot merge: split the two pieces as evenly as the sub-grid allows. + const coordf_t ideal = combined_start + combined / 2.; + size_t best = subs.size(); + // Both halves must respect the support minimum, or the split just moves + // the thin piece. + for (size_t s = seg_begin; s <= seg_end; ++s) + if (subs[s].z - combined_start >= min_layer_height - EPSILON && tail.print_z - subs[s].z >= min_layer_height - EPSILON && + (best == subs.size() || std::abs(subs[s].z - ideal) < std::abs(subs[best].z - ideal))) + best = s; + if (best < subs.size()) { + layer_heights.push_back({subs[best].z, subs[best].z - combined_start, subs[best].obj_layer_nr}); + layer_heights.push_back({tail.print_z, tail.print_z - subs[best].z, tail.obj_layer_nr}); + } else { + // No usable split point: keep the original pieces, thin tail and all. + layer_heights.push_back(prev); + layer_heights.push_back(tail); + } + } + } + seg_begin = seg_end + 1; + } + i = span_end; + } } else { const coordf_t max_layer_height = m_slicing_params.max_suport_layer_height; const coordf_t min_layer_height = m_slicing_params.min_layer_height; diff --git a/src/sentry_wrapper/SentryWrapper.cpp b/src/sentry_wrapper/SentryWrapper.cpp index 097c7d34111..69e8bbba6df 100644 --- a/src/sentry_wrapper/SentryWrapper.cpp +++ b/src/sentry_wrapper/SentryWrapper.cpp @@ -240,6 +240,15 @@ void initSentryEx() std::cout<< "Failed to get temp path, Sentry data directory will be empty"; } } +#else + // Linux: the breakpad backend runs in-process, so no handler path is + // needed; keep the minidump database under the XDG data directory. + const char* xdg_data_env = std::getenv("XDG_DATA_HOME"); + const char* home_dir_env = std::getenv("HOME"); + if (xdg_data_env != nullptr && xdg_data_env[0] != '\0') + dataBaseDir = std::string(xdg_data_env) + "/Snapmaker_Orca/SentryData"; + else if (home_dir_env != nullptr && home_dir_env[0] != '\0') + dataBaseDir = std::string(home_dir_env) + "/.local/share/Snapmaker_Orca/SentryData"; #endif if (!handlerDir.empty()) diff --git a/src/slic3r/GUI/BackgroundSlicingProcess.cpp b/src/slic3r/GUI/BackgroundSlicingProcess.cpp index 64c52c6e72f..4aa8d555b60 100644 --- a/src/slic3r/GUI/BackgroundSlicingProcess.cpp +++ b/src/slic3r/GUI/BackgroundSlicingProcess.cpp @@ -468,6 +468,9 @@ void BackgroundSlicingProcess::call_process(std::exception_ptr& ex) throw() assert(m_print->canceled()); ex = std::current_exception(); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":got cancelled exception" << std::endl; + } catch (const std::exception &e) { + ex = std::current_exception(); + BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":got exception: " << e.what() << std::endl; } catch (...) { ex = std::current_exception(); BOOST_LOG_TRIVIAL(error) << __FUNCTION__ << ":got other exception" << std::endl; diff --git a/src/slic3r/GUI/ConfigManipulation.cpp b/src/slic3r/GUI/ConfigManipulation.cpp index 4009de8f442..6f829fb6ee0 100644 --- a/src/slic3r/GUI/ConfigManipulation.cpp +++ b/src/slic3r/GUI/ConfigManipulation.cpp @@ -16,6 +16,10 @@ #include #include +#include +#include +#include +#include namespace Slic3r { namespace GUI { @@ -49,6 +53,18 @@ void ConfigManipulation::apply(DynamicPrintConfig* config, DynamicPrintConfig* n bool ConfigManipulation::is_applying() const { return is_msg_dlg_already_exist; } +// ORCA: printers whose extruders have differing nozzle diameters. +bool ConfigManipulation::printer_has_mixed_nozzle_sizes() +{ + const auto *diameters = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter"); + if (diameters == nullptr || diameters->values.empty()) + return false; + for (double d : diameters->values) + if (std::abs(d - diameters->values.front()) > EPSILON) + return true; + return false; +} + t_config_option_keys const &ConfigManipulation::applying_keys() const { return m_applying_keys; @@ -733,6 +749,11 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in apply(config, &new_conf); } + // ORCA: per-extruder layer height: the thick layer tolerance only drives the consistent / + // adaptive drift checks; fixed mode ignores it. + toggle_field("extruder_layer_height_tolerance", + config->opt_enum("extruder_layer_height_mode") != elhmFixed); + bool have_perimeters = config->opt_int("wall_loops") > 0; for (auto el : { "extra_perimeters_on_overhangs", "ensure_vertical_shell_thickness", "detect_thin_wall", "detect_overhang_wall", "seam_position", "staggered_inner_seams", "wall_sequence", "outer_wall_line_width" }) @@ -740,6 +761,12 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in for (auto el : { "inner_wall_speed", "outer_wall_speed", "small_perimeter_speed", "small_perimeter_threshold" }) toggle_field(el, have_perimeters, variant_index); + // ORCA: split wall layer heights - the adjustment target and direction only matter while + // the adjustment itself is enabled. + const bool split_wall_adjust = config->opt_bool("split_wall_adjust"); + toggle_line("split_wall_adjust_filament", split_wall_adjust); + toggle_line("split_wall_adjust_direction", split_wall_adjust); + bool have_infill = config->option("sparse_infill_density")->value > 0; // sparse_infill_filament_id uses the same logic as in Print::extruders() for (auto el : { "sparse_infill_pattern", "infill_combination", "fill_multiline","infill_direction", @@ -950,6 +977,10 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in // ORCA: Independent support layer height is not compatible with organic tree supports, // as they rely on the support layers being the same as the object layers to determine where to place branches. toggle_line("independent_support_layer_height", have_support_material && !support_is_organic); + // The step only has an effect for non-organic tree supports with independent layer heights + // under the prime tower; single-extruder multi-material keeps whole steps. + toggle_line("support_layer_height_step", support_is_normal_tree && config->opt_bool("independent_support_layer_height") && + config->opt_bool("enable_prime_tower") && !bSEMM); toggle_field("tree_support_brim_width", support_is_tree && !config->opt_bool("tree_support_auto_brim")); // tree support use max_bridge_length instead of bridge_no_support @@ -985,6 +1016,18 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in toggle_field("inner_wall_line_width", have_perimeters || have_skirt || have_brim); toggle_field("support_filament", have_support_material || have_skirt); + // ORCA: support_nozzle_diameter only applies to printers whose extruders have differing + // nozzle diameters; the material options serve any multi-filament setup and stay visible + // like the other support rows. The legacy base/interface selectors show only while the + // "Show legacy filament selection" toggle is on; opening a 3mf project with an assigned + // selector switches the toggle on (see Plater's project loading). + toggle_line("support_nozzle_diameter", have_support_material && printer_has_mixed_nozzle_sizes()); + toggle_field("support_base_material", have_support_material || have_skirt); + toggle_field("support_interface_material", have_support_material); + const bool legacy_support_selectors = wxGetApp().app_config->get_bool("show_legacy_support_filament"); + toggle_line("support_filament", legacy_support_selectors); + toggle_line("support_interface_filament", legacy_support_selectors); + toggle_line("raft_contact_distance", have_raft && !have_support_soluble); // Orca: First-layer density is available for supports broadly. @@ -1262,6 +1305,91 @@ void ConfigManipulation::toggle_print_sla_options(DynamicPrintConfig* config) toggle_field("pad_object_connector_penetration", zero_elev); } +// ORCA: dialog raised when the user enables support on a printer with differing nozzle sizes: +// the nozzle size that prints the support, and the loaded filament types used for the raft/base +// and the interface. Writes support_nozzle_diameter and the two support material options, which +// exclude extruders of other types at slice time; the legacy selectors stay untouched. +int ConfigManipulation::show_support_filament_dialog(DynamicPrintConfig* config, DynamicPrintConfig* new_conf) +{ + PresetBundle &bundle = *wxGetApp().preset_bundle; + const auto *nozzle_opt = bundle.printers.get_edited_preset().config.option("nozzle_diameter"); + if (nozzle_opt == nullptr || nozzle_opt->values.empty()) + return wxID_CANCEL; + const std::vector &nozzles = nozzle_opt->values; + + // The distinct nozzle sizes and the loaded filaments' types, keeping extruder / slot order. + std::vector sizes; + for (double d : nozzles) + if (std::find_if(sizes.begin(), sizes.end(), [d](double s) { return std::abs(s - d) < EPSILON; }) == sizes.end()) + sizes.emplace_back(d); + std::vector types; + for (const std::string &name : bundle.filament_presets) { + const Preset *preset = bundle.filaments.find_preset(name); + const std::string type = preset != nullptr ? preset->config.opt_string("filament_type", 0u) : std::string(); + if (! type.empty() && std::find(types.begin(), types.end(), type) == types.end()) + types.emplace_back(type); + } + + wxDialog dlg(m_msg_dlg_parent, wxID_ANY, _(L("Support for mixed nozzle sizes"))); + auto *sizer = new wxBoxSizer(wxVERTICAL); + auto *intro = new wxStaticText(&dlg, wxID_ANY, + _(L("This printer uses different nozzle sizes. Select the nozzle size that prints the " + "support, and the filament types used for the raft and the support interface."))); + intro->Wrap(dlg.FromDIP(400)); + sizer->Add(intro, 0, wxALL, 10); + auto add_choice = [&dlg, sizer](const wxString &label, const wxArrayString &items, int selection) { + auto *row = new wxBoxSizer(wxHORIZONTAL); + row->Add(new wxStaticText(&dlg, wxID_ANY, label), 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, 8); + auto *choice = new wxComboBox(&dlg, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, items, wxCB_READONLY); + choice->SetSelection(selection); + row->Add(choice, 1, wxALIGN_CENTER_VERTICAL); + sizer->Add(row, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10); + return choice; + }; + + wxArrayString size_items; + int size_selection = 0; + for (size_t i = 0; i < sizes.size(); ++ i) { + size_items.Add(wxString::Format("%g mm", sizes[i])); + if (std::abs(sizes[i] - config->opt_float("support_nozzle_diameter")) < EPSILON) + size_selection = int(i); + } + wxArrayString type_items; + type_items.Add(_(L("Default"))); + for (const std::string &type : types) + type_items.Add(wxString::FromUTF8(type)); + // Preselect the currently configured materials. + auto type_selection = [&](const char *key) { + const std::string &material = config->opt_string(key); + for (size_t i = 0; i < types.size(); ++ i) + if (types[i] == material) + return int(i) + 1; + return 0; + }; + auto *size_choice = add_choice(_(L("Support nozzle size")), size_items, size_selection); + auto *base_choice = add_choice(_(L("Raft and support base")), type_items, type_selection("support_base_material")); + auto *interface_choice = add_choice(_(L("Support interface")), type_items, type_selection("support_interface_material")); + sizer->Add(dlg.CreateSeparatedButtonSizer(wxOK | wxCANCEL), 0, wxEXPAND | wxALL, 10); + if (wxWindow *btn = dlg.FindWindow(wxID_OK); btn != nullptr) + btn->SetLabel(_(L("OK"))); + if (wxWindow *btn = dlg.FindWindow(wxID_CANCEL); btn != nullptr) + btn->SetLabel(_(L("Cancel"))); + dlg.SetSizerAndFit(sizer); + dlg.CentreOnScreen(); + const int answer = dlg.ShowModal(); + if (answer != wxID_OK) + return answer; + + const double size = sizes[std::max(0, size_choice->GetSelection())]; + auto material_of = [&types](int choice) { + return choice <= 0 ? std::string() : types[choice - 1]; + }; + new_conf->set_key_value("support_nozzle_diameter", new ConfigOptionFloat(size)); + new_conf->set_key_value("support_base_material", new ConfigOptionString(material_of(base_choice->GetSelection()))); + new_conf->set_key_value("support_interface_material", new ConfigOptionString(material_of(interface_choice->GetSelection()))); + return answer; +} + int ConfigManipulation::show_spiral_mode_settings_dialog(bool is_object_config) { wxString msg_text = _(L("Spiral mode only works when wall loops is 1, support is disabled, clumping detection by probing is disabled, top shell layers is 0, sparse infill density is 0 and timelapse type is traditional.")); diff --git a/src/slic3r/GUI/ConfigManipulation.hpp b/src/slic3r/GUI/ConfigManipulation.hpp index ac53ffb4bb6..563c15e269d 100644 --- a/src/slic3r/GUI/ConfigManipulation.hpp +++ b/src/slic3r/GUI/ConfigManipulation.hpp @@ -102,6 +102,9 @@ class ConfigManipulation m_support_material_overhangs_queried = queried; } int show_spiral_mode_settings_dialog(bool is_object_config = false); + // ORCA: support filament dialog for printers with differing nozzle sizes. + int show_support_filament_dialog(DynamicPrintConfig* config, DynamicPrintConfig* new_conf); + static bool printer_has_mixed_nozzle_sizes(); private: bool get_temperature_range(DynamicPrintConfig *config, int &range_low, int &range_high); diff --git a/src/slic3r/GUI/GUI_ObjectList.cpp b/src/slic3r/GUI/GUI_ObjectList.cpp index 4912bef104e..879232a3da1 100644 --- a/src/slic3r/GUI/GUI_ObjectList.cpp +++ b/src/slic3r/GUI/GUI_ObjectList.cpp @@ -749,6 +749,12 @@ ModelConfig& ObjectList::get_item_config(const wxDataViewItem& item) const (*m_objects)[obj_idx]->config; } +// ORCA: per-object/per-part support and feature filament selectors. They must track filament +// count changes alongside the "extruder" selector, or a stale id lands on the wrong filament. +static const char *filament_selector_keys[] = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", + "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", + "support_filament", "support_interface_filament"}; + void ObjectList::update_filament_values_for_items(const size_t filaments_count) { for (size_t i = 0; i < m_objects->size(); ++i) @@ -767,10 +773,7 @@ void ObjectList::update_filament_values_for_items(const size_t filaments_count) } m_objects_model->SetExtruder(extruder, item); - static const char *keys[] = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", - "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", - "support_filament", "support_interface_filament"}; - for (auto key : keys) + for (auto key : filament_selector_keys) if (object->config.has(key) && object->config.opt_int(key) > filaments_count) object->config.erase(key); @@ -792,7 +795,7 @@ void ObjectList::update_filament_values_for_items(const size_t filaments_count) m_objects_model->SetExtruder(extruder, item); - for (auto key : keys) + for (auto key : filament_selector_keys) if (object->volumes[id]->config.has(key) && object->volumes[id]->config.opt_int(key) > filaments_count) object->volumes[id]->config.erase(key); } @@ -804,7 +807,7 @@ void ObjectList::update_filament_values_for_items(const size_t filaments_count) } // NOTE: the "when delete filament" remapping helpers live further down in this file -// (the Snapmaker variants that also remap the per-feature filament selectors and the +// (the Snapmaker variants that also remap the per-feature *_filament_id selectors and the // height-range configs); the duplicate Orca copy that used to sit here was dropped. void ObjectList::update_plate_values_for_items() @@ -972,10 +975,7 @@ void ObjectList::update_filament_values_for_items_when_delete_filament(const siz } m_objects_model->SetExtruder(extruder, item); - static const char* keys[] = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", - "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", - "support_filament", "support_interface_filament"}; - for (auto key : keys) { + for (auto key : filament_selector_keys) { if (object->config.has(key)) { if (object->config.opt_int(key) == filament_id + 1) object->config.erase(key); @@ -993,7 +993,7 @@ void ObjectList::update_filament_values_for_items_when_delete_filament(const siz if (!item) continue; - for (auto key : keys) { + for (auto key : filament_selector_keys) { if (object->volumes[id]->config.has(key)) { if (object->volumes[id]->config.opt_int(key) == filament_id + 1) object->volumes[id]->config.erase(key); @@ -1050,6 +1050,16 @@ void ObjectList::update_filament_values_for_items_when_delete_filament(const siz extruder = wxString::Format("%d", new_extruder); layer_range_item.second.set("extruder", new_extruder); } + // Height ranges carry the per-feature selectors too (the engine reads them from + // layer_config_ranges); remap them like the object / volume configs above. + for (auto key : filament_selector_keys) { + if (layer_range_item.second.has(key)) { + if (layer_range_item.second.option(key)->getInt() == int(filament_id) + 1) + layer_range_item.second.erase(key); + else if (layer_range_item.second.option(key)->getInt() > int(filament_id)) + layer_range_item.second.set(key, layer_range_item.second.option(key)->getInt() - 1); + } + } m_objects_model->SetExtruder(extruder, layer_item); } } diff --git a/src/slic3r/GUI/OptionsGroup.cpp b/src/slic3r/GUI/OptionsGroup.cpp index 7117bc2a912..6490f0b2614 100644 --- a/src/slic3r/GUI/OptionsGroup.cpp +++ b/src/slic3r/GUI/OptionsGroup.cpp @@ -177,10 +177,10 @@ void OptionsGroup::set_max_win_width(int max_win_width) void OptionsGroup::remove_option_if(std::function const& comp) { // m_options_mode parallels only the lines that carried options when appended: - // append_line() skips the mode push for full-width widget lines, and append_separator() - // adds an optionless line directly. Walk the two structures in step - indexing - // m_options_mode with the m_lines index reads and erases out of bounds as soon as one - // such line exists. + // append_line() skips the mode push for full-width widget lines and optionless + // (widget-only) lines, e.g. the legacy support selection toggle. Walk the two + // structures in step - indexing m_options_mode with the m_lines index reads and + // erases out of bounds as soon as one such line exists. size_t mode_idx = 0; for (auto& l : m_lines) { auto& opts = const_cast&>(l.get_options()); @@ -272,6 +272,8 @@ void OptionsGroup::append_line(const Line& line) // BBS: get line for opt_key Line* OptionsGroup::get_line(const std::string& opt_key) { + // ORCA: widget-only lines (e.g. the legacy support selection toggle) carry no options; the + // per-option scan below simply skips them. for (int index = 0; index < m_lines.size(); index++) { for (auto& opt : m_lines[index].get_options()) if (opt.opt_id == opt_key) diff --git a/src/slic3r/GUI/Plater.cpp b/src/slic3r/GUI/Plater.cpp index e118de4ccff..bad4ed84422 100644 --- a/src/slic3r/GUI/Plater.cpp +++ b/src/slic3r/GUI/Plater.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -447,19 +448,20 @@ static void collect_filament_slots_from_config( const DynamicPrintConfig& config, int num_filaments, std::set& used_slots_0_based) { - // Support/feature filaments - static const std::vector feature_keys = { - "support_filament", - "support_interface_filament", + // All feature filament keys use 0 = "Default" (inherit the active object/part filament), + // so only explicit selections (>= 1) mark a slot as used. + static const std::vector keys_with_default = { "outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", + "support_filament", + "support_interface_filament", "wipe_tower_filament" }; - for (const char* key : feature_keys) + for (const char* key : keys_with_default) { const ConfigOptionInt* option = config.option(key); if (option != nullptr && option->value >= 1 && option->value <= num_filaments) @@ -484,16 +486,17 @@ static void collect_filament_slots_from_model_config( used_slots_0_based.insert(extruder_id - 1); } - // Support/feature filaments + // Per-object feature-specific keys (outer_wall_filament_id, etc.) may be + // overridden independently of the object's primary extruder. static const std::vector feature_keys = { - "support_filament", - "support_interface_filament", "outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", + "support_filament", + "support_interface_filament", "wipe_tower_filament" }; for (const char* key : feature_keys) @@ -511,7 +514,9 @@ static void collect_filament_slots_from_model_config( /// \details Mirrors the slot-collection block of Plater::check_filament_temp_mixing so that /// cold-plate incompatibility checking uses the same definition of "used filament". /// Includes: plate config, per-object/volume configs, plus Plater working config -/// (wipe_tower / support / wall / infill defaults when any object uses extruder=0). +/// (wipe_tower / support always; global feature selectors unless every object/part +/// on the plate overrides the same key; the default extruder when any object uses +/// extruder=0). /// \param[in] plate Non-null target plate. /// \param[in] num_filaments Total number of filaments in the current configuration. /// \param[in] plater_working_config The Plater's current working config (this->config()). @@ -530,7 +535,17 @@ static void collect_used_filament_slots_on_plate( // Plate-local config collect_filament_slots_from_config(*plate->config(), num_filaments, used_slots_0_based); - // Per-object + per-volume config + // Per-object + per-volume config. Also track, per feature selector, whether + // any object/part on the plate still follows the global value. + static const std::vector selector_keys = { + "outer_wall_filament_id", + "inner_wall_filament_id", + "sparse_infill_filament_id", + "internal_solid_filament_id", + "top_surface_filament_id", + "bottom_surface_filament_id" + }; + std::vector selector_overridden_everywhere(selector_keys.size(), true); bool uses_default_extruder = false; for (size_t obj_idx = 0; obj_idx < wxGetApp().model().objects.size(); ++obj_idx) { const ModelObject* model_object = wxGetApp().model().objects[obj_idx]; @@ -548,10 +563,25 @@ static void collect_used_filament_slots_on_plate( used_slots_0_based.insert(extruder_id - 1); } } + + // A global selector reaches this object's regions unless the object (or each of its + // printed parts) explicitly overrides the same key. + for (size_t k = 0; k < selector_keys.size(); ++k) { + if (!selector_overridden_everywhere[k] || model_object->config.has(selector_keys[k])) + continue; + bool all_parts_override = true; + for (const ModelVolume* model_volume : model_object->volumes) + if (model_volume->is_model_part() && !model_volume->config.has(selector_keys[k])) { + all_parts_override = false; + break; + } + if (!all_parts_override) + selector_overridden_everywhere[k] = false; + } } - // Plater working config — global features (always apply) + feature-specific - // keys (only when at least one object uses the default extruder). + // Plater working config — global features (always apply) + feature selectors + // (collected unless every object/part on the plate overrides the same key). if (plater_working_config != nullptr) { static const std::vector always_collect = {"wipe_tower_filament", "support_filament", "support_interface_filament"}; for (const char* key : always_collect) { @@ -560,13 +590,12 @@ static void collect_used_filament_slots_on_plate( used_slots_0_based.insert(option->value - 1); } - if (uses_default_extruder) { - static const std::vector default_keys = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id"}; - for (const char* key : default_keys) { - const ConfigOptionInt* option = plater_working_config->option(key); - if (option != nullptr && option->value >= 1 && option->value <= num_filaments) - used_slots_0_based.insert(option->value - 1); - } + for (size_t k = 0; k < selector_keys.size(); ++k) { + if (selector_overridden_everywhere[k]) + continue; + const ConfigOptionInt* option = plater_working_config->option(selector_keys[k]); + if (option != nullptr && option->value >= 1 && option->value <= num_filaments) + used_slots_0_based.insert(option->value - 1); } } @@ -1633,7 +1662,9 @@ struct Sidebar::priv // nozzle notebook and related controls CustomNotebook* m_nozzle_notebook{nullptr}; std::vector m_nozzle_diameter_lists; + std::vector m_nozzle_layer_height_lists; std::vector m_nozzle_edit_btns; + bool m_nozzle_rebuild_scheduled{false}; ObjectList *m_object_list{ nullptr }; ObjectSettings *object_settings{ nullptr }; @@ -4225,7 +4256,8 @@ Sidebar::Sidebar(Plater *parent) wxBoxSizer* nozzle_sizer = new wxBoxSizer(wxVERTICAL); nozzle_sizer->Add(p->m_nozzle_notebook, 1, wxEXPAND | wxALL, FromDIP(0)); nozzle_container->SetSizer(nozzle_sizer); - nozzle_container->SetMinSize(wxSize(-1, FromDIP(80))); + // Tall enough for the tab strip plus the Diameter and Preferred layer height rows. + nozzle_container->SetMinSize(wxSize(-1, FromDIP(112))); // 添加到主布局 vsizer_printer->Add(nozzle_container, 0, wxEXPAND | wxALL, FromDIP(4)); @@ -10932,6 +10964,115 @@ void Sidebar::update_dynamic_filament_list() dynamic_physical_filament_list.update(); } +// ORCA multi-nozzle-size: label of a nozzle diameter / layer height combo item. Formatted with +// the C locale (period decimal) to match the other "x.xmm" items and the ToCDouble parsing of +// the selection handlers. +static wxString nozzle_combo_label(double value) +{ + std::ostringstream oss; + oss.imbue(std::locale::classic()); + oss << value; + return wxString(oss.str()) + "mm"; +} + +// Numeric part of a nozzle_combo_label() item ("0.4mm" -> "0.4"); parse with ToCDouble(). +static wxString nozzle_combo_number(wxString label) +{ + if (label.EndsWith("mm")) + label.RemoveLast(2); + return label; +} + +// Show THIS nozzle's own diameter (per-nozzle sizes are supported), selecting the matching +// "x.xmm" item so the read-only combo accepts it. Falls back to the uniform printer_variant +// label only when the per-nozzle value is unavailable. +static void select_nozzle_diameter_label(ComboBox *diameter_combo, double this_nd) +{ + wxString this_label; + for (unsigned int n = 0; n < diameter_combo->GetCount(); ++n) { + const wxString item = diameter_combo->GetString(n); + double item_nd = 0.; + if (nozzle_combo_number(item).ToCDouble(&item_nd) && std::abs(item_nd - this_nd) < EPSILON) { + this_label = item; + break; + } + } + if (this_label.empty() && this_nd > 0.) { + // A per-nozzle diameter not among the printer's variant list (e.g. an imported config): + // add it so the combo can display the true value. + this_label = nozzle_combo_label(this_nd); + diameter_combo->AppendString(this_label); + } + if (this_label.empty()) { + const auto *pv = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("printer_variant"); + this_label = (pv ? wxString(pv->value) : wxString()) + "mm"; + } + diameter_combo->SetValue(this_label); +} + +// ORCA multi-nozzle-size: (re)fill one sidebar "Preferred layer height" combo with the target +// heights extruder `extruder_idx` may use: "Default" (= 0, follow the object layer height) plus +// every integer multiple of the object layer height that fits through the nozzle bore and lies +// within the extruder's layer height limits. +static void fill_nozzle_layer_height_combo(ComboBox *combo, size_t extruder_idx) +{ + const DynamicPrintConfig &printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + + const auto *nozzle_diameter = printer_config.option("nozzle_diameter"); + const auto *preferred = printer_config.option("extruder_layer_height"); + const auto *min_lh = printer_config.option("min_layer_height"); + const auto *max_lh = printer_config.option("max_layer_height"); + const auto *base_opt = print_config.option("layer_height"); + const double base_height = base_opt != nullptr ? base_opt->value : 0.; + + combo->Clear(); + combo->AppendString(_L("Default")); + + const double bore = (nozzle_diameter != nullptr && extruder_idx < nozzle_diameter->values.size()) ? + nozzle_diameter->values[extruder_idx] : 0.; + double cap = bore; + if (max_lh != nullptr && !max_lh->values.empty() && max_lh->get_at(extruder_idx) > EPSILON) + cap = std::min(cap, max_lh->get_at(extruder_idx)); + const double floor_lh = (min_lh != nullptr && !min_lh->values.empty()) ? min_lh->get_at(extruder_idx) : 0.; + const double current = (preferred != nullptr && !preferred->values.empty()) ? + std::max(0., preferred->get_at(extruder_idx)) : 0.; + + wxString current_label; + if (base_height > EPSILON) { + // Fractions of the object layer height for finer nozzles: selecting one lowers the + // object layer height to it and pins the other extruders to their current effective + // height, so the printed result is unchanged and the configuration stays valid. + for (int d = 4; d >= 2; d /= 2) { + const double height = base_height / d; + if (height + EPSILON < floor_lh || height > cap + EPSILON) + continue; + if (std::abs(height * 1000. - std::round(height * 1000.)) > 1e-6) + continue; // only cleanly representable heights + const wxString label = nozzle_combo_label(height); + combo->AppendString(label); + if (current > 0. && std::abs(height - current) < EPSILON) + current_label = label; + } + for (int n = 1; n * base_height <= cap + EPSILON; ++n) { + const double height = n * base_height; + if (height + EPSILON < floor_lh) + continue; + const wxString label = nozzle_combo_label(height); + combo->AppendString(label); + if (current > 0. && std::abs(height - current) < EPSILON) + current_label = label; + } + } + if (current_label.empty() && current > 0.) { + // An explicit preference no longer among the valid values (the object layer height or + // the limits changed after it was set) is still displayed truthfully; slicing warns. + current_label = nozzle_combo_label(current); + combo->AppendString(current_label); + } + combo->SetValue(current_label.empty() ? _L("Default") : current_label); +} + void Sidebar::update_nozzle_settings(bool switch_machine) { if (!p->m_nozzle_notebook) @@ -10943,23 +11084,19 @@ void Sidebar::update_nozzle_settings(bool switch_machine) auto* nozzle_diameter = dynamic_cast(printer_config.option("nozzle_diameter")); size_t new_nozzle_count = nozzle_diameter ? nozzle_diameter->values.size() : 1; - std::string diam_str = ""; - if (const auto* pv = printer_config.option("printer_variant")) // absent in bare configs - diam_str = pv->value; - - // Visible presets for this printer_model (system + user). - auto diameters = wxGetApp().preset_bundle->printers.diameters_of_selected_printer(); + // Avoid flicker while the notebook is torn down and rebuilt (2.3.6). + wxWindowUpdateLocker noUpdates(p->m_nozzle_notebook); - // Record focus before DeleteAllPages destroys the focused control. + // Record focus before DeleteAllPages destroys the focused control (2.3.6). bool focus_was_in_notebook = false; if (wxWindow* focus = wxWindow::FindFocus()) focus_was_in_notebook = p->m_nozzle_notebook->IsDescendant(focus); - wxWindowUpdateLocker noUpdates(p->m_nozzle_notebook); - - // Clear existing pages and controls + // Clear existing pages and controls, keeping the selected tab across the rebuild. + const int prev_page = p->m_nozzle_notebook->GetSelection(); p->m_nozzle_notebook->DeleteAllPages(); p->m_nozzle_diameter_lists.clear(); + p->m_nozzle_layer_height_lists.clear(); p->m_nozzle_edit_btns.clear(); // Recreate pages for new nozzle count @@ -10969,7 +11106,7 @@ void Sidebar::update_nozzle_settings(bool switch_machine) wxTAB_TRAVERSAL | wxBORDER_NONE); // nozzle_panel->SetBackgroundColour(wxColour(255, 255, 255)); - wxBoxSizer* tab_sizer = new wxBoxSizer(wxHORIZONTAL); + wxBoxSizer* tab_sizer = new wxBoxSizer(wxVERTICAL); // Add diameter label and combobox wxBoxSizer* diameter_sizer = new wxBoxSizer(wxHORIZONTAL); @@ -10988,70 +11125,112 @@ void Sidebar::update_nozzle_settings(bool switch_machine) nullptr, wxCB_READONLY); + // Visible presets for this printer_model (system + user). Imported multi-nozzle variants are + // usually non-system; diameters_for_same_printer_model() only counted system and kept the combo disabled. + auto diameters = wxGetApp().preset_bundle->printers.diameters_of_selected_printer(); for (auto& diameter : diameters) { diameter_combo->AppendString(wxString(diameter) + "mm"); } - if (diameter_combo->GetCount() == 0 && !diam_str.empty()) { - diameter_combo->AppendString(wxString(diam_str) + "mm"); + if (diameter_combo->GetCount() == 0) { + const auto *pv = wxGetApp().preset_bundle->printers.get_edited_preset().config.option("printer_variant"); + if (pv) + diameter_combo->AppendString(wxString(pv->value) + "mm"); } if (diameters.size() < 2) { diameter_combo->Enable(false); } diameter_combo->Bind(wxEVT_COMBOBOX, [this, diameter_combo, i](wxCommandEvent& event) { + // ORCA multi-nozzle-size: set ONLY this nozzle's diameter, mirroring the + // Printer Settings -> Extruder tab. Previously this switched the whole printer preset + // to a single-diameter variant (forcing all nozzles to the same size); that defeats + // per-nozzle sizes, which the slicer now supports. + + // Parse the selected diameter from the "0.4mm" combo item. + const wxString sel_num = nozzle_combo_number(diameter_combo->GetValue()); + double new_nd = 0.; + if (!sel_num.ToCDouble(&new_nd) || new_nd <= 0.) + return; - //auto* pNotice = p->plater->get_notification_manager(); - //if (pNotice) - //{ - // pNotice->close_notification_of_type(NotificationType::CustomNotification); - // pNotice->push_notification(_u8L("Note: Printing PLA Silk on the hot end of 0.6mm hardened steel is not recommended. 0.4mm or smaller specifications are suggested."), 0); - // pNotice->set_slicing_progress_hidden(); - //} - - auto printer_config = wxGetApp().preset_bundle->printers.get_edited_preset().config; - auto printer_model_opt = printer_config.option("printer_model"); - if (printer_model_opt) { - std::string printer_model = printer_model_opt->value; - bool is_snapmaker_u1 = boost::icontains(printer_model, "Snapmaker") && boost::icontains(printer_model, "U1"); - - if (is_snapmaker_u1) - { - //check the config has flags to tips switch nozzle and all nozzle will be changed to the same type - auto notShow = wxGetApp().app_config->get("app", "sync_diameter_flags"); - if (notShow != "true") - { - RichMessageDialog dlg(static_cast(wxGetApp().mainframe), - _L("Note: Changing this will sync all other nozzles to the same diameter."), - _L("Set Nozzle Diameter"), - wxOK); - dlg.ShowCheckBox(_L("Don't show this again"), false); - auto res = dlg.ShowModal(); - bool isCheckBox = dlg.IsCheckBoxChecked(); - - if (wxID_OK == res) - wxGetApp().app_config->set("app", "sync_diameter_flags", isCheckBox); - } - } - } - - auto diameter = diameter_combo->GetValue().substr(0, 3); - auto preset = wxGetApp().preset_bundle->get_similar_printer_preset({}, diameter.ToStdString()); - if (preset == nullptr) { - BOOST_LOG_TRIVIAL(error) << "get the similar printer preset fail"; + Tab* printer_tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); + if (printer_tab == nullptr) return; - } - preset->is_visible = true; // force visible - for (size_t i = 0; i < p->m_nozzle_diameter_lists.size(); ++i) { - //set all nozzle use the diameter - p->m_nozzle_diameter_lists[i]->SetValue(diameter + "mm"); + // Write nozzle_diameter[i] into the edited printer config, like Tab.cpp's extruder page. + DynamicPrintConfig new_conf = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const auto* nozzle_diam_opt = static_cast(new_conf.option("nozzle_diameter")); + if (nozzle_diam_opt == nullptr || i >= nozzle_diam_opt->values.size()) + return; + std::vector nozzle_diameters = nozzle_diam_opt->values; + if (std::abs(nozzle_diameters[i] - new_nd) < EPSILON) + return; // unchanged + nozzle_diameters[i] = new_nd; + new_conf.set_key_value("nozzle_diameter", new ConfigOptionFloats(nozzle_diameters)); + + // ORCA multi-nozzle-size: a different nozzle size usually means different layer + // height limits. Adopt them from the printer's profile for the new nozzle size when + // one exists, otherwise ask the user to review the limits manually. + std::string notice; + bool variant_found = false; + { + const PrinterPresetCollection &printers = wxGetApp().preset_bundle->printers; + const std::string model = new_conf.opt_string("printer_model"); + const std::string variant = sel_num.ToStdString(); + const Preset *variant_preset = printers.find_system_preset_by_model_and_variant(model, variant); + if (variant_preset == nullptr) + variant_preset = printers.find_custom_preset_by_model_and_variant(model, variant); + const auto *v_min = variant_preset == nullptr ? nullptr : variant_preset->config.option("min_layer_height"); + const auto *v_max = variant_preset == nullptr ? nullptr : variant_preset->config.option("max_layer_height"); + const auto *e_min = static_cast(new_conf.option("min_layer_height")); + const auto *e_max = static_cast(new_conf.option("max_layer_height")); + if (v_min != nullptr && !v_min->values.empty() && v_max != nullptr && !v_max->values.empty() && + e_min != nullptr && e_max != nullptr) { + variant_found = true; + std::vector mins = e_min->values, maxs = e_max->values; + mins.resize(nozzle_diameters.size(), mins.empty() ? 0. : mins.back()); + maxs.resize(nozzle_diameters.size(), maxs.empty() ? 0. : maxs.back()); + mins[i] = v_min->get_at(i); + maxs[i] = v_max->get_at(i); + new_conf.set_key_value("min_layer_height", new ConfigOptionFloats(mins)); + new_conf.set_key_value("max_layer_height", new ConfigOptionFloats(maxs)); + notice = GUI::format(_u8L("Nozzle %1%: layer height limits set to %2%-%3% mm, from \"%4%\"."), + i + 1, mins[i], maxs[i], variant_preset->name); + } else { + notice = GUI::format(_u8L("This printer has no profile for a %1% mm nozzle. Please review the " + "layer height limits of nozzle %2% in the printer settings."), + variant, i + 1); + } } - - wxGetApp().get_tab(Preset::TYPE_PRINTER)->select_preset(preset->name); - // Do not event.Skip(): select_preset rebuilds nozzle UI and can destroy this combo; skipping would let sidebar treat this as bed-type combo and use-after-free. + // A preferred layer height that no longer fits through the new nozzle cannot print; + // reset it to Default rather than leave a dead setting behind. + if (const auto *height_opt = static_cast(new_conf.option("extruder_layer_height")); + height_opt != nullptr && !height_opt->values.empty() && height_opt->get_at(i) > new_nd + EPSILON) { + std::vector heights = height_opt->values; + heights.resize(nozzle_diameters.size(), 0.); + heights[i] = 0.; + new_conf.set_key_value("extruder_layer_height", new ConfigOptionFloats(heights)); + notice += "\n"; + notice += GUI::format(_u8L("The preferred layer height of nozzle %1% no longer fits through it and was reset to Default."), i + 1); + } + + // load_config marks the printer preset modified and propagates the change without + // rebuilding these combos or switching presets, so the other nozzles keep their sizes. + printer_tab->load_config(new_conf); + + wxGetApp().plater()->get_notification_manager()->push_notification( + NotificationType::CustomNotification, + variant_found ? NotificationManager::NotificationLevel::RegularNotificationLevel : + NotificationManager::NotificationLevel::WarningNotificationLevel, + notice); + // The valid preferred layer heights of this nozzle follow its bore and limits. + if (i < p->m_nozzle_layer_height_lists.size() && p->m_nozzle_layer_height_lists[i] != nullptr) + fill_nozzle_layer_height_combo(p->m_nozzle_layer_height_lists[i], i); + // Do not event.Skip(): this is a plain ComboBox; skipping would let the sidebar treat + // it as the bed-type combo (Plater::priv::on_combobox_select) and mishandle it. }); - diameter_combo->SetValue(diam_str.empty() ? wxString() : wxString(diam_str) + "mm"); + const double this_nd = (nozzle_diameter && i < nozzle_diameter->values.size()) ? nozzle_diameter->values[i] : 0.; + select_nozzle_diameter_label(diameter_combo, this_nd); p->m_nozzle_diameter_lists.push_back(diameter_combo); @@ -11060,9 +11239,72 @@ void Sidebar::update_nozzle_settings(bool switch_machine) diameter_sizer->AddSpacer(10); diameter_sizer->Add(diameter_combo, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(15)); + // Preferred layer height row: which multiple of the object layer height this extruder + // should print with (the "extruder_layer_height" printer option). + wxBoxSizer* lh_sizer = new wxBoxSizer(wxHORIZONTAL); + wxStaticText* lh_label = new wxStaticText(nozzle_panel, wxID_ANY, _L("Preferred layer height")); + lh_label->SetForegroundColour(is_dark ? wxColor(194, 194, 194) : wxColor(0, 0, 0)); + lh_label->SetFont(Label::Body_14); + + ComboBox* lh_combo = new ComboBox(nozzle_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, {-1, FromDIP(32)}, 0, + nullptr, wxCB_READONLY); + lh_combo->SetToolTip(_L("Layer height this extruder should print with: a multiple of the object layer " + "height within this extruder's layer height limits. Default keeps the object layer " + "height. Selecting a fraction of the object layer height lowers the object layer " + "height to it and keeps the other extruders at their current effective height.")); + fill_nozzle_layer_height_combo(lh_combo, i); + + lh_combo->Bind(wxEVT_COMBOBOX, [lh_combo, i](wxCommandEvent& event) { + // "Default" (or anything non-numeric) clears the preference: 0 = object layer height. + double new_height = 0.; + if (!nozzle_combo_number(lh_combo->GetValue()).ToCDouble(&new_height) || new_height < 0.) + new_height = 0.; + + Tab* printer_tab = wxGetApp().get_tab(Preset::TYPE_PRINTER); + if (printer_tab == nullptr) + return; + DynamicPrintConfig new_conf = wxGetApp().preset_bundle->printers.get_edited_preset().config; + const auto* height_opt = static_cast(new_conf.option("extruder_layer_height")); + const auto* nd_opt = static_cast(new_conf.option("nozzle_diameter")); + if (height_opt == nullptr || nd_opt == nullptr) + return; + std::vector heights = height_opt->values; + heights.resize(nd_opt->values.size(), 0.); + if (i >= heights.size() || std::abs(heights[i] - new_height) < EPSILON) + return; + heights[i] = new_height; + const auto* base_opt = wxGetApp().preset_bundle->prints.get_edited_preset().config.option("layer_height"); + const double base_height = base_opt != nullptr ? base_opt->value : 0.; + if (new_height > EPSILON && base_height > EPSILON && new_height < base_height - EPSILON) { + // A preference below the object layer height: the engine slices the object on + // the finest preferred height, so lower the object layer height to it and pin + // every extruder that followed the old value - the printed result is identical + // and the configuration stays valid. + for (size_t j = 0; j < heights.size(); ++j) + if (j != i && heights[j] <= EPSILON) + heights[j] = base_height; + if (Tab* print_tab = wxGetApp().get_tab(Preset::TYPE_PRINT); print_tab != nullptr) { + DynamicPrintConfig print_conf = wxGetApp().preset_bundle->prints.get_edited_preset().config; + print_conf.set_key_value("layer_height", new ConfigOptionFloat(new_height)); + print_tab->load_config(print_conf); + } + } + new_conf.set_key_value("extruder_layer_height", new ConfigOptionFloats(heights)); + // As with the diameter combo: marks the printer preset modified and propagates the + // change without switching presets. Do not event.Skip() (plain ComboBox, see above). + printer_tab->load_config(new_conf); + }); + p->m_nozzle_layer_height_lists.push_back(lh_combo); + + lh_sizer->AddSpacer(15); + lh_sizer->Add(lh_label, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(5)); + lh_sizer->AddSpacer(10); + lh_sizer->Add(lh_combo, 1, wxALIGN_CENTER_VERTICAL | wxRIGHT, FromDIP(15)); + // 删除Flow相关控件 - tab_sizer->Add(diameter_sizer, 1, wxEXPAND | wxALIGN_CENTER_VERTICAL); + tab_sizer->Add(diameter_sizer, 0, wxEXPAND | wxTOP, FromDIP(6)); + tab_sizer->Add(lh_sizer, 0, wxEXPAND | wxTOP | wxBOTTOM, FromDIP(6)); nozzle_panel->SetSizer(tab_sizer); @@ -11093,6 +11335,9 @@ void Sidebar::update_nozzle_settings(bool switch_machine) p->m_nozzle_notebook->AddPage(nozzle_panel, tab_name); } + if (prev_page > 0 && prev_page < (int) p->m_nozzle_notebook->GetPageCount()) + p->m_nozzle_notebook->SetSelection(size_t(prev_page)); + p->m_nozzle_notebook->Layout(); if (switch_machine) { @@ -11103,6 +11348,40 @@ void Sidebar::update_nozzle_settings(bool switch_machine) } } +// ORCA multi-nozzle-size: refresh the values shown by the nozzle tabs in place, without +// rebuilding them (no focus or tab-selection changes). Called whenever the printer's nozzle +// sizes, layer height limits or preferred layer heights change, or the object layer height +// changes (it defines which preferred layer heights are valid). A change of the extruder +// count escalates to a deferred full rebuild of the tabs. +void Sidebar::update_nozzle_values() +{ + if (p->m_nozzle_notebook == nullptr) + return; + + const auto *nozzle_diameter = dynamic_cast( + wxGetApp().preset_bundle->printers.get_edited_preset().config.option("nozzle_diameter")); + const size_t nozzle_count = nozzle_diameter != nullptr ? nozzle_diameter->values.size() : 1; + if (nozzle_count != p->m_nozzle_notebook->GetPageCount()) { + // Defer the rebuild: this can be reached from an event handler of a control that lives + // on one of the pages about to be destroyed. + if (!p->m_nozzle_rebuild_scheduled) { + p->m_nozzle_rebuild_scheduled = true; + wxGetApp().CallAfter([this]() { + p->m_nozzle_rebuild_scheduled = false; + update_nozzle_settings(); + }); + } + return; + } + if (nozzle_diameter != nullptr) + for (size_t i = 0; i < p->m_nozzle_diameter_lists.size() && i < nozzle_diameter->values.size(); ++i) + if (p->m_nozzle_diameter_lists[i] != nullptr) + select_nozzle_diameter_label(p->m_nozzle_diameter_lists[i], nozzle_diameter->values[i]); + for (size_t i = 0; i < p->m_nozzle_layer_height_lists.size(); ++i) + if (p->m_nozzle_layer_height_lists[i] != nullptr) + fill_nozzle_layer_height_combo(p->m_nozzle_layer_height_lists[i], i); +} + ObjectList* Sidebar::obj_list() { // BBS @@ -13396,9 +13675,9 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame) "enable_prime_tower", "wipe_tower_x", "wipe_tower_y", "prime_tower_width", "prime_tower_brim_width", "prime_volume", "extruder_colour", "filament_colour", "filament_is_support", "material_colour", "printable_height", "printer_model", "printer_technology", // These values are necessary to construct SlicingParameters by the Canvas3D variable layer height editor. - "layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height", + "layer_height", "initial_layer_print_height", "min_layer_height", "max_layer_height", "extruder_layer_height", "brim_width", "wall_loops", "outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_density", "sparse_infill_filament_id", - "top_shell_layers", + "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", "top_shell_layers", "enable_support", "support_filament", "support_interface_filament", "support_top_z_distance", "support_bottom_z_distance", "raft_layers", "wipe_tower_rotation_angle", "wipe_tower_cone_angle", "wipe_tower_extra_spacing", "wipe_tower_extra_flow", "local_z_wipe_tower_purge_lines", "wipe_tower_max_purge_speed", @@ -14927,6 +15206,26 @@ std::vector Plater::priv::load_files(const std::vector& input_ if (wipe_tower_y_opt) file_wipe_tower_y = *wipe_tower_y_opt; + // ORCA: a project carrying an explicit legacy support filament + // selection reveals the legacy selectors in the Support page. + { + auto assigned = [](const DynamicPrintConfig &c) { + const auto *base = c.option("support_filament"); + const auto *intf = c.option("support_interface_filament"); + return (base != nullptr && base->value > 0) || (intf != nullptr && intf->value > 0); + }; + bool legacy_assigned = assigned(config); + for (const ModelObject *object : model.objects) { + legacy_assigned |= assigned(object->config.get()); + for (const ModelVolume *volume : object->volumes) + legacy_assigned |= assigned(volume->config.get()); + for (const auto &range : object->layer_config_ranges) + legacy_assigned |= assigned(range.second.get()); + } + if (legacy_assigned) + wxGetApp().app_config->set_bool("show_legacy_support_filament", true); + } + preset_bundle->load_config_model(filename.string(), std::move(config), file_version); ConfigOption* bed_type_opt = preset_bundle->project_config.option("curr_bed_type"); @@ -26287,7 +26586,9 @@ void Plater::on_filaments_delete(size_t num_filaments, size_t filament_id, int r // update global feature filament selections static const char* keys[] = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id", - "support_filament", "support_interface_filament"}; + "support_filament", "support_interface_filament", + // 0 = "auto" for the wipe tower, the same deleted -> 0 / shift-down rule applies. + "wipe_tower_filament"}; for (auto key : keys) if (p->config->has(key)) { if (p->config->opt_int(key) == filament_id + 1) @@ -26297,6 +26598,29 @@ void Plater::on_filaments_delete(size_t num_filaments, size_t filament_id, int r (*(p->config)).set_key_value(key, new ConfigOptionInt(new_value)); } } + // The slicer reads these selections from the edited print preset (preset_bundle->full_config()), + // not from the plater's cached config above - remap it too, or a deleted filament's id silently + // shifts onto the wrong physical filament. + { + DynamicPrintConfig &print_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + bool print_config_changed = false; + for (auto key : keys) + if (print_config.has(key)) { + const int value = print_config.opt_int(key); + if (value == filament_id + 1) { + // Back to "Default" (0): use the part's filament. + print_config.set_key_value(key, new ConfigOptionInt(0)); + print_config_changed = true; + } else if (value > filament_id + 1) { + print_config.set_key_value(key, new ConfigOptionInt(value - 1)); + print_config_changed = true; + } + } + if (print_config_changed) { + wxGetApp().get_tab(Preset::TYPE_PRINT)->update_dirty(); + wxGetApp().get_tab(Preset::TYPE_PRINT)->reload_config(); + } + } // update UI — runs after remap so update_mixed_filament_list() won't clip remapped extruder IDs sidebar().on_filaments_delete(filament_id); @@ -26541,7 +26865,19 @@ bool Plater::check_filament_temp_mixing(int plate_index, FilamentTempMixingDetai const int num_filaments = static_cast(filament_type_option->values.size()); collect_filament_slots_from_config(*plate->config(), num_filaments, used_slots_0_based); - // ModelObject config + // Collect from ModelObject/ModelVolume configs and painting extruders for + // objects on the current plate. Also track whether any object relies on the + // global default extruder (extruder=0) so we can resolve it at the end, and + // per feature selector whether any part still follows the global value. + static const std::vector selector_keys = { + "outer_wall_filament_id", + "inner_wall_filament_id", + "sparse_infill_filament_id", + "internal_solid_filament_id", + "top_surface_filament_id", + "bottom_surface_filament_id" + }; + std::vector selector_overridden_everywhere(selector_keys.size(), true); bool uses_default_extruder = false; for (size_t obj_idx = 0; obj_idx < wxGetApp().model().objects.size(); ++obj_idx) { @@ -26563,36 +26899,49 @@ bool Plater::check_filament_temp_mixing(int plate_index, FilamentTempMixingDetai used_slots_0_based.insert(extruder_id - 1); } } + + // A global selector reaches this object's regions unless the object (or each of its + // printed parts) explicitly overrides the same key. + for (size_t k = 0; k < selector_keys.size(); ++k) + { + if (!selector_overridden_everywhere[k] || model_object->config.has(selector_keys[k])) + continue; + bool all_parts_override = true; + for (const ModelVolume* model_volume : model_object->volumes) + if (model_volume->is_model_part() && !model_volume->config.has(selector_keys[k])) + { + all_parts_override = false; + break; + } + if (!all_parts_override) + selector_overridden_everywhere[k] = false; + } } - // Collect from the Plater working config. The approach balances - // sensitivity against false positives: - // - Global features (wipe tower, support) always apply → always collected. - // - Feature-specific keys (wall_filament, infill) depend on the global - // process defaults. They are only collected when at least one object - // on the plate uses the default extruder (e=0), which means those - // defaults WILL affect the actual slicing output. + // Collect from the Plater working config. Global features (wipe tower, support) + // always apply. An explicit (non-zero) global feature selector is the region + // default regardless of the part's own extruder, so it is collected whenever at + // least one part on the plate does not override the same key per object/volume + // (per-object overrides were already collected from the model configs above). { - // Always collect: features that cannot be overridden per-object. - static const std::vector always_collect = {"wipe_tower_filament", "support_filament", "support_interface_filament"}; + static const std::vector always_collect = { + "wipe_tower_filament", + "support_filament", + "support_interface_filament" + }; for (const char* key : always_collect) { const ConfigOptionInt* option = this->config()->option(key); if (option != nullptr && option->value >= 1 && option->value <= num_filaments) used_slots_0_based.insert(option->value - 1); } - - // If any object uses e=0, the global process defaults for - // wall / infill extruders apply and must be collected. - if (uses_default_extruder) + for (size_t k = 0; k < selector_keys.size(); ++k) { - static const std::vector default_keys = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id"}; - for (const char* key : default_keys) - { - const ConfigOptionInt* option = config()->option(key); - if (option != nullptr && option->value >= 1 && option->value <= num_filaments) - used_slots_0_based.insert(option->value - 1); - } + if (selector_overridden_everywhere[k]) + continue; + const ConfigOptionInt* option = this->config()->option(selector_keys[k]); + if (option != nullptr && option->value >= 1 && option->value <= num_filaments) + used_slots_0_based.insert(option->value - 1); } } @@ -26863,6 +27212,15 @@ bool Plater::check_flow_ratio_zero(int plate_index, FlowRatioZeroDetail& detail) const int num_filaments = static_cast(filament_type_option->values.size()); collect_filament_slots_from_config(*plate->config(), num_filaments, used_slots_0_based); + static const std::vector selector_keys = { + "outer_wall_filament_id", + "inner_wall_filament_id", + "sparse_infill_filament_id", + "internal_solid_filament_id", + "top_surface_filament_id", + "bottom_surface_filament_id" + }; + std::vector selector_overridden_everywhere(selector_keys.size(), true); bool uses_default_extruder = false; for (size_t obj_idx = 0; obj_idx < wxGetApp().model().objects.size(); ++obj_idx) { const ModelObject* model_object = wxGetApp().model().objects[obj_idx]; @@ -26880,6 +27238,21 @@ bool Plater::check_flow_ratio_zero(int plate_index, FlowRatioZeroDetail& detail) used_slots_0_based.insert(extruder_id - 1); } } + + // A global selector reaches this object's regions unless the object (or each of its + // printed parts) explicitly overrides the same key. + for (size_t k = 0; k < selector_keys.size(); ++k) { + if (!selector_overridden_everywhere[k] || model_object->config.has(selector_keys[k])) + continue; + bool all_parts_override = true; + for (const ModelVolume* model_volume : model_object->volumes) + if (model_volume->is_model_part() && !model_volume->config.has(selector_keys[k])) { + all_parts_override = false; + break; + } + if (!all_parts_override) + selector_overridden_everywhere[k] = false; + } } { @@ -26890,13 +27263,12 @@ bool Plater::check_flow_ratio_zero(int plate_index, FlowRatioZeroDetail& detail) used_slots_0_based.insert(option->value - 1); } - if (uses_default_extruder) { - static const std::vector default_keys = {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id"}; - for (const char* key : default_keys) { - const ConfigOptionInt* option = config()->option(key); - if (option != nullptr && option->value >= 1 && option->value <= num_filaments) - used_slots_0_based.insert(option->value - 1); - } + for (size_t k = 0; k < selector_keys.size(); ++k) { + if (selector_overridden_everywhere[k]) + continue; + const ConfigOptionInt* option = config()->option(selector_keys[k]); + if (option != nullptr && option->value >= 1 && option->value <= num_filaments) + used_slots_0_based.insert(option->value - 1); } } @@ -27229,6 +27601,7 @@ void Plater::on_config_change(const DynamicPrintConfig &config) { bool update_scheduled = false; bool bed_shape_changed = false; + bool nozzle_tabs_changed = false; //bool print_sequence_changed = false; t_config_option_keys diff_keys = p->config->diff(config); for (auto opt_key : diff_keys) { @@ -27316,8 +27689,19 @@ void Plater::on_config_change(const DynamicPrintConfig &config) opt_key == "top_surface_filament_id" || opt_key == "bottom_surface_filament_id") { update_scheduled = true; } + // ORCA multi-nozzle-size: the sidebar nozzle tabs mirror the printer's extruder count, + // nozzle sizes, layer height limits and preferred layer heights, and the valid preferred + // heights follow the object layer height. update_nozzle_values() refreshes them in place + // (and defers a full tab rebuild when the extruder count changed). + else if (opt_key == "nozzle_diameter" || opt_key == "extruder_layer_height" || + opt_key == "layer_height" || opt_key == "min_layer_height" || opt_key == "max_layer_height") { + nozzle_tabs_changed = true; + } } + if (nozzle_tabs_changed && p->sidebar != nullptr) + p->sidebar->update_nozzle_values(); + if (bed_shape_changed) set_bed_shape(); diff --git a/src/slic3r/GUI/Plater.hpp b/src/slic3r/GUI/Plater.hpp index 6eb33297226..33a237c97b6 100644 --- a/src/slic3r/GUI/Plater.hpp +++ b/src/slic3r/GUI/Plater.hpp @@ -243,6 +243,8 @@ class Sidebar : public wxPanel void update_dynamic_filament_list(); void update_nozzle_settings(bool switch_machine = false); + // Refresh the nozzle tabs' combo values in place; rebuilds (deferred) on extruder count change. + void update_nozzle_values(); PlaterPresetComboBox * printer_combox(); ObjectList* obj_list(); diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp index f473f1b2e50..0bdb85bdf2b 100644 --- a/src/slic3r/GUI/Tab.cpp +++ b/src/slic3r/GUI/Tab.cpp @@ -1896,6 +1896,16 @@ void Tab::on_value_change(const std::string& opt_key, const boost::any& value) } } + // ORCA: support enabled by the user on a printer with differing nozzle sizes: ask which + // nozzle size prints the support and which materials serve as raft/base and interface. + // Only here, on a real edit - preset and project loading must not raise dialogs. + if (opt_key == "enable_support" && m_type == Preset::TYPE_PRINT && m_config->opt_bool("enable_support") && + ConfigManipulation::printer_has_mixed_nozzle_sizes()) { + DynamicPrintConfig new_conf = *m_config; + if (m_config_manipulation.show_support_filament_dialog(m_config, &new_conf) == wxID_OK) + m_config_manipulation.apply(m_config, &new_conf); + } + if (opt_key == "single_extruder_multi_material" || opt_key == "extruders_count" ) update_wiping_button_visibility(); @@ -2822,6 +2832,8 @@ void TabPrint::build() auto optgroup = page->new_optgroup(L("Layer height"), L"param_layer_height"); optgroup->append_single_option_line("layer_height","quality_settings_layer_height"); optgroup->append_single_option_line("initial_layer_print_height","quality_settings_layer_height"); + optgroup->append_single_option_line("extruder_layer_height_mode","quality_settings_layer_height"); + optgroup->append_single_option_line("extruder_layer_height_tolerance","quality_settings_layer_height"); optgroup->append_single_option_line("enable_mixed_color_sublayer"); optgroup = page->new_optgroup(L("Line width"), L"param_line_width"); @@ -3114,9 +3126,41 @@ void TabPrint::build() optgroup->append_single_option_line("raft_contact_distance", "support_settings_raft"); optgroup = page->new_optgroup(L("Filament for Supports"), L"param_support_filament"); + // ORCA: Snapmaker support material / nozzle selection. + optgroup->append_single_option_line("support_nozzle_diameter", "support_settings_filament"); + optgroup->append_single_option_line("support_base_material", "support_settings_filament"); + optgroup->append_single_option_line("support_interface_material", "support_settings_filament"); optgroup->append_single_option_line("support_filament", "support_settings_filament#base"); optgroup->append_single_option_line("support_interface_filament", "support_settings_filament#interface"); optgroup->append_single_option_line("support_interface_not_for_body", "support_settings_filament#avoid-interface-filament-for-base"); + // ORCA: the support material options own the base/interface choice; this toggle + // reveals the legacy selectors above for older projects. + auto legacy_support_toggle = [this](wxWindow* parent) { + auto *sizer = new wxBoxSizer(wxHORIZONTAL); + auto *check = m_legacy_support_check = new ::CheckBox(parent); + check->SetValue(wxGetApp().app_config->get_bool("show_legacy_support_filament")); + // Page controls are destroyed when another page activates; drop the cached pointer. + check->Bind(wxEVT_DESTROY, [this, check](wxWindowDestroyEvent &evt) { + if (m_legacy_support_check == check) + m_legacy_support_check = nullptr; + evt.Skip(); + }); + check->Bind(wxEVT_TOGGLEBUTTON, [this](wxCommandEvent &evt) { + wxGetApp().app_config->set_bool("show_legacy_support_filament", evt.IsChecked()); + update(); + if (m_active_page != nullptr) + m_active_page->update_visibility(m_mode, true); + m_page_view->GetParent()->Layout(); + evt.Skip(); + }); + sizer->Add(check, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 4); + sizer->Add(new wxStaticText(parent, wxID_ANY, _(L("Show legacy filament selection"))), 0, wxALIGN_CENTER_VERTICAL); + return sizer; + }; + Line legacy_support_line = Line{ "", "" }; + legacy_support_line.full_width = 1; + legacy_support_line.append_widget(legacy_support_toggle); + optgroup->append_line(legacy_support_line); optgroup = page->new_optgroup(L("Support ironing"), L"param_ironing"); optgroup->append_single_option_line("support_ironing", "support_settings_ironing"); @@ -3147,6 +3191,7 @@ void TabPrint::build() optgroup->append_single_option_line("bridge_no_support", "support_settings_advanced#dont-support-bridges"); optgroup->append_single_option_line("max_bridge_length", "support_settings_advanced"); optgroup->append_single_option_line("independent_support_layer_height", "support_settings_advanced#independent-support-layer-height"); + optgroup->append_single_option_line("support_layer_height_step"); optgroup = page->new_optgroup(L("Tree supports"), L"param_support_tree"); optgroup->append_single_option_line("tree_support_tip_diameter", "support_settings_tree#tip-diameter"); @@ -3192,6 +3237,10 @@ void TabPrint::build() optgroup = page->new_optgroup(L("Filament for Features"), L"param_filament_for_features"); optgroup->append_single_option_line("outer_wall_filament_id", "multimaterial_settings_filament_for_features#outer-walls"); optgroup->append_single_option_line("inner_wall_filament_id", "multimaterial_settings_filament_for_features#inner-walls"); + // ORCA: split wall layer heights. + optgroup->append_single_option_line("split_wall_adjust", "multimaterial_settings_filament_for_features#inner-walls"); + optgroup->append_single_option_line("split_wall_adjust_filament", "multimaterial_settings_filament_for_features#inner-walls"); + optgroup->append_single_option_line("split_wall_adjust_direction", "multimaterial_settings_filament_for_features#inner-walls"); optgroup->append_single_option_line("sparse_infill_filament_id", "multimaterial_settings_filament_for_features#sparse-infill"); optgroup->append_single_option_line("internal_solid_filament_id", "multimaterial_settings_filament_for_features#internal-solid-infill"); optgroup->append_single_option_line("top_surface_filament_id", "multimaterial_settings_filament_for_features#top-surface"); @@ -3374,6 +3423,9 @@ void TabPrint::toggle_options() } m_config_manipulation.toggle_print_fff_options(m_config, int(intptr_t(m_extruder_switch->GetClientData())), m_type < Preset::TYPE_COUNT); + // The visibility pass may have switched the legacy toggle on for a loaded selection. + if (m_legacy_support_check != nullptr) + m_legacy_support_check->SetValue(wxGetApp().app_config->get_bool("show_legacy_support_filament")); Field *field = m_active_page->get_field("support_style"); auto support_type = m_config->opt_enum("support_type"); @@ -3558,25 +3610,33 @@ static std::vector substruct(std::vector const& l, std return t; } -static DynamicPrintConfig resolved_model_config_for_tab(const DynamicPrintConfig& config) +static DynamicPrintConfig resolved_model_config_for_tab(const DynamicPrintConfig& config, const DynamicPrintConfig* parent_scope_config) { DynamicPrintConfig resolved(config); + // Mirror the slicing precedence (apply_to_print_region_config): explicit selectors of outer + // scopes - the process preset and, for the part/layer tabs, the parent object's own config - + // win over this scope's extruder; the extruder only fills selectors left on "Default" (0) by + // every outer scope. The gate reads the edited print preset directly: a parent TAB's m_config + // may carry values auto-filled from the parent object's extruder, which must NOT beat this + // scope's own extruder. No cross-propagation between the selectors either - the engine + // resolves each feature's "Default" independently. if (const auto* extruder_opt = config.option("extruder"); extruder_opt != nullptr && extruder_opt->value > 0) { const int extruder = extruder_opt->value; - if (!resolved.has("outer_wall_filament_id")) - resolved.set_key_value("outer_wall_filament_id", new ConfigOptionInt(extruder)); - if (!resolved.has("inner_wall_filament_id")) - resolved.set_key_value("inner_wall_filament_id", new ConfigOptionInt(extruder)); - if (!resolved.has("sparse_infill_filament_id")) - resolved.set_key_value("sparse_infill_filament_id", new ConfigOptionInt(extruder)); - if (!resolved.has("internal_solid_filament_id")) - resolved.set_key_value("internal_solid_filament_id", new ConfigOptionInt(extruder)); + const DynamicPrintConfig& preset_config = wxGetApp().preset_bundle->prints.get_edited_preset().config; + for (const char* key : {"outer_wall_filament_id", "inner_wall_filament_id", "sparse_infill_filament_id", + "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id"}) { + if (resolved.has(key)) + continue; + if (const auto* preset_opt = preset_config.option(key); preset_opt != nullptr && preset_opt->value > 0) + continue; + if (parent_scope_config != nullptr) + if (const auto* parent_opt = parent_scope_config->option(key); parent_opt != nullptr && parent_opt->value > 0) + continue; + resolved.set_key_value(key, new ConfigOptionInt(extruder)); + } } - if (!resolved.has("internal_solid_filament_id") && resolved.has("sparse_infill_filament_id")) - resolved.set_key_value("internal_solid_filament_id", new ConfigOptionInt(resolved.opt_int("sparse_infill_filament_id"))); - return resolved; } @@ -3668,8 +3728,15 @@ void TabPrintModel::update_model_config() } m_null_keys.clear(); if (!m_object_configs.empty()) { + // For the part/layer tabs, the parent object's own explicit selectors also beat this + // scope's extruder in the engine; the object tab holds that object's config while a + // part/layer is selected (GUI_ObjectSettings). + const DynamicPrintConfig *parent_object_config = nullptr; + if (auto *object_tab = dynamic_cast(wxGetApp().get_model_tab()); + object_tab != nullptr && object_tab != this && m_parent_tab == object_tab && object_tab->m_object_configs.size() == 1) + parent_object_config = &object_tab->m_object_configs.begin()->second->get(); DynamicPrintConfig const & global_config= *m_config; - const DynamicPrintConfig local_config = resolved_model_config_for_tab(m_object_configs.begin()->second->get()); + const DynamicPrintConfig local_config = resolved_model_config_for_tab(m_object_configs.begin()->second->get(), parent_object_config); DynamicPrintConfig diff_config; std::vector all_keys = variant_keys(local_config); // at least one has these keys std::vector local_diffs; // all diff keys to first config @@ -3679,7 +3746,7 @@ void TabPrintModel::update_model_config() // ORCA: the object/part/layer scope resolves its own explicit selectors first // (see resolved_model_config_for_tab); local_config is a resolved copy, so the // first entry simply diffs to nothing instead of being skipped by address. - const DynamicPrintConfig resolved_config = resolved_model_config_for_tab(config.second->get()); + const DynamicPrintConfig resolved_config = resolved_model_config_for_tab(config.second->get(), parent_object_config); all_keys = concat(all_keys, variant_keys(resolved_config)); auto diffs = deep_diff(resolved_config, global_config, false); global_diffs = concat(global_diffs, diffs); @@ -6102,6 +6169,8 @@ if (is_marlin_flavor) optgroup = page->new_optgroup(L("Layer height limits"), L"param_layer_height"); optgroup->append_single_option_line("min_layer_height", "printer_extruder_basic_information#extruder-layer-height-limits", extruder_idx); optgroup->append_single_option_line("max_layer_height", "printer_extruder_basic_information#extruder-layer-height-limits", extruder_idx); + // ORCA: per-extruder layer height. + optgroup->append_single_option_line("extruder_layer_height", "printer_extruder_basic_information#extruder-layer-height-limits", extruder_idx); optgroup = page->new_optgroup(L("Position"), L"param_position"); optgroup->append_single_option_line("extruder_offset", "printer_extruder_basic_information#extruder-offset-position", extruder_idx); diff --git a/src/slic3r/GUI/Tab.hpp b/src/slic3r/GUI/Tab.hpp index c6041ba1eaa..673c6462538 100644 --- a/src/slic3r/GUI/Tab.hpp +++ b/src/slic3r/GUI/Tab.hpp @@ -493,6 +493,7 @@ class TabPrint : public Tab private: ogStaticText* m_recommended_thin_wall_thickness_description_line = nullptr; ogStaticText* m_top_bottom_shell_thickness_explanation = nullptr; + ::CheckBox* m_legacy_support_check = nullptr; }; class TabPrintModel : public TabPrint diff --git a/tests/fff_print/CMakeLists.txt b/tests/fff_print/CMakeLists.txt index 465136e8b15..0459a313506 100644 --- a/tests/fff_print/CMakeLists.txt +++ b/tests/fff_print/CMakeLists.txt @@ -12,6 +12,7 @@ add_executable(${_TEST_NAME}_tests test_gcodewriter.cpp test_model.cpp test_multifilament.cpp + test_multi_nozzle_layer_height.cpp test_perimeters.cpp test_print.cpp test_printobject.cpp diff --git a/tests/fff_print/test_multi_nozzle_layer_height.cpp b/tests/fff_print/test_multi_nozzle_layer_height.cpp new file mode 100644 index 00000000000..47d494192f3 --- /dev/null +++ b/tests/fff_print/test_multi_nozzle_layer_height.cpp @@ -0,0 +1,1692 @@ +#include + +#include + +#include "libslic3r/libslic3r.h" +#include "libslic3r/Print.hpp" +#include "libslic3r/Layer.hpp" +#include "libslic3r/ExtrusionEntity.hpp" +#include "libslic3r/ExtrusionEntityCollection.hpp" +#include "libslic3r/Flow.hpp" +#include "libslic3r/Slicing.hpp" +#include "libslic3r/GCode/ToolOrdering.hpp" +#include + +#include "test_helpers.hpp" + +using namespace Slic3r; +using namespace Slic3r::Test; + +// Print::validate() now reports warnings through a vector out-param (upstream Orca API). +static std::string concat_warning_strings(const std::vector& warnings) +{ + std::string all; + for (const StringObjectException& w : warnings) + all += w.string + "\n"; + return all; +} +static bool warnings_have_opt_key(const std::vector& warnings, const std::string& key) +{ + for (const StringObjectException& w : warnings) + if (w.opt_key == key) + return true; + return false; +} + +// ORCA: tests for the per-extruder layer height feature ("extruder_layer_height"). + +template +static void for_each_path(const ExtrusionEntityCollection &collection, const PathFn &fn) +{ + for (const ExtrusionEntity *entity : collection.entities) { + if (auto *sub_collection = dynamic_cast(entity)) + for_each_path(*sub_collection, fn); + else if (auto *loop = dynamic_cast(entity)) { + for (const ExtrusionPath &path : loop->paths) + fn(path); + } else if (auto *multi_path = dynamic_cast(entity)) { + for (const ExtrusionPath &path : multi_path->paths) + fn(path); + } else if (auto *path = dynamic_cast(entity)) + fn(*path); + } +} + +static void collect_path_heights(const ExtrusionEntityCollection &collection, std::vector &heights) +{ + for_each_path(collection, [&heights](const ExtrusionPath &path) { + // Bridges print with the bridge flow whose height derives from the nozzle, + // not from the layer height; they are not this feature's concern. + if (path.role() != erBridgeInfill && path.role() != erInternalBridgeInfill) + heights.emplace_back(path.height); + }); +} + +static std::vector region_path_heights(const LayerRegion *layerm) +{ + std::vector heights; + collect_path_heights(layerm->perimeters, heights); + collect_path_heights(layerm->fills, heights); + return heights; +} + +static void collect_path_role_widths(const ExtrusionEntityCollection &collection, std::vector> &widths) +{ + for_each_path(collection, [&widths](const ExtrusionPath &path) { widths.emplace_back(path.role(), path.width); }); +} + +// Two extruders: a 0.4 mm nozzle printing with the 0.2 mm object layer height and a 0.6 mm nozzle +// with a configurable extruder layer height (0.4 => multiplier 2). +// On this fork's classic multi-tool printers a filament index is the extruder index, so no +// filament map configuration applies. +static DynamicPrintConfig two_extruder_config(double second_extruder_layer_height) +{ + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_key_value("layer_height", new ConfigOptionFloat(0.2)); + config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(0.4)); + config.set_key_value("enable_prime_tower", new ConfigOptionBool(false)); + config.set_key_value("enable_support", new ConfigOptionBool(false)); + + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({0.4, 0.6})); + config.set_key_value("extruder_layer_height", new ConfigOptionFloats({0., second_extruder_layer_height})); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.07, 0.07})); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.45})); + 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("filament_type", new ConfigOptionStrings({"PLA", "PLA"})); + config.set_key_value("default_filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00"})); + 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})); + // flush_volumes_matrix must be filament_count^2 entries. + config.set_key_value("flush_multiplier", new ConfigOptionFloats({1.})); + config.set_key_value("flush_volumes_matrix", new ConfigOptionFloats({0, 0, 0, 0})); + // Print::validate() reports motion-ability diagnostics by overwriting the single warning + // out-param; raise the machine limit so the default print accelerations do not clobber the + // layer height warnings under test. + config.set_key_value("machine_max_acceleration_extruding", new ConfigOptionFloats({100000., 100000.})); + // The default G-code flavor rejects relative extruder addressing without a G92 E0 layer-change + // reset; this suite does not exercise the G-code writer, keep validation quiet. + config.set_key_value("use_relative_e_distances", new ConfigOptionBool(false)); + // The scenarios build on consistent-mode expectations with a tight drift tolerance; the + // shipping defaults are fixed mode with a generous tolerance. + config.option>("extruder_layer_height_mode", true)->value = elhmConsistent; + config.set_key_value("extruder_layer_height_tolerance", new ConfigOptionPercent(10)); + return config; +} + +// One object made of two 20x20 mm parts side by side; the second part prints with filament 2. +// The parts are z-scaled by z_scale (cubes are 10 mm tall by default). +static void init_two_part_print(Print &print, Model &model, const DynamicPrintConfig &config, float z_scale = 0.5f, + TestMesh coarse_shape = TestMesh::cube_20x20x20) +{ + TriangleMesh fine_mesh = mesh(TestMesh::cube_20x20x20); + fine_mesh.scale(Vec3f(1.f, 1.f, z_scale)); + TriangleMesh coarse_mesh = mesh(coarse_shape); + coarse_mesh.scale(Vec3f(1.f, 1.f, z_scale)); + coarse_mesh.translate(30.f, 0.f, 0.f); + + ModelObject *object = model.add_object(); + object->name = "two_part_cube"; + object->add_volume(std::move(fine_mesh)); + ModelVolume *coarse_volume = object->add_volume(std::move(coarse_mesh)); + coarse_volume->config.set("extruder", 2); + object->add_instance(); + + // This fork's arrangement engine rejects positions outside the (unset) plate even for an + // InfiniteBed; the fixture geometry is already laid out, so place it at a fixed bed spot. + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); +} + +static void find_regions(const PrintObject &object, int &fine_region, int &coarse_region) +{ + fine_region = coarse_region = -1; + for (size_t i = 0; i < object.num_printing_regions(); ++ i) { + if (object.printing_region(i).config().outer_wall_filament_id.value == 2) + coarse_region = int(i); + else + fine_region = int(i); + } +} + +SCENARIO("Per-extruder layer height combines region layers", "[MultiNozzleLayerHeight]") { + GIVEN("A two-part object, the second part on a 0.6 mm nozzle with a 0.4 mm extruder layer height") { + DynamicPrintConfig config = two_extruder_config(0.4); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the configuration passes validation and slices as expected") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + REQUIRE(coarse_region >= 0); + // 0.4 mm first layer + 48 layers of 0.2 mm = 10 mm object height. + REQUIRE(object.layer_count() == 49); + + // The coarse region extrudes on the first layer and then only on every 2nd layer, + // always with 0.4 mm high paths; the layers in between print nothing for it. + size_t coarse_layers = 0, coarse_bad_heights = 0, coarse_unexpected = 0, coarse_missing = 0; + // The fine region extrudes on every layer with the base layer heights. + size_t fine_bad_heights = 0, fine_missing = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const Layer *layer = object.get_layer(int(idx)); + const std::vector coarse_heights = region_path_heights(layer->get_region(coarse_region)); + if (idx % 2 == 0) { + if (coarse_heights.empty()) + ++ coarse_missing; + else + ++ coarse_layers; + for (float height : coarse_heights) + if (std::abs(height - 0.4) > 1e-3) + ++ coarse_bad_heights; + } else if (! coarse_heights.empty()) + ++ coarse_unexpected; + + const std::vector fine_heights = region_path_heights(layer->get_region(fine_region)); + if (fine_heights.empty()) + ++ fine_missing; + const double fine_expected = idx == 0 ? 0.4 : 0.2; + for (float height : fine_heights) + if (std::abs(height - fine_expected) > 1e-3) + ++ fine_bad_heights; + } + CHECK(coarse_missing == 0); + CHECK(coarse_unexpected == 0); + CHECK(coarse_bad_heights == 0); + CHECK(coarse_layers == 25); // layer 0 + the 24 group tops + CHECK(fine_missing == 0); + CHECK(fine_bad_heights == 0); + } + } + + GIVEN("The same object with extruder_layer_height disabled") { + DynamicPrintConfig config = two_extruder_config(0.); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("both regions print on every layer with the base layer heights") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + REQUIRE(coarse_region >= 0); + + size_t missing = 0, bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const Layer *layer = object.get_layer(int(idx)); + const double expected = idx == 0 ? 0.4 : 0.2; + for (int region_id : { fine_region, coarse_region }) { + const std::vector heights = region_path_heights(layer->get_region(region_id)); + if (heights.empty()) + ++ missing; + for (float height : heights) + if (std::abs(height - expected) > 1e-3) + ++ bad_heights; + } + } + CHECK(missing == 0); + CHECK(bad_heights == 0); + } + } +} + +SCENARIO("Fixed mode always prints the extruder layer height", "[MultiNozzleLayerHeight]") { + // A 10 mm tall pyramid on the coarse extruder: its outline drifts by 0.2 mm per edge on every + // 0.2 mm layer, far past the suite's 10 % thick layer tolerance (of the 0.6 mm nozzle), so + // consistent mode falls back to the object layer height everywhere. + GIVEN("A pyramid part whose outline drifts past the thick layer tolerance on every layer") { + DynamicPrintConfig config = two_extruder_config(0.4); + // Count coarse extrusion heights well below the apex, where slices stay large enough to print. + auto coarse_height_counts = [](Print &print, size_t &at_pitch, size_t &at_base, size_t &odd_layers) { + print.process(); + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(coarse_region >= 0); + at_pitch = at_base = odd_layers = 0; + for (size_t idx = 1; idx <= 40; ++ idx) { + const std::vector heights = region_path_heights(object.get_layer(int(idx))->get_region(coarse_region)); + if (idx % 2 == 1 && ! heights.empty()) + ++ odd_layers; + for (float height : heights) { + if (std::abs(height - 0.4) < 1e-3) + ++ at_pitch; + else if (std::abs(height - 0.2) < 1e-3) + ++ at_base; + } + } + }; + WHEN("thick layer regions are Consistent") { + Print print; + Model model; + init_two_part_print(print, model, config, 0.25f, TestMesh::pyramid); + THEN("the drift keeps the coarse part at the object layer height") { + REQUIRE(print.validate().string.empty()); + size_t at_pitch, at_base, odd_layers; + coarse_height_counts(print, at_pitch, at_base, odd_layers); + CHECK(at_pitch == 0); + CHECK(at_base > 0); + CHECK(odd_layers == 20); + } + } + WHEN("thick layer regions are Fixed") { + config.option>("extruder_layer_height_mode", true)->value = elhmFixed; + Print print; + Model model; + init_two_part_print(print, model, config, 0.25f, TestMesh::pyramid); + THEN("every coarse extrusion above the first layer keeps the extruder layer height") { + REQUIRE(print.validate().string.empty()); + size_t at_pitch, at_base, odd_layers; + coarse_height_counts(print, at_pitch, at_base, odd_layers); + CHECK(at_pitch > 0); + CHECK(at_base == 0); + CHECK(odd_layers == 0); + } + } + } +} + +SCENARIO("Fixed mode keeps top surfaces on combined steps", "[MultiNozzleLayerHeight]") { + // A shoulder that ends mid-run: the wide cube's exposed ring is combined away with its layer + // (the run prints only the common shape), so it must reappear as a top surface on the printed + // layer below it - otherwise the step carries bare sparse infill. + GIVEN("A wide cube ending mid-run with a narrower cube on top") { + auto top_area = [](ExtruderLayerHeightMode mode) { + DynamicPrintConfig config = two_extruder_config(0.4); + config.option>("extruder_layer_height_mode", true)->value = mode; + Print print; + Model model; + TriangleMesh base = mesh(TestMesh::cube_20x20x20); + base.scale(Vec3f(1.f, 1.f, 0.25f)); // 5 mm tall: the shoulder ends mid-run + TriangleMesh boss = mesh(TestMesh::cube_20x20x20); + boss.scale(Vec3f(0.5f, 0.5f, 0.1f)); // 10 x 10 x 2 mm on top + boss.translate(5.f, 5.f, 5.f); + ModelObject *object = model.add_object(); + object->name = "stepped_cube"; + object->add_volume(std::move(base)); + object->add_volume(std::move(boss)); + object->config.set("extruder", 2); + object->add_instance(); + // This fork's arrangement engine rejects positions outside the (unset) plate even for + // an InfiniteBed; place the object at a fixed bed spot like init_two_part_print(). + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); + REQUIRE(print.validate().string.empty()); + print.process(); + const PrintObject &po = *print.objects().front(); + double area = 0.; + for (size_t idx = 0; idx < po.layer_count(); ++ idx) + for (int r = 0; r < po.get_layer(int(idx))->region_count(); ++ r) + for (const Surface &surface : po.get_layer(int(idx))->get_region(r)->fill_surfaces.surfaces) + if (surface.surface_type == stTop) + area += unscale(unscale(surface.expolygon.area())); + return area; + }; + THEN("the combined print keeps most of the per-layer top surface area") { + const double per_layer = top_area(elhmConsistent); + const double combined = top_area(elhmFixed); + CAPTURE(per_layer, combined); + REQUIRE(per_layer > 100.); + REQUIRE(combined > 0.7 * per_layer); + } + } +} + +SCENARIO("Fixed mode bridges lids that start inside a run", "[MultiNozzleLayerHeight]") { + // The runs spanning the lid's first layers print nothing there; it must still bridge. + GIVEN("A hollow tube capped by a lid whose bottom starts in the middle of a run") { + DynamicPrintConfig config = two_extruder_config(0.4); + config.option>("extruder_layer_height_mode", true)->value = elhmFixed; + Print print; + Model model; + TriangleMesh tube = mesh(TestMesh::cube_with_hole); // 20 x 20 x 10 mm, 10 mm hole through z + tube.scale(Vec3f(1.f, 1.f, 0.5f)); // 5 mm tall: the lid starts mid-run + TriangleMesh lid = mesh(TestMesh::cube_20x20x20); + lid.scale(Vec3f(1.f, 1.f, 0.1f)); + lid.translate(0.f, 0.f, 5.f); + ModelObject *object = model.add_object(); + object->name = "capped_tube"; + object->add_volume(std::move(tube)); + object->add_volume(std::move(lid)); + object->config.set("extruder", 2); + object->add_instance(); + // This fork's arrangement engine rejects positions outside the (unset) plate even for + // an InfiniteBed; place the object at a fixed bed spot like init_two_part_print(). + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); + THEN("the lid interior is classified as an unsupported bottom") { + REQUIRE(print.validate().string.empty()); + print.process(); + const PrintObject &po = *print.objects().front(); + double bridge_area = 0.; + for (size_t idx = 0; idx < po.layer_count(); ++ idx) + for (int r = 0; r < po.get_layer(int(idx))->region_count(); ++ r) + for (const Surface &surface : po.get_layer(int(idx))->get_region(r)->fill_surfaces.surfaces) + if (surface.surface_type == stBottomBridge) + bridge_area += unscale(unscale(surface.expolygon.area())); + CAPTURE(bridge_area); + REQUIRE(bridge_area > 40.); + } + } +} + +SCENARIO("A bottom over another region's combined-away geometry bridges", "[MultiNozzleLayerHeight]") { + // At a filament boundary the support below a region's bottom can belong to a neighboring + // region whose run commits only its common shape: that support never prints even though the + // object's slices still cover the area, so the bottom must classify as an unsupported bridge. + GIVEN("A coarse slab whose top layer is a pocket rim holding a fine-filament insert") { + DynamicPrintConfig config = two_extruder_config(0.4); + config.option>("extruder_layer_height_mode", true)->value = elhmFixed; + Print print; + Model model; + // One coarse volume: a full slab plus a one-layer pocket rim on top. The run pairing the + // slab's top layer with the rim commits only the rim and drops the pocket footprint. + TriangleMesh slab = mesh(TestMesh::cube_20x20x20); + slab.scale(Vec3f(1.f, 1.f, 0.07f)); // 20 x 20 x 1.4 mm + TriangleMesh rim = mesh(TestMesh::cube_with_hole); // 20 x 20, 10 mm hole + rim.scale(Vec3f(1.f, 1.f, 0.02f)); // one 0.2 mm layer + rim.translate(0.f, 0.f, 1.4f); + slab.merge(rim); + TriangleMesh insert = mesh(TestMesh::cube_20x20x20); + insert.scale(Vec3f(0.4f, 0.4f, 0.04f)); // 8 x 8 x 0.8 mm in the pocket + insert.translate(6.f, 6.f, 1.4f); + ModelObject *object = model.add_object(); + object->name = "pocketed_slab"; + ModelVolume *coarse_volume = object->add_volume(std::move(slab)); + coarse_volume->config.set("extruder", 2); + object->add_volume(std::move(insert)); + object->add_instance(); + // This fork's arrangement engine rejects positions outside the (unset) plate even for + // an InfiniteBed; place the object at a fixed bed spot like init_two_part_print(). + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); + THEN("the insert's first layer is classified as an unsupported bottom") { + REQUIRE(print.validate().string.empty()); + print.process(); + const PrintObject &po = *print.objects().front(); + int fine_region = -1, coarse_region = -1; + find_regions(po, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + double bridge_area = 0.; + for (size_t idx = 0; idx < po.layer_count(); ++ idx) + if (const Layer *layer = po.get_layer(int(idx)); fine_region < layer->region_count()) + for (const Surface &surface : layer->get_region(fine_region)->fill_surfaces.surfaces) + if (surface.surface_type == stBottomBridge) + bridge_area += unscale(unscale(surface.expolygon.area())); + CAPTURE(bridge_area); + REQUIRE(bridge_area > 30.); + } + } +} + +SCENARIO("A floating insert below its covering run is filled by the run and resumes on top", "[MultiNozzleLayerHeight]") { + // Geometry whose covering run commits above it would print into thin air before any support + // exists: its floating layers are dropped, the covering run's pass fills the object volume + // they occupied, and the region resumes fully supported on top of the pass. + GIVEN("A hollow tube capped by a pocketed coarse roof with a fine insert starting mid-run") { + DynamicPrintConfig config = two_extruder_config(0.6); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.6})); + config.option>("extruder_layer_height_mode", true)->value = elhmFixed; + Print print; + Model model; + // Coarse volume: tube walls, a full roof slab over the cavity, and a one-run pocket rim + // above it. The run pairs the slab with the rim and drops the slab's pocket footprint. + TriangleMesh roof = mesh(TestMesh::cube_with_hole); // 20 x 20, 10 mm hole + roof.scale(Vec3f(1.f, 1.f, 0.1f)); // 1 mm tall tube + TriangleMesh slab = mesh(TestMesh::cube_20x20x20); + slab.scale(Vec3f(1.f, 1.f, 0.01f)); // 20 x 20 x 0.2 mm + slab.translate(0.f, 0.f, 1.f); + roof.merge(slab); + const float rim_dims[4][4] = {{0.3f, 1.f, 0.f, 0.f}, {0.3f, 1.f, 14.f, 0.f}, + {0.4f, 0.3f, 6.f, 0.f}, {0.4f, 0.3f, 6.f, 14.f}}; + for (const auto &d : rim_dims) { + TriangleMesh rim = mesh(TestMesh::cube_20x20x20); + rim.scale(Vec3f(d[0], d[1], 0.02f)); // rim pieces around an 8 x 8 pocket + rim.translate(d[2], d[3], 1.2f); + roof.merge(rim); + } + TriangleMesh insert = mesh(TestMesh::cube_20x20x20); + insert.scale(Vec3f(0.4f, 0.4f, 0.04f)); // 8 x 8 x 0.8 mm in the pocket + insert.translate(6.f, 6.f, 1.2f); + ModelObject *object = model.add_object(); + object->name = "pocketed_roof"; + ModelVolume *coarse_volume = object->add_volume(std::move(roof)); + coarse_volume->config.set("extruder", 2); + object->add_volume(std::move(insert)); + object->add_instance(); + // This fork's arrangement engine rejects positions outside the (unset) plate even for + // an InfiniteBed; place the object at a fixed bed spot like init_two_part_print(). + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); + THEN("the covering run fills the floating layers and the insert resumes on top") { + REQUIRE(print.validate().string.empty()); + print.process(); + const PrintObject &po = *print.objects().front(); + int fine_region = -1, coarse_region = -1; + find_regions(po, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + REQUIRE(coarse_region >= 0); + double floating_area = 0., filled_bridge_area = 0., resumed_area = 0.; + for (size_t idx = 0; idx < po.layer_count(); ++ idx) { + const Layer *layer = po.get_layer(int(idx)); + for (int r = 0; r < layer->region_count(); ++ r) + for (const Surface &surface : layer->get_region(r)->fill_surfaces.surfaces) { + const double area = unscale(unscale(surface.expolygon.area())); + if (r == fine_region && layer->print_z < 1.7) + floating_area += area; + else if (r == coarse_region && std::abs(layer->print_z - 1.6) < EPSILON && surface.surface_type == stBottomBridge) + filled_bridge_area += area; + else if (r == fine_region && std::abs(layer->print_z - 1.8) < EPSILON) + resumed_area += area; + } + } + CAPTURE(floating_area, filled_bridge_area, resumed_area); + REQUIRE(floating_area < 0.1); // nothing of the insert prints in the air + REQUIRE(filled_bridge_area > 60.); // the coarse pass bridges rim and pocket alike + REQUIRE(resumed_area > 25.); // the insert continues on top of the pass + } + } +} + +SCENARIO("Per-extruder layer height respects the extruder's minimum layer height", "[MultiNozzleLayerHeight]") { + GIVEN("A 0.6 mm preferred layer height with a 0.4 mm minimum, on a part height leaving a 1-layer tail") { + DynamicPrintConfig config = two_extruder_config(0.6); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.6})); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.07, 0.4})); + Print print; + Model model; + // 10.2 mm parts: a 0.4 mm first layer + 49 layers of 0.2 mm. 49 is not divisible by the + // multiplier 3, so without the minimum the column would end in a single 0.2 mm layer. + init_two_part_print(print, model, config, 0.51f); + THEN("no layer of the coarse part above the first prints below 0.4 mm") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(coarse_region >= 0); + + size_t below_min = 0, full_runs = 0, forced_runs = 0; + for (size_t idx = 1; idx < object.layer_count(); ++ idx) { + const std::vector heights = region_path_heights(object.get_layer(int(idx))->get_region(coarse_region)); + for (float height : heights) { + if (height < 0.4 - 1e-3) + ++ below_min; + else if (std::abs(height - 0.6) < 1e-3) + ++ full_runs; + else if (std::abs(height - 0.4) < 1e-3) + ++ forced_runs; + } + } + CHECK(below_min == 0); + CHECK(full_runs > 0); + CHECK(forced_runs > 0); + } + } + GIVEN("A preferred layer height below the extruder's minimum layer height") { + DynamicPrintConfig config = two_extruder_config(0.4); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.07, 0.45})); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("validation warns instead of rejecting: the minimum is a soft profile limit") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("minimum layer") != std::string::npos); + REQUIRE(warnings_have_opt_key(warnings, "extruder_layer_height")); + } + } +} + +// Shared check: the fine part's walls print on every layer with the base layer heights while +// combined 0.4 mm high infill appears on some layers above the first. +static void check_plain_walls_combined_infill(Print &print) +{ + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + + size_t wall_bad_heights = 0, wall_missing = 0, combined_infill_paths = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const LayerRegion *layerm = object.get_layer(int(idx))->get_region(fine_region); + std::vector wall_heights; + collect_path_heights(layerm->perimeters, wall_heights); + if (wall_heights.empty()) + ++ wall_missing; + const double expected = idx == 0 ? 0.4 : 0.2; + for (float height : wall_heights) + if (std::abs(height - expected) > 1e-3) + ++ wall_bad_heights; + if (idx > 0) { + std::vector fill_heights; + collect_path_heights(layerm->fills, fill_heights); + for (float height : fill_heights) + if (std::abs(height - 0.4) < 1e-3) + ++ combined_infill_paths; + } + } + CHECK(wall_missing == 0); + CHECK(wall_bad_heights == 0); + CHECK(combined_infill_paths > 0); +} + +SCENARIO("Per-extruder layer height honors feature filaments", "[MultiNozzleLayerHeight]") { + GIVEN("A part whose sparse infill uses the filament with a 0.4 mm preferred layer height") { + DynamicPrintConfig config = two_extruder_config(0.4); + // Both parts print their sparse infill with filament 2; the first part's walls stay on + // filament 1 with no preferred layer height. + config.set_key_value("sparse_infill_filament_id", new ConfigOptionInt(2)); + config.set_key_value("sparse_infill_density", new ConfigOptionPercent(15)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the first part prints per-layer walls with sparse infill combined to 0.4 mm") { + check_plain_walls_combined_infill(print); + } + } + + GIVEN("A part whose 100% density solid infill prints with the preferred-height filament") { + DynamicPrintConfig config = two_extruder_config(0.4); + // At 100% density the combined infill is internal solid infill printed with the INTERNAL + // SOLID filament (PrintRegion::extruder()), so that filament's preference must decide the + // combined height. + config.set_key_value("internal_solid_filament_id", new ConfigOptionInt(2)); + config.set_key_value("sparse_infill_density", new ConfigOptionPercent(100)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the first part prints per-layer walls with solid infill combined to 0.4 mm") { + check_plain_walls_combined_infill(print); + } + } + + GIVEN("A part whose outer walls use a filament with a different preferred layer height") { + DynamicPrintConfig config = two_extruder_config(0.4); + // The first part's outer walls print with filament 2 while its inner walls stay on + // filament 1 ("Default", no preferred height): the explicit preference sets the part's + // pitch and the no-preference filaments follow it instead of vetoing it. + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(2)); + // Keep the combined-region line width checks out of the way, this test targets heights. + config.set_key_value("line_width", new ConfigOptionFloatOrPercent(0.5, false)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the part combines to the outer wall filament's height, warning about limits") { + // Filament 1 prints the pitch above its max_layer_height (0.3 < 0.4): warned, not vetoed. + // validate() appends warnings to the vector out-param (upstream Orca API). + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("maximum layer") != std::string::npos); + REQUIRE(warnings_have_opt_key(warnings, "extruder_layer_height")); + + print.process(); + // Both parts combine now; the first part's region is identified by its top surface + // filament staying on 1. Its walls print 0.4 mm on every 2nd layer. + const PrintObject &object = *print.objects().front(); + int fine_region = -1; + for (size_t i = 0; i < object.num_printing_regions(); ++ i) + if (object.printing_region(i).config().top_surface_filament_id.value == 1) + fine_region = int(i); + REQUIRE(fine_region >= 0); + size_t combined_layers = 0, bad_heights = 0, unexpected = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector heights; + collect_path_heights(object.get_layer(int(idx))->get_region(fine_region)->perimeters, heights); + if (idx % 2 == 0) { + if (! heights.empty()) + ++ combined_layers; + for (float height : heights) + if (std::abs(height - 0.4) > 1e-3) + ++ bad_heights; + } else if (! heights.empty()) + ++ unexpected; + } + CHECK(combined_layers > 20); + CHECK(bad_heights == 0); + CHECK(unexpected == 0); + } + } + + GIVEN("Feature filaments with disagreeing preferred layer heights and no wall preference") { + // Top surfaces on filament 2 (prefers 0.4 mm) and bottom surfaces on filament 3 (prefers + // 0.6 mm): the features cannot agree on one pitch, so the part keeps the object layer + // height and validation warns that not all preferences can be honored. + DynamicPrintConfig config = two_extruder_config(0.4); + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({0.4, 0.6, 0.6})); + config.set_key_value("extruder_layer_height", new ConfigOptionFloats({0., 0.4, 0.6})); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.07, 0.07, 0.07})); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.6, 0.6})); + config.set_key_value("filament_diameter", new ConfigOptionFloats({1.75, 1.75, 1.75})); + config.set_key_value("filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00", "#0000FF"})); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PLA", "PLA"})); + config.set_key_value("default_filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00", "#0000FF"})); + config.set_key_value("nozzle_temperature", new ConfigOptionInts({210, 210, 210})); + config.set_key_value("nozzle_temperature_range_low", new ConfigOptionInts({190, 190, 190})); + config.set_key_value("nozzle_temperature_range_high", new ConfigOptionInts({240, 240, 240})); + config.set_key_value("flush_volumes_matrix", new ConfigOptionFloats(std::vector(9, 0.))); + config.set_key_value("machine_max_acceleration_extruding", new ConfigOptionFloats({100000., 100000., 100000.})); + config.set_key_value("top_surface_filament_id", new ConfigOptionInt(2)); + config.set_key_value("bottom_surface_filament_id", new ConfigOptionInt(3)); + // Keep the combined-region line width checks out of the way, this test targets heights. + config.set_key_value("line_width", new ConfigOptionFloatOrPercent(0.5, false)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the part keeps the object layer height and validation warns") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("cannot all be honored") != std::string::npos); + + print.process(); + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + size_t missing = 0, bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector heights; + collect_path_heights(object.get_layer(int(idx))->get_region(fine_region)->perimeters, heights); + if (heights.empty()) + ++ missing; + const double expected = idx == 0 ? 0.4 : 0.2; + for (float height : heights) + if (std::abs(height - expected) > 1e-3) + ++ bad_heights; + } + CHECK(missing == 0); + CHECK(bad_heights == 0); + } + } +} + +SCENARIO("Fill line width follows the filament that prints the surface", "[MultiNozzleLayerHeight]") { + GIVEN("Internal solid infill mapped to the 0.6 mm filament, bottom surfaces staying on the 0.4 mm filament") { + DynamicPrintConfig config = two_extruder_config(0.); + config.set_key_value("internal_solid_filament_id", new ConfigOptionInt(2)); + config.set_key_value("initial_layer_line_width", new ConfigOptionFloatOrPercent(125., true)); + config.set_key_value("internal_solid_infill_line_width", new ConfigOptionFloatOrPercent(105., true)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("bottom surface widths resolve against their own filament's nozzle") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + + // Bottom surfaces print with filament 1, so their percent line width resolves against + // its 0.4 mm nozzle, while internal solid infill (filament 2) resolves against 0.6 mm. + // Solid fills may stretch line spacing up to 20% to fit a region evenly, so accept + // widths in [nominal, 1.2 * nominal]. + // Notes on the expected widths: + // - Bottom surface paths resolve their percent width against filament 1's 0.4 mm nozzle. + // - Internal solid infill proper resolves against filament 2's 0.6 mm nozzle - but the + // solid paths ADJACENT to top/bottom shells print with the surface's filament by + // design (Fill.cpp), so a filament-1-derived width band among erSolidInfill paths is + // correct, and individual lines may be spacing-adapted below the nominal width. + // Assert each band exists where it must and nothing exceeds its own band's ceiling. + size_t bottom_paths = 0, bottom_in_band = 0, solid_paths = 0, solid_in_band = 0, solid_above_band = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector> widths; + collect_path_role_widths(object.get_layer(int(idx))->get_region(fine_region)->fills, widths); + for (const std::pair &role_width : widths) { + const bool bottom = role_width.first == erBottomSurface; + if (! bottom && role_width.first != erSolidInfill) + continue; + ++ (bottom ? bottom_paths : solid_paths); + const double expected = (idx == 0 ? 1.25 : 1.05) * (bottom ? 0.4 : 0.6); + if (role_width.second >= expected - 1e-3 && role_width.second <= expected * 1.2 + 1e-3) + ++ (bottom ? bottom_in_band : solid_in_band); + if (! bottom && role_width.second > expected * 1.2 + 1e-3) + ++ solid_above_band; + } + } + CHECK(bottom_paths > 0); + CHECK(bottom_in_band * 4 > bottom_paths * 3); + CHECK(solid_paths > 0); + CHECK(solid_in_band > 0); + CHECK(solid_above_band == 0); + } + } +} + +SCENARIO("Combined infill is limited by the printing nozzle only", "[MultiNozzleLayerHeight]") { + GIVEN("Infill combining to a preferred height above the filament's maximum layer height") { + // Infill on filament 2: preferred layer height 0.6 exceeds its max_layer_height 0.45. + // The maximum is a soft profile limit: the explicit preference wins (with stock profiles + // the maximum would otherwise silently veto every legal preference), only the physical + // 0.6 mm nozzle bore caps the combining, and validation warns about the exceeded maximum. + DynamicPrintConfig config = two_extruder_config(0.6); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.45})); + config.set_key_value("sparse_infill_filament_id", new ConfigOptionInt(2)); + config.set_key_value("internal_solid_filament_id", new ConfigOptionInt(2)); + config.set_key_value("sparse_infill_density", new ConfigOptionPercent(15)); + Print print; + Model model; + // A single part: filament 2 prints only infill (the derived 0.6 mm feature pitch is vetoed + // by the walls' physical 0.4 mm nozzle, so the part itself stays at the object layer height). + TriangleMesh cube = mesh(TestMesh::cube_20x20x20); + cube.scale(Vec3f(1.f, 1.f, 0.5f)); + ModelObject *object_model = model.add_object(); + object_model->name = "single_cube"; + object_model->add_volume(std::move(cube)); + object_model->add_instance(); + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); + THEN("infill combines to the full preferred height and validation warns about the maximum") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("maximum layer") != std::string::npos); + print.process(); + + const PrintObject &object = *print.objects().front(); + size_t over_preferred = 0, full_height = 0; + for (size_t idx = 1; idx < object.layer_count(); ++ idx) + for (const LayerRegion *layerm : object.get_layer(int(idx))->regions()) { + std::vector heights; + collect_path_heights(layerm->fills, heights); + for (float height : heights) { + if (height > 0.6 + 1e-3) + ++ over_preferred; + else if (std::abs(height - 0.6) < 1e-3) + ++ full_height; + } + } + CHECK(over_preferred == 0); + CHECK(full_height > 0); + } + } + + GIVEN("Walls combining to a pitch above a feature filament's maximum layer height") { + // Both wall filaments map to filament 2 at a 0.4 mm pitch while top/bottom/solid features + // stay on filament 1 whose max_layer_height is only 0.3: the explicit wall preference + // wins - the part combines to 0.4 mm and validation warns about the exceeded maximum + // (only a physically too small nozzle vetoes the pitch). + DynamicPrintConfig config = two_extruder_config(0.4); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(2)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(2)); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.3, 0.45})); + // Keep the combined-region line width checks out of the way, this test targets heights. + config.set_key_value("line_width", new ConfigOptionFloatOrPercent(0.5, false)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("validation warns about the maximum and the part prints the walls' pitch") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("maximum layer") != std::string::npos); + + print.process(); + // Both parts' walls print with filament 2, so the parts are told apart by their + // top surface filament; the first part now combines like the second. + const PrintObject &object = *print.objects().front(); + int fine_region = -1; + for (size_t i = 0; i < object.num_printing_regions(); ++ i) + if (object.printing_region(i).config().top_surface_filament_id.value == 1) + fine_region = int(i); + REQUIRE(fine_region >= 0); + size_t combined_layers = 0, wall_bad_heights = 0, unexpected = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector heights; + collect_path_heights(object.get_layer(int(idx))->get_region(fine_region)->perimeters, heights); + if (idx % 2 == 0) { + if (! heights.empty()) + ++ combined_layers; + for (float height : heights) + if (std::abs(height - 0.4) > 1e-3) + ++ wall_bad_heights; + } else if (! heights.empty()) + ++ unexpected; + } + CHECK(combined_layers > 20); + CHECK(wall_bad_heights == 0); + CHECK(unexpected == 0); + } + } + + GIVEN("Internal solid infill on the coarse filament while the walls stay on Default") { + // Only internal_solid_filament_id points at filament 2 (preferred + // layer height 0.4) and no wall filament carries a preference. The feature filament's + // preference must derive the part's pitch instead of being silently ignored; areas falling + // back to the object layer height print below filament 2's 0.3 mm minimum, which warns. + DynamicPrintConfig config = two_extruder_config(0.4); + config.set_key_value("internal_solid_filament_id", new ConfigOptionInt(2)); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.07, 0.3})); + // Keep the combined-region line width checks out of the way, this test targets heights. + config.set_key_value("line_width", new ConfigOptionFloatOrPercent(0.5, false)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the feature filament's preference drives the part's pitch, warning about the minimum") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("minimum layer") != std::string::npos); + + print.process(); + // The first part's walls have no preference of their own, yet the part prints 0.4 mm + // layers on every 2nd layer because its internal solid infill filament asks for them. + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + size_t combined_layers = 0, bad_heights = 0, unexpected = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector heights; + collect_path_heights(object.get_layer(int(idx))->get_region(fine_region)->perimeters, heights); + if (idx % 2 == 0) { + if (! heights.empty()) + ++ combined_layers; + for (float height : heights) + if (std::abs(height - 0.4) > 1e-3) + ++ bad_heights; + } else if (! heights.empty()) + ++ unexpected; + } + CHECK(combined_layers > 20); + CHECK(bad_heights == 0); + CHECK(unexpected == 0); + } + } +} + +SCENARIO("Fill collections dispatch to the filament their flow was computed for", "[MultiNozzleLayerHeight]") { + GIVEN("A region with distinct per-feature filaments") { + PrintRegionConfig region_config; + region_config.outer_wall_filament_id.value = 1; + region_config.inner_wall_filament_id.value = 1; + region_config.sparse_infill_filament_id.value = 4; + region_config.internal_solid_filament_id.value = 3; + region_config.top_surface_filament_id.value = 1; + region_config.bottom_surface_filament_id.value = 1; + const PrintRegion region(region_config, region_config.hash(), 0); + LayerTools layer_tools(0.); + + auto collection_extruder = [&](std::initializer_list roles) { + ExtrusionEntityCollection eec; + for (ExtrusionRole role : roles) + eec.entities.push_back(new ExtrusionPath(role)); + return layer_tools.extruder(eec, region); + }; + + THEN("top and bottom surfaces keep their filament when gap fill is mixed in") { + CHECK(collection_extruder({erTopSolidInfill}) == 0); // 0 based filament 1 + CHECK(collection_extruder({erTopSolidInfill, erGapFill}) == 0); + CHECK(collection_extruder({erBottomSurface, erGapFill}) == 0); + CHECK(collection_extruder({erSolidInfill, erGapFill}) == 2); // filament 3 + } + THEN("external bridges print with the bottom surface filament, internal ones stay solid") { + CHECK(collection_extruder({erBridgeInfill}) == 0); // bottom filament 1 + CHECK(collection_extruder({erInternalBridgeInfill}) == 2); // internal solid filament 3 + } + THEN("gap fill with no sibling surface prints with the outer wall filament") { + PrintRegionConfig gap_region_config = region_config; + gap_region_config.outer_wall_filament_id.value = 2; + const PrintRegion gap_region(gap_region_config, gap_region_config.hash(), 0); + ExtrusionEntityCollection eec; + eec.entities.push_back(new ExtrusionPath(erGapFill)); + CHECK(layer_tools.extruder(eec, gap_region) == 1); // 0 based outer wall filament 2 + } + } +} + +SCENARIO("Support nozzle diameter restricts support printing", "[MultiNozzleLayerHeight]") { + // A raft makes the object require support handling without any overhang geometry: the raft + // layers below the object print as support-only layers. + auto raft_config = [](double support_nozzle_diameter) { + DynamicPrintConfig config = two_extruder_config(0.); + config.set_key_value("raft_layers", new ConfigOptionInt(2)); + config.option>("support_type", true)->value = stNormalAuto; + config.set_key_value("support_nozzle_diameter", new ConfigOptionFloat(support_nozzle_diameter)); + config.set_key_value("support_line_width", new ConfigOptionFloatOrPercent(105., true)); + return config; + }; + + GIVEN("A raft restricted to the 0.6 mm nozzle while the default filament prints with 0.4 mm") { + DynamicPrintConfig config = raft_config(0.6); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("support flows, layer height limits and tool ordering follow the 0.6 mm filament") { + REQUIRE(print.validate().string.empty()); + + const PrintObject &object = *print.objects().front(); + // Support / raft flows must resolve width against the restricted nozzle, not against + // extruder 1 that the "default" support filament falls back to. + REQUIRE(double(support_material_flow(&object).width()) == Catch::Approx(1.05 * 0.6).margin(1e-4)); + REQUIRE(double(support_material_interface_flow(&object).width()) == Catch::Approx(1.05 * 0.6).margin(1e-4)); + + // Support layer height limits follow the restricted nozzle (filament 2: max 0.45). + PrintConfig print_config; + print_config.apply(config, true); + PrintObjectConfig object_config; + object_config.apply(config, true); + const SlicingParameters params = SlicingParameters::create_from_config( + print_config, object_config, 10., std::vector{0, 1}, Vec3d(1., 1., 1.)); + REQUIRE(params.max_suport_layer_height == Catch::Approx(0.45).margin(1e-6)); + + // The raft layers below the object print with filament 2 only. + print.process(); + ToolOrdering tool_ordering(print, (unsigned int)-1, false); + size_t support_only_layers = 0, wrong_extruders = 0; + for (const LayerTools &layer_tools : tool_ordering.layer_tools()) + if (layer_tools.has_support && ! layer_tools.has_object) { + ++ support_only_layers; + for (unsigned int extruder_id : layer_tools.extruders) + if (extruder_id != 1) // 0 based: filament 2 prints with the 0.6 mm nozzle + ++ wrong_extruders; + } + CHECK(support_only_layers > 0); + CHECK(wrong_extruders == 0); + } + } + + GIVEN("A support nozzle diameter no extruder has") { + DynamicPrintConfig config = raft_config(0.5); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("validation fails") { + const StringObjectException err = print.validate(); + REQUIRE(! err.string.empty()); + REQUIRE(err.opt_key == "support_nozzle_diameter"); + } + } + + GIVEN("A support filament printing with a different nozzle than the support nozzle diameter") { + DynamicPrintConfig config = raft_config(0.6); + config.set_key_value("support_filament", new ConfigOptionInt(1)); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("validation fails") { + const StringObjectException err = print.validate(); + REQUIRE(! err.string.empty()); + REQUIRE(err.opt_key == "support_filament"); + } + } +} + +SCENARIO("A raft keeps the bottom surfaces of combined regions", "[MultiNozzleLayerHeight]") { + GIVEN("A combined region printing on a raft") { + DynamicPrintConfig config = two_extruder_config(0.4); + config.set_key_value("raft_layers", new ConfigOptionInt(2)); + config.option>("support_type", true)->value = stNormalAuto; + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("the first layer above the raft prints uncombined and carries the bottom surfaces") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + int fine_region, coarse_region; + find_regions(object, fine_region, coarse_region); + REQUIRE(fine_region >= 0); + REQUIRE(coarse_region >= 0); + + // The first layer above the raft must not be swallowed by a combined group: surface + // detection can only seed the object's bottom shells there. + const Layer *first_layer = object.get_layer(0); + size_t bottom_regions = 0; + for (int region_id : { fine_region, coarse_region }) { + const LayerRegion *layerm = first_layer->get_region(region_id); + const std::vector heights = region_path_heights(layerm); + CHECK(! heights.empty()); + for (float height : heights) + CHECK(double(height) == Catch::Approx(0.2).margin(1e-3)); + for (const Surface &surface : layerm->fill_surfaces.surfaces) + if (surface.is_bottom()) { + ++ bottom_regions; + break; + } + } + CHECK(bottom_regions == 2); + + // Combining still happens above the first object layer. + size_t combined_layers = 0; + for (size_t idx = 1; idx < object.layer_count(); ++ idx) + for (float height : region_path_heights(object.get_layer(int(idx))->get_region(coarse_region))) + if (std::abs(height - 0.4) < 1e-3) { + ++ combined_layers; + break; + } + CHECK(combined_layers > 0); + } + } +} + +SCENARIO("Per-extruder layer height validation rejects invalid configurations", "[MultiNozzleLayerHeight]") { + auto expect_error = [](double second_extruder_layer_height) { + DynamicPrintConfig config = two_extruder_config(second_extruder_layer_height); + Print print; + Model model; + init_two_part_print(print, model, config); + const StringObjectException err = print.validate(); + REQUIRE(! err.string.empty()); + REQUIRE(err.opt_key == "extruder_layer_height"); + }; + GIVEN("An extruder layer height that is no integer multiple of the object layer height") { + THEN("validation fails") { expect_error(0.5); } + } + GIVEN("An extruder layer height smaller than the object layer height") { + THEN("validation fails") { expect_error(0.1); } + } + GIVEN("An extruder layer height exceeding the nozzle diameter") { + THEN("validation fails") { expect_error(0.8); } + } + GIVEN("An extruder layer height exceeding the extruder's maximum layer height") { + // 0.6 is a multiple of 0.2 and fits the 0.6 mm nozzle; it exceeds max_layer_height 0.45, + // but that is a soft profile limit - the explicit preference prints and validation warns + // (with stock profiles the maximum would otherwise reject every legal preference). + DynamicPrintConfig config = two_extruder_config(0.6); + Print print; + Model model; + init_two_part_print(print, model, config); + THEN("validation warns instead of failing") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + REQUIRE(concat_warning_strings(warnings).find("maximum layer") != std::string::npos); + REQUIRE(warnings_have_opt_key(warnings, "extruder_layer_height")); + } + } +} + +// Four extruders with different nozzles, mirroring a Snapmaker U1 customized to 0.2/0.4/0.6/0.8 mm +// nozzles where every extruder carries a preferred layer height (4 * the 0.12 mm object layer +// height on the largest). On such a machine no whole-part pitch is possible - the 0.2 mm nozzle +// prints the part's default features - so the per-feature combining paths must serve instead. +static DynamicPrintConfig four_nozzle_config() +{ + DynamicPrintConfig config = DynamicPrintConfig::full_print_config(); + config.set_key_value("layer_height", new ConfigOptionFloat(0.12)); + config.set_key_value("initial_layer_print_height", new ConfigOptionFloat(0.12)); + config.set_key_value("enable_prime_tower", new ConfigOptionBool(false)); + config.set_key_value("enable_support", new ConfigOptionBool(false)); + + config.set_key_value("nozzle_diameter", new ConfigOptionFloats({0.2, 0.4, 0.6, 0.8})); + config.set_key_value("extruder_layer_height", new ConfigOptionFloats({0.12, 0.24, 0.36, 0.48})); + config.set_key_value("min_layer_height", new ConfigOptionFloats({0.08, 0.08, 0.14, 0.16})); + config.set_key_value("max_layer_height", new ConfigOptionFloats({0.16, 0.32, 0.48, 0.64})); + config.set_key_value("filament_diameter", new ConfigOptionFloats({1.75, 1.75, 1.75, 1.75})); + config.set_key_value("filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00", "#0000FF", "#FFFF00"})); + config.set_key_value("filament_type", new ConfigOptionStrings({"ABS", "ABS", "ABS", "ABS"})); + config.set_key_value("default_filament_colour", new ConfigOptionStrings({"#FF0000", "#00FF00", "#0000FF", "#FFFF00"})); + config.set_key_value("nozzle_temperature", new ConfigOptionInts({240, 240, 240, 240})); + config.set_key_value("nozzle_temperature_range_low", new ConfigOptionInts({220, 220, 220, 220})); + config.set_key_value("nozzle_temperature_range_high", new ConfigOptionInts({270, 270, 270, 270})); + config.set_key_value("flush_multiplier", new ConfigOptionFloats({1.})); + config.set_key_value("flush_volumes_matrix", new ConfigOptionFloats(std::vector(16, 0.))); + config.set_key_value("machine_max_acceleration_extruding", new ConfigOptionFloats({100000., 100000.})); + config.set_key_value("use_relative_e_distances", new ConfigOptionBool(false)); + return config; +} + +// One 20x20x10 mm cube. +static void init_cube_print(Print &print, Model &model, const DynamicPrintConfig &config) +{ + TriangleMesh cube = mesh(TestMesh::cube_20x20x20); + cube.scale(Vec3f(1.f, 1.f, 0.5f)); + ModelObject *object = model.add_object(); + object->name = "cube"; + object->add_volume(std::move(cube)); + object->add_instance(); + for (ModelObject *mo : model.objects) { + mo->center_around_origin(); + mo->translate(120., 120., 0.); + mo->ensure_on_bed(); + } + print.apply(model, config); + print.set_status_silent(); +} + +SCENARIO("Walls combine to their filament's pitch when the part cannot follow", "[MultiNozzleLayerHeight]") { + GIVEN("Both walls on the 0.8 mm nozzle filament preferring 0.48 mm, the rest on the 0.2 mm nozzle") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(4)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("walls print once per 4 layers at 0.48 mm while the fills keep 0.12 mm") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + // The whole-part pitch is impossible (0.2 mm nozzle prints the fills), but the walls + // combine on their own - no "parts print with the object layer height" fallback. + CHECK(concat_warning_strings(warnings).find("too small to extrude") == std::string::npos); + print.process(); + + const PrintObject &object = *print.objects().front(); + size_t tall_wall_layers = 0, plain_wall_layers = 0, wall_bad_heights = 0, fill_bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const LayerRegion *layerm = object.get_layer(int(idx))->get_region(0); + std::vector wall_heights; + collect_path_heights(layerm->perimeters, wall_heights); + bool tall = false, plain = false; + for (float height : wall_heights) { + if (std::abs(height - 0.48) < 1e-3) + tall = true; + else if (std::abs(height - 0.12) < 1e-3 || std::abs(height - 0.24) < 1e-3) + // The first layer and the run capping the object top stay finer. + plain = true; + else + ++ wall_bad_heights; + } + if (tall) ++ tall_wall_layers; + if (plain) ++ plain_wall_layers; + std::vector fill_heights; + collect_path_heights(layerm->fills, fill_heights); + for (float height : fill_heights) + if (std::abs(height - 0.12) > 1e-3) + ++ fill_bad_heights; + } + // 83 layers: layer 0 plain, 20 full runs of 4, a 2-layer cap. + CHECK(tall_wall_layers >= 15); + CHECK(plain_wall_layers <= 4); + CHECK(wall_bad_heights == 0); + CHECK(fill_bad_heights == 0); + } + } +} + +SCENARIO("Top surfaces combine to their filament's pitch by absorbing the shells below", "[MultiNozzleLayerHeight]") { + GIVEN("Top surfaces on the 0.8 mm nozzle filament preferring 0.48 mm, the rest on the 0.2 mm nozzle") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("top_surface_filament_id", new ConfigOptionInt(4)); + config.set_key_value("top_shell_layers", new ConfigOptionInt(9)); + config.set_key_value("bottom_shell_layers", new ConfigOptionInt(7)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("the topmost surface prints once at 0.48 mm while everything else keeps 0.12 mm") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + size_t tall_fill_paths = 0, wall_bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const LayerRegion *layerm = object.get_layer(int(idx))->get_region(0); + std::vector fill_heights; + collect_path_heights(layerm->fills, fill_heights); + for (float height : fill_heights) + if (std::abs(height - 0.48) < 1e-3) { + ++ tall_fill_paths; + // Only the topmost layer may carry the absorbed pass. + CHECK(idx == object.layer_count() - 1); + } + std::vector wall_heights; + collect_path_heights(layerm->perimeters, wall_heights); + for (float height : wall_heights) + if (std::abs(height - 0.12) > 1e-3) + ++ wall_bad_heights; + } + CHECK(tall_fill_paths > 0); + CHECK(wall_bad_heights == 0); + } + } +} + +SCENARIO("Internal solid infill combines to its filament's pitch", "[MultiNozzleLayerHeight]") { + GIVEN("Disagreeing wall preferences with the internal solid infill on the 0.8 mm nozzle filament") { + // The wall filaments' explicit preferences disagree (0.12 vs 0.24 mm), so the part keeps + // the object layer height and the walls split. The internal solid infill used to fall + // through every combining pass here, printing 0.12 mm layers on the 0.8 mm nozzle - below + // its own 0.16 mm minimum layer height. + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(1)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(2)); + config.set_key_value("sparse_infill_filament_id", new ConfigOptionInt(3)); + config.set_key_value("internal_solid_filament_id", new ConfigOptionInt(4)); + config.set_key_value("top_surface_filament_id", new ConfigOptionInt(4)); + config.set_key_value("bottom_surface_filament_id", new ConfigOptionInt(4)); + config.set_key_value("top_shell_layers", new ConfigOptionInt(4)); + config.set_key_value("bottom_shell_layers", new ConfigOptionInt(5)); + config.set_key_value("sparse_infill_density", new ConfigOptionPercent(15)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("the solid interior prints 0.48 mm groups and never below the extruder's minimum") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + // The bottom surfaces (also filament 4) keep printing the object layer height: warned. + REQUIRE(concat_warning_strings(warnings).find("minimum layer") != std::string::npos); + print.process(); + + const PrintObject &object = *print.objects().front(); + // The one legitimate below-minimum leftover: the single solid layer an internal + // bridge rests on. It is tied to its own layer (sparse below, the bridge above), so + // no combining can lift it to the minimum. + auto seats_internal_bridge = [&object](size_t idx) { + if (idx + 1 >= object.layer_count()) + return false; + const Surfaces &above = object.get_layer(int(idx + 1))->get_region(0)->fill_surfaces.surfaces; + return std::any_of(above.begin(), above.end(), + [](const Surface &surface) { return surface.surface_type == stInternalBridge; }); + }; + size_t tall_solid_paths = 0, below_min_paths = 0; + size_t tall_sparse_paths = 0, below_min_sparse_paths = 0; + std::vector below_min_layers; + for (size_t idx = 1; idx < object.layer_count(); ++ idx) + for_each_path(object.get_layer(int(idx))->get_region(0)->fills, [&](const ExtrusionPath &path) { + if (path.role() == erInternalInfill) { + // The sparse infill (filament 3, preferring 0.36 mm) must honor its own + // 0.14 mm minimum too: band-edge leftovers re-group instead of stranding. + if (path.height > 0.36f - 1e-3f) + ++ tall_sparse_paths; + else if (path.height < 0.14f - 1e-3f) + ++ below_min_sparse_paths; + return; + } + if (path.role() != erSolidInfill) + return; + if (path.height > 0.48f - 1e-3f) + ++ tall_solid_paths; + else if (path.height < 0.16f - 1e-3f && ! seats_internal_bridge(idx)) { + ++ below_min_paths; + if (below_min_layers.empty() || below_min_layers.back() != idx) + below_min_layers.push_back(idx); + } + }); + // Phase coherence: the uniform interior must extrude on the same layers everywhere; + // phase-shifted areas would leave a permanent one-course step along their seam. + size_t sparse_layers = 0; + for (size_t idx = 10; idx < 40; ++ idx) { + bool has_sparse = false; + for_each_path(object.get_layer(int(idx))->get_region(0)->fills, [&](const ExtrusionPath &path) { + has_sparse |= path.role() == erInternalInfill; + }); + if (has_sparse) + ++ sparse_layers; + } + CAPTURE(below_min_layers); + CHECK(tall_solid_paths > 0); + CHECK(below_min_paths == 0); + CHECK(tall_sparse_paths > 0); + CHECK(below_min_sparse_paths == 0); + CHECK(sparse_layers <= 12); + } + } +} + +SCENARIO("Support materials exclude filaments of other types", "[MultiNozzleLayerHeight]") { + GIVEN("PETG loaded twice, the support base material set to PETG") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PETG", "PETG", "PLA"})); + config.set_key_value("enable_support", new ConfigOptionBool(true)); + config.set_key_value("support_base_material", new ConfigOptionString("PETG")); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("only the PETG filaments may print the base and the selector stays on default") { + const PrintObject &object = *print.objects().front(); + CHECK(object.config().support_filament.value == 0); + CHECK(! object.support_filament_allowed(1, false)); + CHECK(object.support_filament_allowed(2, false)); + CHECK(object.support_filament_allowed(3, false)); + CHECK(! object.support_filament_allowed(4, false)); + CHECK(object.resolved_default_support_filament(false) == 2); + } + THEN("the interface without a material stays unrestricted") { + const PrintObject &object = *print.objects().front(); + CHECK(object.support_filament_allowed(1, true)); + CHECK(object.support_filament_allowed(4, true)); + CHECK(object.resolved_default_support_filament(true) == 0); + } + } + GIVEN("the support nozzle size and the interface material combined") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PETG", "PETG", "PLA"})); + config.set_key_value("enable_support", new ConfigOptionBool(true)); + config.set_key_value("support_nozzle_diameter", new ConfigOptionFloat(0.6)); + config.set_key_value("support_interface_material", new ConfigOptionString("PETG")); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("only the PETG filament on the 0.6 mm nozzle may print the interface") { + const PrintObject &object = *print.objects().front(); + CHECK(! object.support_filament_allowed(2, true)); + CHECK(object.support_filament_allowed(3, true)); + CHECK(object.resolved_default_support_filament(true) == 3); + CHECK(print.validate().string.empty()); + } + } + GIVEN("a material no loaded filament matches") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PETG", "PETG", "PLA"})); + config.set_key_value("enable_support", new ConfigOptionBool(true)); + config.set_key_value("support_base_material", new ConfigOptionString("TPU")); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("validation rejects the setup") { + CHECK(print.validate().string.find("base material") != std::string::npos); + } + } + GIVEN("an explicit base filament of another type") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("filament_type", new ConfigOptionStrings({"PLA", "PETG", "PETG", "PLA"})); + config.set_key_value("enable_support", new ConfigOptionBool(true)); + config.set_key_value("support_base_material", new ConfigOptionString("PETG")); + config.set_key_value("support_filament", new ConfigOptionInt(1)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("validation flags the conflict") { + CHECK(print.validate().string.find("base filament") != std::string::npos); + } + } +} + +SCENARIO("A preference-less fine-nozzle wall filament vetoes the walls-only pitch", "[MultiNozzleLayerHeight]") { + GIVEN("Outer walls on the 0.8 mm nozzle preferring 0.48 mm, inner walls on a 0.2 mm nozzle with no preference") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("extruder_layer_height", new ConfigOptionFloats({0., 0., 0., 0.48})); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(1)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("no wall combines: the 0.2 mm inner-wall nozzle cannot extrude 0.48 mm layers") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + size_t wall_bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector wall_heights; + collect_path_heights(object.get_layer(int(idx))->get_region(0)->perimeters, wall_heights); + for (float height : wall_heights) + if (std::abs(height - 0.12f) > 1e-3f) + ++ wall_bad_heights; + } + CHECK(wall_bad_heights == 0); + } + } +} + +SCENARIO("Disagreeing wall preferences meet at the lower height", "[MultiNozzleLayerHeight]") { + GIVEN("Outer walls prefer 0.48 mm (0.8 mm nozzle) and inner walls prefer 0.36 mm (0.6 mm nozzle)") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(3)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("the walls combine to 0.36 mm - the lower preference both nozzles can print") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + print.process(); + + const PrintObject &object = *print.objects().front(); + size_t tall_wall_layers = 0, wall_bad_heights = 0, fill_bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + const LayerRegion *layerm = object.get_layer(int(idx))->get_region(0); + std::vector wall_heights; + collect_path_heights(layerm->perimeters, wall_heights); + for (float height : wall_heights) { + if (std::abs(height - 0.36f) < 1e-3f) + ++ tall_wall_layers; + else if (std::abs(height - 0.12f) > 1e-3f && std::abs(height - 0.24f) > 1e-3f) + // The first layer and forced / capping runs stay finer. + ++ wall_bad_heights; + } + std::vector fill_heights; + collect_path_heights(layerm->fills, fill_heights); + for (float height : fill_heights) + if (std::abs(height - 0.12f) > 1e-3f) + ++ fill_bad_heights; + } + CHECK(tall_wall_layers >= 15); + CHECK(wall_bad_heights == 0); + CHECK(fill_bad_heights == 0); + } + } +} + +// Heights of the wall extrusions per wall class, classified like the G-code dispatch +// (perimeter_entity_uses_outer_wall_filament()). Bridges keep their nozzle-derived flow height +// and are skipped, like collect_path_heights(). +static void collect_wall_class_heights(const ExtrusionEntityCollection &collection, + std::vector &outer_heights, std::vector &inner_heights) +{ + for (const ExtrusionEntity *entity : collection.entities) { + if (auto *sub = dynamic_cast(entity)) { + collect_wall_class_heights(*sub, outer_heights, inner_heights); + continue; + } + std::vector &dst = perimeter_entity_uses_outer_wall_filament(*entity) ? outer_heights : inner_heights; + if (auto *loop = dynamic_cast(entity)) { + for (const ExtrusionPath &path : loop->paths) + if (path.role() != erBridgeInfill && path.role() != erInternalBridgeInfill && path.role() != erOverhangPerimeter) + dst.emplace_back(path.height); + } else if (auto *multi_path = dynamic_cast(entity)) { + for (const ExtrusionPath &path : multi_path->paths) + dst.emplace_back(path.height); + } else if (auto *path = dynamic_cast(entity)) + dst.emplace_back(path->height); + } +} + +// Wall heights of the whole object bucketed per class: `tall` counts the layers where a class +// prints its own pitch (the first expected entry); any height outside the class's expected set +// (the finer entries: fine cadence, first-layer and cap fallbacks) counts as `bad`. +struct WallHeightCounts { size_t outer_tall = 0, inner_tall = 0, bad = 0; }; +static WallHeightCounts count_wall_heights(const PrintObject &object, + const std::vector &outer_expected, + const std::vector &inner_expected) +{ + auto tally = [](const std::vector &heights, const std::vector &expected, size_t &tall_layers, size_t &bad) { + bool tall = false; + for (float height : heights) { + if (std::abs(height - expected.front()) < 1e-3f) + tall = true; + else if (std::none_of(expected.begin() + 1, expected.end(), + [height](float e) { return std::abs(height - e) < 1e-3f; })) + ++ bad; + } + tall_layers += tall; + }; + WallHeightCounts counts; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector outer_heights, inner_heights; + collect_wall_class_heights(object.get_layer(int(idx))->get_region(0)->perimeters, outer_heights, inner_heights); + tally(outer_heights, outer_expected, counts.outer_tall, counts.bad); + tally(inner_heights, inner_expected, counts.inner_tall, counts.bad); + } + return counts; +} + +SCENARIO("Split wall layer heights print each wall class at its own pitch", "[MultiNozzleLayerHeight]") { + GIVEN("Outer walls prefer 0.48 mm and inner walls 0.24 mm - divisible heights split automatically") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(2)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("outer walls print once per 4 layers at 0.48 mm, inner walls once per 2 at 0.24 mm") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + // The disagreement is intentional here; no conflict warning. + CHECK(concat_warning_strings(warnings).find("prefer different layer heights") == std::string::npos); + print.process(); + + // Outside committed coarse runs the outer walls follow the fine cadence; the first + // layer and fallback areas keep the object layer height. 83 layers: ~20 coarse runs + // of 4 and ~40 fine runs of 2 above the first layer. + const PrintObject &object = *print.objects().front(); + const WallHeightCounts counts = count_wall_heights(object, {0.48f, 0.24f, 0.12f}, {0.24f, 0.12f}); + CHECK(counts.outer_tall >= 15); + CHECK(counts.inner_tall >= 30); + CHECK(counts.bad == 0); + size_t fill_bad_heights = 0; + for (size_t idx = 0; idx < object.layer_count(); ++ idx) { + std::vector fill_heights; + collect_path_heights(object.get_layer(int(idx))->get_region(0)->fills, fill_heights); + for (float height : fill_heights) + if (std::abs(height - 0.12f) > 1e-3f) + ++ fill_bad_heights; + } + CHECK(fill_bad_heights == 0); + } + } + GIVEN("The finer wall class at the object layer height itself") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(1)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("inner walls print every 0.12 mm layer while outer walls combine to 0.48 mm") { + REQUIRE(print.validate().string.empty()); + print.process(); + + const WallHeightCounts counts = count_wall_heights(*print.objects().front(), {0.48f, 0.12f}, {0.12f}); + CHECK(counts.outer_tall >= 15); + CHECK(counts.bad == 0); + } + } + GIVEN("Wall preferences that do not divide evenly (0.48 mm and 0.36 mm), no adjustment") { + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(3)); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("the walls fall back to printing together at the lower height, with the conflict warning") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + CHECK(concat_warning_strings(warnings).find("prefer different layer heights") != std::string::npos); + print.process(); + + const WallHeightCounts counts = count_wall_heights(*print.objects().front(), + {0.36f, 0.24f, 0.12f}, {0.36f, 0.24f, 0.12f}); + CHECK(counts.outer_tall >= 15); + CHECK(counts.bad == 0); + } + } +} + +// Non-divisible wall preferences reconciled by "split_wall_adjust": outer walls prefer 0.48 mm +// (filament 4, multiplier 4) and inner walls 0.36 mm (filament 3, multiplier 3) over 0.12 mm +// object layers. The selected wall class moves to the nearest divisor / multiple of the other +// in the selected direction, hard-bounded by its filament's layer height limits. +static DynamicPrintConfig wall_adjust_config(WallSplitFilament filament, WallSplitDirection direction) +{ + DynamicPrintConfig config = four_nozzle_config(); + config.set_key_value("outer_wall_filament_id", new ConfigOptionInt(4)); + config.set_key_value("inner_wall_filament_id", new ConfigOptionInt(3)); + config.set_key_value("split_wall_adjust", new ConfigOptionBool(true)); + config.set_key_value("split_wall_adjust_filament", new ConfigOptionEnum(filament)); + config.set_key_value("split_wall_adjust_direction", new ConfigOptionEnum(direction)); + return config; +} + +SCENARIO("Adjusting a wall layer height reconciles non-divisible wall preferences", "[MultiNozzleLayerHeight]") { + GIVEN("The inner walls adjusted downwards") { + DynamicPrintConfig config = wall_adjust_config(wsfInnerWall, wsdDecrease); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("inner walls print 0.24 mm - the largest divisor of 0.48 mm below 0.36 mm - and the walls split") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + CHECK(concat_warning_strings(warnings).find("was adjusted") != std::string::npos); + CHECK(concat_warning_strings(warnings).find("prefer different layer heights") == std::string::npos); + print.process(); + + // In particular no 0.36 mm: the raw inner preference is off for walls. + const WallHeightCounts counts = count_wall_heights(*print.objects().front(), + {0.48f, 0.24f, 0.12f}, {0.24f, 0.12f}); + CHECK(counts.outer_tall >= 15); + CHECK(counts.inner_tall >= 30); + CHECK(counts.bad == 0); + } + } + GIVEN("The inner walls adjusted upwards") { + DynamicPrintConfig config = wall_adjust_config(wsfInnerWall, wsdIncrease); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("the inner walls land on the outer walls' 0.48 mm and the walls merge there") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + CHECK(concat_warning_strings(warnings).find("was adjusted") != std::string::npos); + CHECK(concat_warning_strings(warnings).find("prefer different layer heights") == std::string::npos); + print.process(); + + // Merged walls never print the raw 0.36 mm inner preference (bad == 0 covers it). + const WallHeightCounts counts = count_wall_heights(*print.objects().front(), + {0.48f, 0.24f, 0.12f}, {0.48f, 0.24f, 0.12f}); + CHECK(counts.inner_tall >= 15); + CHECK(counts.bad == 0); + } + } + GIVEN("The outer walls adjusted upwards, where the next candidate breaks the layer height limit") { + // The smallest multiple of the inner 0.36 mm above the outer 0.48 mm is 0.72 mm, over + // filament 4's 0.64 mm maximum layer height - a hard bound for adjustments. + DynamicPrintConfig config = wall_adjust_config(wsfOuterWall, wsdIncrease); + Print print; + Model model; + init_cube_print(print, model, config); + THEN("no adjustment happens: the walls merge at the lower height with the conflict warning") { + std::vector warnings; + REQUIRE(print.validate(&warnings).string.empty()); + CHECK(concat_warning_strings(warnings).find("was adjusted") == std::string::npos); + CHECK(concat_warning_strings(warnings).find("prefer different layer heights") != std::string::npos); + print.process(); + + const WallHeightCounts counts = count_wall_heights(*print.objects().front(), + {0.36f, 0.24f, 0.12f}, {0.36f, 0.24f, 0.12f}); + CHECK(counts.outer_tall >= 15); + CHECK(counts.bad == 0); + } + } +} diff --git a/tests/libslic3r/test_mixed_filament.cpp b/tests/libslic3r/test_mixed_filament.cpp index bcb8763d4b8..dd8a2662822 100644 --- a/tests/libslic3r/test_mixed_filament.cpp +++ b/tests/libslic3r/test_mixed_filament.cpp @@ -2649,7 +2649,7 @@ TEST_CASE("MERGE-REGRESS-04: merge_mixed_filament marks source deleted and seria // [MixedFilament][Delete] — DELETE-PRIORITY resolution order tests // ============================================================================ -TEST_CASE("DELETE-PRIORITY-01: resolve-order — manual_pattern blocks pair/gradient check", "[MixedFilament][Delete]") +TEST_CASE("DELETE-PRIORITY-01: resolve-order - manual_pattern blocks pair/gradient check", "[MixedFilament][Delete]") { // Verify that when a mixed filament has a non-empty manual_pattern, the // component_a/component_b pair check and gradient check are skipped (both @@ -2819,7 +2819,7 @@ TEST_CASE("DELETE-GROUP-01: comma-separated group adjustment after deletion", "[ // [MixedFilament][Gradient] — GRAD-DEL regression tests // ============================================================================ -TEST_CASE("GRAD-DEL-01: gradient with partial component survival — matching ID removes entry", "[MixedFilament][Gradient]") +TEST_CASE("GRAD-DEL-01: gradient with partial component survival - matching ID removes entry", "[MixedFilament][Gradient]") { // Setup: 6 physical. Create a custom entry with gradient_component_ids="123" // (IDs 1, 2, 3). Delete physical #2. The gradient check (step 2 in @@ -2853,7 +2853,7 @@ TEST_CASE("GRAD-DEL-01: gradient with partial component survival — matching ID CHECK(gradient_entries == 0); } -TEST_CASE("GRAD-DEL-02: gradient partial survival — no matching component, IDs adjusted", "[MixedFilament][Gradient]") +TEST_CASE("GRAD-DEL-02: gradient partial survival - no matching component, IDs adjusted", "[MixedFilament][Gradient]") { // Setup: 6 physical. Create a custom entry with gradient_component_ids="345" // (IDs 3, 4, 5). Delete physical #2. None of the gradient IDs match #2,