Merge branch 'main' into feature/protobuf_config_and_dynamic_ui

This commit is contained in:
ExPikaPaka
2026-07-09 09:00:21 +02:00
committed by GitHub
75 changed files with 1649 additions and 331 deletions
+56 -37
View File
@@ -122,54 +122,73 @@ jobs:
arch: universal
macos-combine-only: true
secrets: inherit
unit_tests:
name: Unit Tests
# Tests are built on the aarch64 leg by default (faster GitHub arm runner),
# so run them there; self-hosted builds them on the amd64 server instead.
runs-on: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04-arm' }}
# One test job per built arch, on the runner that built it.
unit_tests_linux_x86_64:
name: Linux x86_64
needs: build_linux
if: ${{ !cancelled() && success() }}
uses: ./.github/workflows/unit_tests.yml
with:
os: ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}
artifact: ${{ github.sha }}-tests-linux-x86_64
unit_tests_linux_aarch64:
name: Linux aarch64
needs: build_linux
if: ${{ !cancelled() && success() }}
uses: ./.github/workflows/unit_tests.yml
with:
os: ubuntu-24.04-arm
artifact: ${{ github.sha }}-tests-linux-aarch64
unit_tests_windows_x64:
name: Windows x64
needs: build_windows
if: ${{ !cancelled() && success() }}
uses: ./.github/workflows/unit_tests.yml
with:
os: ${{ vars.SELF_HOSTED && 'orca-win-server' || 'windows-latest' }}
artifact: ${{ github.sha }}-tests-windows-x64
unit_tests_windows_arm64:
name: Windows arm64
needs: build_windows
if: ${{ !cancelled() && success() }}
uses: ./.github/workflows/unit_tests.yml
with:
os: windows-11-arm
artifact: ${{ github.sha }}-tests-windows-arm64
test-dir: build-arm64/tests
unit_tests_macos_arm64:
name: macOS arm64
needs: build_macos_arch
if: ${{ !cancelled() && success() }}
uses: ./.github/workflows/unit_tests.yml
with:
os: ${{ vars.SELF_HOSTED && 'orca-macos-arm64' || 'macos-14' }}
artifact: ${{ github.sha }}-tests-macos-arm64
test-dir: build/arm64/tests
publish_test_results:
name: Publish Test Results
needs: [unit_tests_linux_x86_64, unit_tests_linux_aarch64, unit_tests_windows_x64, unit_tests_windows_arm64, unit_tests_macos_arm64]
if: ${{ !cancelled() }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
with:
sparse-checkout: |
.github
scripts
tests
- name: Apt-Install Dependencies
if: ${{ !vars.SELF_HOSTED }}
uses: ./.github/actions/apt-install-deps
- name: Restore Test Artifact
- name: Download Test Results
uses: actions/download-artifact@v8
with:
name: ${{ github.sha }}-tests
- uses: lukka/get-cmake@latest
with:
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
useLocalCache: true # <--= Use the local cache (default is 'false').
useCloudCache: true
- name: Unpackage and Run Unit Tests
timeout-minutes: 20
run: |
tar -xvf build_tests.tar
scripts/run_unit_tests.sh
- name: Upload Test Logs
uses: actions/upload-artifact@v7
if: ${{ failure() }}
with:
name: unit-test-logs
path: build/tests/**/*.log
pattern: test-results-*
path: test-results
# Best-effort: a read-only token (e.g. fork PRs) can't write the check, so
# don't let a publish failure fail the run. The test jobs gate correctness.
- name: Publish Test Results
if: always()
continue-on-error: true
uses: EnricoMi/publish-unit-test-result-action@v2
with:
files: "ctest_results.xml"
- name: Delete Test Artifact
files: "test-results/**/*.xml"
- name: Delete Test Results
if: success()
uses: geekyeggo/delete-artifact@v6
with:
name: ${{ github.sha }}-tests
name: test-results-*
failOnError: false
flatpak:
name: "Flatpak"
container:
+43 -12
View File
@@ -160,8 +160,26 @@ jobs:
- name: Build slicer mac
if: runner.os == 'macOS' && !inputs.macos-combine-only
working-directory: ${{ github.workspace }}
# arm64 only: build the tests here; the unit_tests_macos job runs them.
env:
ORCA_TESTS_BUILD_ONLY: ${{ inputs.arch == 'arm64' && '1' || '' }}
run: |
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15
./build_release_macos.sh -s -n -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a ${{ inputs.arch }} -t 10.15 ${{ inputs.arch == 'arm64' && '-T' || '' }}
- name: Pack unit tests mac
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
working-directory: ${{ github.workspace }}
run: tar -cvf build_tests.tar build/arm64/tests
- name: Upload Test Artifact mac
if: runner.os == 'macOS' && !inputs.macos-combine-only && inputs.arch == 'arm64'
uses: actions/upload-artifact@v7
with:
name: ${{ github.sha }}-tests-macos-arm64
overwrite: true
path: build_tests.tar
retention-days: 5
if-no-files-found: error
- name: Pack macOS app bundle ${{ inputs.arch }}
if: runner.os == 'macOS' && !inputs.macos-combine-only
@@ -354,11 +372,28 @@ jobs:
# env:
# WindowsSdkDir: 'C:\Program Files (x86)\Windows Kits\10\'
# WindowsSDKVersion: '10.0.26100.0\'
# "tests" builds the unit tests too; the unit_tests_windows_* jobs run them.
run: |
$arch = "${{ inputs.arch }}"
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 } else { .\build_release_vs.bat slicer }
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 tests } else { .\build_release_vs.bat slicer tests }
shell: pwsh
- name: Pack unit tests Win
if: runner.os == 'Windows'
working-directory: ${{ github.workspace }}
shell: pwsh
run: tar -cvf build_tests.tar ${{ env.BUILD_DIR }}/tests
- name: Upload Test Artifact Win
if: runner.os == 'Windows'
uses: actions/upload-artifact@v7
with:
name: ${{ github.sha }}-tests-windows-${{ inputs.arch }}
overwrite: true
path: build_tests.tar
retention-days: 5
if-no-files-found: error
# NSIS is x86-only; it runs (and the installer it emits runs) under ARM64's
# x86 emulation, packaging the native arm64 payload from build-arm64.
- name: Create installer Win
@@ -471,26 +506,22 @@ jobs:
if: runner.os == 'Linux'
shell: bash
run: |
# Build + tar the unit tests (-t) only on the leg that runs them: the
# aarch64 leg by default (faster GitHub arm runner), or amd64 when using
# self-hosted runners (no arm self-hosted server). unit_tests downloads
# this tarball. The profile validator is built with -s, so amd64 keeps it.
tests=${{ (!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64') }}
if $tests; then flags=-istrlL; else flags=-isrlL; fi
./build_linux.sh "$flags"
# Build + tar the unit tests (-t) on both Linux legs so each arch
# (x86_64 + aarch64) gets tested by its own unit_tests_linux_* job.
./build_linux.sh -istrlL
./scripts/check_appimage_libs.sh ./build/package ./build/package/bin/orca-slicer
appimage=./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
mv -n ./build/OrcaSlicer_Linux_V${{ env.ver_pure }}.AppImage "$appimage"
chmod +x "$appimage"
if $tests; then tar -cvpf build_tests.tar build/tests; fi
tar -cvf build_tests.tar build/tests
# Use tar because upload-artifacts won't always preserve directory structure
# and doesn't preserve file permissions
- name: Upload Test Artifact
if: runner.os == 'Linux' && ((!vars.SELF_HOSTED && inputs.arch == 'aarch64') || (vars.SELF_HOSTED && inputs.arch != 'aarch64'))
if: runner.os == 'Linux'
uses: actions/upload-artifact@v7
with:
name: ${{ github.sha }}-tests
name: ${{ github.sha }}-tests-linux-${{ inputs.arch == 'aarch64' && 'aarch64' || 'x86_64' }}
overwrite: true
path: build_tests.tar
retention-days: 5
+1 -1
View File
@@ -27,7 +27,7 @@ jobs:
with:
prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
claude_args: "--model claude-sonnet-4-5-20250929"
model: "claude-sonnet-4-5-20250929"
claude_env: |
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+73
View File
@@ -0,0 +1,73 @@
name: Unit Tests
# Download a platform's test artifact, run ctest, and upload the JUnit
# results for aggregation. Called once per arch from build_all.yml.
on:
workflow_call:
inputs:
os:
required: true
type: string
artifact:
description: Test artifact uploaded by the build leg
required: true
type: string
test-dir:
description: Built tests dir; defaults to build/tests, override for arch-separated builds
required: false
type: string
default: build/tests
jobs:
unit_tests:
# Static "Unit Tests"; the per-arch label is the caller's job name, so the
# graph shows e.g. "Windows x64 / Unit Tests".
name: Unit Tests
runs-on: ${{ inputs.os }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
# tests/data is referenced by absolute path (TEST_DATA_DIR).
sparse-checkout: |
.github
scripts
tests
- name: Apt-Install Dependencies
if: runner.os == 'Linux' && !vars.SELF_HOSTED
uses: ./.github/actions/apt-install-deps
- name: Restore Test Artifact
uses: actions/download-artifact@v8
with:
name: ${{ inputs.artifact }}
- uses: lukka/get-cmake@latest
with:
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
useLocalCache: true
useCloudCache: true
- name: Unpackage and Run Unit Tests
timeout-minutes: 20
shell: bash
run: |
tar -xvf build_tests.tar
# Multi-config generators (Windows/macOS) need a config; Linux is single-config.
scripts/run_unit_tests.sh "${{ inputs.test-dir }}" "${{ runner.os != 'Linux' && 'Release' || '' }}"
- name: Upload Test Logs
if: ${{ failure() }}
uses: actions/upload-artifact@v7
with:
name: unit-test-logs-${{ inputs.artifact }}
path: ${{ inputs.test-dir }}/**/*.log
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v7
with:
name: test-results-${{ inputs.artifact }}
path: ctest_results.xml
retention-days: 5
if-no-files-found: warn
- name: Delete Test Artifact
if: success()
uses: geekyeggo/delete-artifact@v6
with:
name: ${{ inputs.artifact }}
+5 -8
View File
@@ -59,7 +59,7 @@ while getopts ":dpa:snt:xbc:i:1Tuh" opt; do
echo " -c: Set CMake build configuration, default is Release"
echo " -i: Add a prefix to ignore during CMake dependency discovery (repeatable), defaults to /opt/local:/usr/local:/opt/homebrew"
echo " -1: Use single job for building"
echo " -T: Build and run tests"
echo " -T: Build and run tests (set ORCA_TESTS_BUILD_ONLY=1 to build without running)"
exit 0
;;
* )
@@ -216,13 +216,10 @@ function build_slicer() {
cmake --build . --config "$BUILD_CONFIG" --target "$SLICER_BUILD_TARGET"
)
if [ "1." == "$BUILD_TESTS". ]; then
echo "Running tests for $_ARCH..."
(
set -x
cd "$PROJECT_BUILD_DIR"
ctest --build-config "$BUILD_CONFIG" --output-on-failure
)
# -T also runs the tests; ORCA_TESTS_BUILD_ONLY=1 builds them without
# running, so CI can build here and run them in a dedicated job.
if [ "1." == "$BUILD_TESTS". ] && [ "1." != "$ORCA_TESTS_BUILD_ONLY". ]; then
"$PROJECT_DIR/scripts/run_unit_tests.sh" "build/$_ARCH/tests" "$BUILD_CONFIG"
fi
echo "Verify localization with gettext..."
+8 -2
View File
@@ -20,6 +20,12 @@ for %%a in (%*) do (
if "%%a"=="-x" set USE_NINJA=1
)
@REM Check for unit-tests option ("tests")
set BUILD_TESTS=OFF
for %%a in (%*) do (
if /I "%%a"=="tests" set BUILD_TESTS=ON
)
if "%USE_NINJA%"=="1" (
echo Using Ninja Multi-Config generator
set CMAKE_GENERATOR="Ninja Multi-Config"
@@ -154,10 +160,10 @@ cd %build_dir%
echo on
set CMAKE_POLICY_VERSION_MINIMUM=3.5
if "%USE_NINJA%"=="1" (
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type%
cmake --build . --config %build_type% --target ALL_BUILD
) else (
cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DBUILD_TESTS=%BUILD_TESTS% -DCMAKE_BUILD_TYPE=%build_type%
cmake --build . --config %build_type% --target ALL_BUILD -- -m
)
@echo off
+24 -3
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:50-0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -325,6 +325,7 @@ msgstr ""
msgid "Optimize orientation"
msgstr ""
msgctxt "Verb"
msgid "Scale"
msgstr ""
@@ -368,6 +369,9 @@ msgstr ""
msgid "Object operations"
msgstr ""
msgid "Scale"
msgstr ""
msgid "Volume operations"
msgstr ""
@@ -413,6 +417,10 @@ msgstr ""
msgid "Reset current rotation to real zeros."
msgstr ""
msgctxt "Noun"
msgid "Scale"
msgstr ""
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr ""
@@ -3499,6 +3507,7 @@ msgstr ""
msgid "Save"
msgstr ""
msgctxt "Navigation"
msgid "Back"
msgstr ""
@@ -4781,6 +4790,7 @@ msgstr ""
msgid "Color change"
msgstr ""
msgctxt "Noun"
msgid "Print"
msgstr ""
@@ -4936,11 +4946,15 @@ msgstr ""
msgid "Align to Y axis"
msgstr ""
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr ""
msgctxt "Camera View"
msgid "Left"
msgstr ""
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr ""
@@ -5257,6 +5271,10 @@ msgstr ""
msgid "Export G-code file"
msgstr ""
msgctxt "Verb"
msgid "Print"
msgstr ""
msgid "Export plate sliced file"
msgstr ""
@@ -13920,6 +13938,9 @@ msgstr ""
msgid "Aligned back"
msgstr ""
msgid "Back"
msgstr ""
msgid "Random"
msgstr ""
+28 -8
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -332,6 +332,7 @@ msgstr "Gizmo-Rotació"
msgid "Optimize orientation"
msgstr "Optimitzar l'orientació"
msgctxt "Verb"
msgid "Scale"
msgstr "Escalar"
@@ -376,6 +377,9 @@ msgstr "Ràtios d'escala"
msgid "Object operations"
msgstr "Operacions amb objectes"
msgid "Scale"
msgstr "Escalar"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Operacions de volum"
@@ -427,6 +431,10 @@ msgstr "Restableix la rotació actual al valor d'quan s'ha obert l'eina de rotac
msgid "Reset current rotation to real zeros."
msgstr "Restableix la rotació actual a zeros reals."
msgctxt "Noun"
msgid "Scale"
msgstr "Escalar"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Mida"
@@ -3652,7 +3660,7 @@ msgstr "Calibratge completat. Trobeu la línia d'extrusió més uniforme al vost
msgid "Save"
msgstr "Desar"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Darrera"
@@ -5035,6 +5043,7 @@ msgstr "Canvis d'eina"
msgid "Color change"
msgstr "Canvi de color"
msgctxt "Noun"
msgid "Print"
msgstr "Imprimir"
@@ -5198,11 +5207,15 @@ msgstr "Evitar la regió de calibratge d'extrusió"
msgid "Align to Y axis"
msgstr "Alinear a l'eix Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Darrera"
msgctxt "Camera View"
msgid "Left"
msgstr "Esquerra"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Dreta"
@@ -5531,6 +5544,10 @@ msgstr "Imprimir placa d'impressió"
msgid "Export G-code file"
msgstr "Exportar el fitxer del Codi-G"
msgctxt "Verb"
msgid "Print"
msgstr "Imprimir"
msgid "Export plate sliced file"
msgstr "Exportar fitxer de la placa laminada"
@@ -14808,6 +14825,10 @@ msgstr "Alineat"
msgid "Aligned back"
msgstr "Alineat al darrere"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Darrera"
msgid "Random"
msgstr "Aleatori"
@@ -19647,6 +19668,9 @@ msgstr ""
"Evitar la deformació( warping )\n"
"Sabíeu que quan imprimiu materials propensos a deformar-se, com ara l'ABS, augmentar adequadament la temperatura del llit pot reduir la probabilitat de deformació?"
#~ msgid "Print"
#~ msgstr "Imprimir"
#~ msgid "in"
#~ msgstr "polç"
@@ -21103,10 +21127,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Desmarcar"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Escalar"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Forçar elevació Z"
+28 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Jakub Hencl\n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "Gizmo-Otočit"
msgid "Optimize orientation"
msgstr "Optimalizovat orientaci"
msgctxt "Verb"
msgid "Scale"
msgstr "Měřítko"
@@ -371,6 +372,9 @@ msgstr "Poměry měřítka"
msgid "Object operations"
msgstr "Operace s objektem"
msgid "Scale"
msgstr "Měřítko"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Operace s hlasitostí"
@@ -422,6 +426,10 @@ msgstr "Obnovit aktuální rotaci na hodnotu při otevření nástroje pro rotac
msgid "Reset current rotation to real zeros."
msgstr "Obnovit aktuální rotaci na skutečné nuly."
msgctxt "Noun"
msgid "Scale"
msgstr "Měřítko"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Velikost"
@@ -3651,7 +3659,7 @@ msgstr "Kalibrace byla dokončena. Najděte na vyhřívané podložce nejrovnom
msgid "Save"
msgstr "Uložit"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Zpět"
@@ -5032,6 +5040,7 @@ msgstr "Výměny nástrojů"
msgid "Color change"
msgstr "Změna barvy"
msgctxt "Noun"
msgid "Print"
msgstr "Tisk"
@@ -5195,11 +5204,15 @@ msgstr "Vyhněte se kalibrační oblasti extruze"
msgid "Align to Y axis"
msgstr "Zarovnat na osu Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Zpět"
msgctxt "Camera View"
msgid "Left"
msgstr "Levý"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Pravý"
@@ -5527,6 +5540,10 @@ msgstr "Tisková deska"
msgid "Export G-code file"
msgstr "Exportovat G-code soubor"
msgctxt "Verb"
msgid "Print"
msgstr "Tisk"
msgid "Export plate sliced file"
msgstr "Exportovat nařezaný soubor desky"
@@ -14855,6 +14872,10 @@ msgstr "Zarovnáno"
msgid "Aligned back"
msgstr "Zarovnat zpět"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Zpět"
msgid "Random"
msgstr "Náhodně"
@@ -19681,6 +19702,9 @@ msgstr ""
"Zamezte kroucení\n"
"Víte, že při tisku materiálů náchylných ke kroucení, jako je ABS, může vhodné zvýšení teploty vyhřívané desky snížit pravděpodobnost kroucení?"
#~ msgid "Print"
#~ msgstr "Tisk"
#~ msgid "in"
#~ msgstr "v"
+28 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "Gizmo-Drehen"
msgid "Optimize orientation"
msgstr "Optimiere Ausrichtung"
msgctxt "Verb"
msgid "Scale"
msgstr "Skalieren"
@@ -371,6 +372,9 @@ msgstr "Skalierungsverhältnisse"
msgid "Object operations"
msgstr "Objekt-Operationen"
msgid "Scale"
msgstr "Skalieren"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Volumen Operationen"
@@ -422,6 +426,10 @@ msgstr "Setze die aktuelle Rotation auf den Wert zurück, als das Rotationswerkz
msgid "Reset current rotation to real zeros."
msgstr "Setze die aktuelle Rotation auf die realen Nullen zurück."
msgctxt "Noun"
msgid "Scale"
msgstr "Skalieren"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Größe"
@@ -3654,7 +3662,7 @@ msgstr "Kalibrierung abgeschlossen. Bitte suchen Sie die gleichmäßigste Extrus
msgid "Save"
msgstr "Speichern"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Zurück"
@@ -5036,6 +5044,7 @@ msgstr "Werkzeugwechsel"
msgid "Color change"
msgstr "Farbwechsel"
msgctxt "Noun"
msgid "Print"
msgstr "aktuelle Platte drucken"
@@ -5199,11 +5208,15 @@ msgstr "Vermeiden Sie den Bereich der Extrusionskalibrierung"
msgid "Align to Y axis"
msgstr "An Y-Achse ausrichten"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Zurück"
msgctxt "Camera View"
msgid "Left"
msgstr "links"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "rechts"
@@ -5529,6 +5542,10 @@ msgstr "Aktuelle Platte drucken"
msgid "Export G-code file"
msgstr "G-Code als Datei exportieren"
msgctxt "Verb"
msgid "Print"
msgstr "aktuelle Platte drucken"
msgid "Export plate sliced file"
msgstr "Exportiere aktuelle Platte als STL Datei"
@@ -14962,6 +14979,10 @@ msgstr "Ausgerichtet"
msgid "Aligned back"
msgstr "Ausgerichtet hinten"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Zurück"
msgid "Random"
msgstr "Zufall"
@@ -19822,6 +19843,9 @@ msgstr ""
"Verwerfungen vermeiden\n"
"Wussten Sie, dass beim Drucken von Materialien, die zu Verwerfungen neigen, wie z.B. ABS, durch eine entsprechende Erhöhung der Heizbetttemperatur die Wahrscheinlichkeit von Verwerfungen verringert werden kann?"
#~ msgid "Print"
#~ msgstr "aktuelle Platte drucken"
#~ msgid "in"
#~ msgstr "in"
@@ -21730,10 +21754,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Abwählen"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Skalieren"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Z-Höhe einhalten"
+24 -3
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-06-17 15:44-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: \n"
@@ -321,6 +321,7 @@ msgstr ""
msgid "Optimize orientation"
msgstr ""
msgctxt "Verb"
msgid "Scale"
msgstr ""
@@ -364,6 +365,9 @@ msgstr ""
msgid "Object operations"
msgstr ""
msgid "Scale"
msgstr ""
msgid "Volume operations"
msgstr ""
@@ -409,6 +413,10 @@ msgstr ""
msgid "Reset current rotation to real zeros."
msgstr ""
msgctxt "Noun"
msgid "Scale"
msgstr ""
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr ""
@@ -3495,6 +3503,7 @@ msgstr ""
msgid "Save"
msgstr ""
msgctxt "Navigation"
msgid "Back"
msgstr ""
@@ -4777,6 +4786,7 @@ msgstr ""
msgid "Color change"
msgstr ""
msgctxt "Noun"
msgid "Print"
msgstr ""
@@ -4932,11 +4942,15 @@ msgstr ""
msgid "Align to Y axis"
msgstr ""
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr ""
msgctxt "Camera View"
msgid "Left"
msgstr ""
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr ""
@@ -5253,6 +5267,10 @@ msgstr ""
msgid "Export G-code file"
msgstr ""
msgctxt "Verb"
msgid "Print"
msgstr ""
msgid "Export plate sliced file"
msgstr ""
@@ -13916,6 +13934,9 @@ msgstr ""
msgid "Aligned back"
msgstr ""
msgid "Back"
msgstr ""
msgid "Random"
msgstr ""
+35 -15
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Ian A. Bassi <>\n"
"Language-Team: \n"
@@ -321,6 +321,7 @@ msgstr "Herramienta de rotación"
msgid "Optimize orientation"
msgstr "Optimizar orientación"
msgctxt "Verb"
msgid "Scale"
msgstr "Escalar"
@@ -332,7 +333,7 @@ msgstr "Error: Por favor, cierre primero todos los menús de la barra de herrami
msgctxt "inches"
msgid "in"
msgstr ""
msgstr "\""
msgid "mm"
msgstr "mm"
@@ -364,6 +365,9 @@ msgstr "Factor de escalado"
msgid "Object operations"
msgstr "Operaciones con objetos"
msgid "Scale"
msgstr "Escalar"
msgid "Volume operations"
msgstr "Operaciones de volumen"
@@ -409,6 +413,10 @@ msgstr "Restablecer la rotación actual al valor que tenía al abrir la herramie
msgid "Reset current rotation to real zeros."
msgstr "Restablecer la rotación actual a ceros reales."
msgctxt "Noun"
msgid "Scale"
msgstr "Escala"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Tamaño"
@@ -3580,6 +3588,7 @@ msgstr "Calibración completada. Por favor, observe cual es línea de extrusión
msgid "Save"
msgstr "Guardar"
msgctxt "Navigation"
msgid "Back"
msgstr "Atrás"
@@ -4709,7 +4718,7 @@ msgid "Support interface"
msgstr "Interfaz de soporte"
msgid "Prime tower"
msgstr "Torre de Purga"
msgstr "Torre de purga"
msgid "Bottom surface"
msgstr "Relleno sólido inferior"
@@ -4930,8 +4939,9 @@ msgstr "Cambios de herramienta"
msgid "Color change"
msgstr "Cambio de color"
msgctxt "Noun"
msgid "Print"
msgstr "Imprimir"
msgstr "Impresión"
msgid "Printer"
msgstr "Impresora"
@@ -5089,11 +5099,15 @@ msgstr "Evitar la zona de calibración del extrusor"
msgid "Align to Y axis"
msgstr "Alinear con el eje Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Posterior"
msgctxt "Camera View"
msgid "Left"
msgstr "Izquierda"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Derecha"
@@ -5416,6 +5430,10 @@ msgstr "Imprimir cama"
msgid "Export G-code file"
msgstr "Exportar archivo G-Code"
msgctxt "Verb"
msgid "Print"
msgstr "Imprimir"
msgid "Export plate sliced file"
msgstr "Exportar los objetos laminados de la cama a un archivo"
@@ -5488,10 +5506,10 @@ msgid "Front View"
msgstr "Vista frontal"
msgid "Rear"
msgstr "Trasera"
msgstr "Posterior"
msgid "Rear View"
msgstr "Vista trasera"
msgstr "Vista posterior"
msgid "Left View"
msgstr "Vista izquierda"
@@ -9190,7 +9208,7 @@ msgstr "Característica experimental: Retraer y cortar el filamento a mayor dist
msgid ""
"When recording timelapse without toolhead, it is recommended to add a \"Timelapse Wipe Tower\" \n"
"by right-click the empty position of build plate and choose \"Add Primitive\"->\"Timelapse Wipe Tower\"."
msgstr "Cuando se graba un timelapse sin cabezal, se recomienda añadir una \"Torre de Purga de Timelapse\" haciendo clic con el botón derecho del ratón en una posición vacía de la cama de impresión y seleccionando \"Añadir Primitivo\"->Torre de Purga de Timelapse\"."
msgstr "Cuando se graba un timelapse sin cabezal, se recomienda añadir una \"Torre de purga de Timelapse\" haciendo clic con el botón derecho del ratón en una posición vacía de la cama de impresión y seleccionando \"Añadir Primitivo\"->\"Torre de purga de Timelapse\"."
msgid "A copy of the current system preset will be created, which will be detached from the system preset."
msgstr "Se creará una copia de el perfil de sistema actual, que quedará separado del perfil de sistema."
@@ -10896,7 +10914,7 @@ msgid " is too close to clumping detection area, there may be collisions when pr
msgstr " está demasiado cerca del área de detección de aglomeraciones, puede haber colisiones durante la impresión."
msgid "Prime Tower"
msgstr "Torre de Purga"
msgstr "Torre de purga"
msgid " is too close to others, and collisions may be caused.\n"
msgstr " está demasiado cerca de otros, y se pueden producir colisiones.\n"
@@ -12750,7 +12768,7 @@ msgid "After a tool change, the exact position of the newly loaded filament insi
msgstr "Tras un cambio de cabezal, es posible que no se conozca la posición exacta del filamento recién cargado dentro de la boquilla y que la presión del filamento aún no sea estable. Antes de purgar el cabezal de impresión en un relleno o en un objeto de sacrificio, OrcaSlicer siempre cebará esta cantidad de material en la torre de purga para producir sucesivas extrusiones de relleno u objetos de sacrificio de forma fiable."
msgid "Wipe tower cooling"
msgstr "Refrigeración de Torre de Purga"
msgstr "Refrigeración de torre de purga"
msgid "Temperature drop before entering filament tower"
msgstr "Descenso de temperatura antes de entrar en la torre de filamentos"
@@ -14657,6 +14675,9 @@ msgstr "Alineado"
msgid "Aligned back"
msgstr "Alineado atrás"
msgid "Back"
msgstr "Atrás"
msgid "Random"
msgstr "Aleatorio"
@@ -19429,6 +19450,9 @@ msgstr ""
"Evita la deformación\n"
"¿Sabías que al imprimir materiales propensos a la deformación como el ABS, aumentar adecuadamente la temperatura de la cama térmica puede reducir la probabilidad de deformaciones?"
#~ msgid "Print"
#~ msgstr "Imprimir"
#~ msgid "in"
#~ msgstr "pulg"
@@ -21012,10 +21036,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Deseleccionar"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Escala"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Forzar elevación Z"
+27 -7
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: Guislain Cyril, Thomas Lété\n"
@@ -324,6 +324,7 @@ msgstr "Gizmo-Pivoter"
msgid "Optimize orientation"
msgstr "Optimiser l'orientation"
msgctxt "Verb"
msgid "Scale"
msgstr "Redimensionner"
@@ -367,6 +368,9 @@ msgstr "Rapports d'échelle"
msgid "Object operations"
msgstr "Opérations sur les objets"
msgid "Scale"
msgstr "Redimensionner"
msgid "Volume operations"
msgstr "Opérations sur les volumes"
@@ -412,6 +416,10 @@ msgstr "Réinitialiser la rotation actuelle à la valeur lors de l'ouverture de
msgid "Reset current rotation to real zeros."
msgstr "Réinitialiser la rotation actuelle à zéro."
msgctxt "Noun"
msgid "Scale"
msgstr "Redimensionner"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Taille"
@@ -3569,6 +3577,7 @@ msgstr "Calibrage terminé. Veuillez trouver la ligne d'extrusion la plus unifor
msgid "Save"
msgstr "Enregistrer"
msgctxt "Navigation"
msgid "Back"
msgstr "Arrière"
@@ -4916,6 +4925,7 @@ msgstr "Changements d’outil"
msgid "Color change"
msgstr "Changement de couleur"
msgctxt "Noun"
msgid "Print"
msgstr "Imprimer"
@@ -5075,11 +5085,15 @@ msgstr "Éviter la région de calibration de l'extrusion"
msgid "Align to Y axis"
msgstr "Aligner sur l’axe Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Arrière"
msgctxt "Camera View"
msgid "Left"
msgstr "Gauche"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Droite"
@@ -5402,6 +5416,10 @@ msgstr "Imprimer le plateau"
msgid "Export G-code file"
msgstr "Exporter le fichier G-code"
msgctxt "Verb"
msgid "Print"
msgstr "Imprimer"
msgid "Export plate sliced file"
msgstr "Exporter le fichier découpé du plateau"
@@ -14628,6 +14646,9 @@ msgstr "Alignée"
msgid "Aligned back"
msgstr "Aligné à l'arrière"
msgid "Back"
msgstr "Arrière"
msgid "Random"
msgstr "Aléatoire"
@@ -19397,6 +19418,9 @@ msgstr ""
"Éviter la déformation\n"
"Saviez-vous que lors de l’impression de matériaux susceptibles de se déformer, tels que l’ABS, une augmentation appropriée de la température du plateau chauffant peut réduire la probabilité de déformation?"
#~ msgid "Print"
#~ msgstr "Imprimer"
#~ msgid "in"
#~ msgstr "dans"
@@ -21107,10 +21131,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Désélectionner"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Redimensionner"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Exécution du décalage en Z"
+28 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -324,6 +324,7 @@ msgstr "Gizmo-Forgatás"
msgid "Optimize orientation"
msgstr "Orientáció optimalizálása"
msgctxt "Verb"
msgid "Scale"
msgstr "Átméretezés"
@@ -368,6 +369,9 @@ msgstr "Méretarányok"
msgid "Object operations"
msgstr "Objektum műveletek"
msgid "Scale"
msgstr "Átméretezés"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Térfogat műveletek"
@@ -419,6 +423,10 @@ msgstr "Az aktuális forgatás visszaállítása a forgatás eszköz megnyitása
msgid "Reset current rotation to real zeros."
msgstr "Az aktuális forgatás visszaállítása valódi nullára."
msgctxt "Noun"
msgid "Scale"
msgstr "Átméretezés"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Méret"
@@ -3645,7 +3653,7 @@ msgstr "A kalibrálás befejeződött. Kérlek, válaszd ki az alábbi képen l
msgid "Save"
msgstr "Mentés"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Hátul"
@@ -5026,6 +5034,7 @@ msgstr "Szerszámváltások"
msgid "Color change"
msgstr "Színváltás"
msgctxt "Noun"
msgid "Print"
msgstr "Nyomtatás"
@@ -5189,11 +5198,15 @@ msgstr "Extrudáláskalibráció környékének elkerülése"
msgid "Align to Y axis"
msgstr "Igazítás az Y-tengelyhez"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Hátul"
msgctxt "Camera View"
msgid "Left"
msgstr "Bal"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Jobb"
@@ -5521,6 +5534,10 @@ msgstr "Nyomtatótálca"
msgid "Export G-code file"
msgstr "G-kód fájl exportálása"
msgctxt "Verb"
msgid "Print"
msgstr "Nyomtatás"
msgid "Export plate sliced file"
msgstr "Szeletelt tálca exportálása"
@@ -14880,6 +14897,10 @@ msgstr "Igazított"
msgid "Aligned back"
msgstr "Hátulra igazítva"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Hátul"
msgid "Random"
msgstr "Véletlenszerû"
@@ -19712,6 +19733,9 @@ msgstr ""
"Kunkorodás elkerülése\n"
"Tudtad, hogy a kunkorodásra hajlamos anyagok (például ABS) nyomtatásakor a tárgyasztal hőmérsékletének növelése csökkentheti a kunkorodás valószínűségét?"
#~ msgid "Print"
#~ msgstr "Nyomtatás"
#~ msgid "in"
#~ msgstr "in"
+28 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "Strumento di rotazione"
msgid "Optimize orientation"
msgstr "Ottimizza orientamento"
msgctxt "Verb"
msgid "Scale"
msgstr "Ridimensiona"
@@ -371,6 +372,9 @@ msgstr "Rapporti di scala"
msgid "Object operations"
msgstr "Operazioni sugli oggetti"
msgid "Scale"
msgstr "Ridimensiona"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Operazioni volume"
@@ -422,6 +426,10 @@ msgstr "Reimposta la rotazione corrente al valore di apertura dello strumento."
msgid "Reset current rotation to real zeros."
msgstr "Reimposta la rotazione corrente a zero reale."
msgctxt "Noun"
msgid "Scale"
msgstr "Ridimensiona"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Dimensioni"
@@ -3646,7 +3654,7 @@ msgstr "Calibrazione completata. Trova la linea di estrusione più uniforme sul
msgid "Save"
msgstr "Salva"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Posteriore"
@@ -5027,6 +5035,7 @@ msgstr "Cambi testina"
msgid "Color change"
msgstr "Cambio colore"
msgctxt "Noun"
msgid "Print"
msgstr "Stampa"
@@ -5190,11 +5199,15 @@ msgstr "Evitare la regione di calibrazione dell'estrusione"
msgid "Align to Y axis"
msgstr "Allinea all'asse Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Posteriore"
msgctxt "Camera View"
msgid "Left"
msgstr "Sinistra"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Destra"
@@ -5522,6 +5535,10 @@ msgstr "Piatto di stampa"
msgid "Export G-code file"
msgstr "Esporta file G-code"
msgctxt "Verb"
msgid "Print"
msgstr "Stampa"
msgid "Export plate sliced file"
msgstr "Esporta il file del piatto elaborato"
@@ -14854,6 +14871,10 @@ msgstr "Allineato"
msgid "Aligned back"
msgstr "Allineato dietro"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Posteriore"
msgid "Random"
msgstr "Casuale"
@@ -19692,6 +19713,9 @@ msgstr ""
"Evita le deformazioni\n"
"Sapevi che quando si stampano materiali soggetti a deformazioni come l'ABS, aumentare in modo appropriato la temperatura del piano riscaldato può ridurre la probabilità di deformazione?"
#~ msgid "Print"
#~ msgstr "Stampa"
#~ msgid "in"
#~ msgstr "in"
@@ -21208,10 +21232,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Deseleziona"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Ridimensiona"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Applicazione dell'ascensore Z"
+28 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "ギズモ-回転"
msgid "Optimize orientation"
msgstr "向きを最適化"
msgctxt "Verb"
msgid "Scale"
msgstr "スケール"
@@ -371,6 +372,9 @@ msgstr "倍率"
msgid "Object operations"
msgstr "オブジェクト操作"
msgid "Scale"
msgstr "スケール"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "操作"
@@ -422,6 +426,10 @@ msgstr "回転ツールを開いた時の値にリセットします。"
msgid "Reset current rotation to real zeros."
msgstr "現在の回転を0にリセットします。"
msgctxt "Noun"
msgid "Scale"
msgstr "スケール"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "サイズ"
@@ -3629,7 +3637,7 @@ msgstr "キャリブレーションが完了しました。下の写真のよう
msgid "Save"
msgstr "保存"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "背面"
@@ -5000,6 +5008,7 @@ msgstr "ツールチェンジ"
msgid "Color change"
msgstr "色変更"
msgctxt "Noun"
msgid "Print"
msgstr "造形する"
@@ -5163,11 +5172,15 @@ msgstr "押出しキャリブレーション領域を避ける"
msgid "Align to Y axis"
msgstr "Y軸に整列"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "背面"
msgctxt "Camera View"
msgid "Left"
msgstr "左"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "右"
@@ -5489,6 +5502,10 @@ msgstr "造形開始"
msgid "Export G-code file"
msgstr "G-codeをエクスポート"
msgctxt "Verb"
msgid "Print"
msgstr "造形する"
msgid "Export plate sliced file"
msgstr "エクスポート"
@@ -14502,6 +14519,10 @@ msgstr "整列"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "背面"
msgid "Random"
msgstr "ランダム"
@@ -19160,6 +19181,9 @@ msgstr ""
"反りを避ける\n"
"ABSのような反りやすい素材を印刷する場合、ヒートベッドの温度を適切に上げることで、反りが発生する確率を下げることができることをご存知ですか?"
#~ msgid "Print"
#~ msgstr "造形する"
#~ msgid "in"
#~ msgstr "に"
@@ -20106,10 +20130,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "選択解除"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "スケール"
#~ msgid "Z-hop when retract"
#~ msgstr "リトラクト時にZ方向調整"
+28 -8
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
"Language-Team: \n"
@@ -331,6 +331,7 @@ msgstr "변형도구 - 회전"
msgid "Optimize orientation"
msgstr "방향 최적화"
msgctxt "Verb"
msgid "Scale"
msgstr "배율"
@@ -375,6 +376,9 @@ msgstr "배율비"
msgid "Object operations"
msgstr "객체 작업"
msgid "Scale"
msgstr "배율"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "용량 작업"
@@ -426,6 +430,10 @@ msgstr "회전 도구를 열었을 때의 값으로 현재 회전을 초기화
msgid "Reset current rotation to real zeros."
msgstr "현재 회전을 0으로 초기화합니다."
msgctxt "Noun"
msgid "Scale"
msgstr "배율"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "크기"
@@ -3644,7 +3652,7 @@ msgstr "교정이 완료되었습니다. 당신의 고온 베드에서 아래
msgid "Save"
msgstr "저장"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "뒷면"
@@ -5026,6 +5034,7 @@ msgstr ""
msgid "Color change"
msgstr "색 변경"
msgctxt "Noun"
msgid "Print"
msgstr "출력"
@@ -5189,11 +5198,15 @@ msgstr "압출 교정 영역을 피하세요"
msgid "Align to Y axis"
msgstr "Y축에 정렬"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "뒷면"
msgctxt "Camera View"
msgid "Left"
msgstr "왼쪽"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "오른쪽"
@@ -5517,6 +5530,10 @@ msgstr "플레이트 출력"
msgid "Export G-code file"
msgstr "Gcode 파일 내보내기"
msgctxt "Verb"
msgid "Print"
msgstr "출력"
msgid "Export plate sliced file"
msgstr "플레이트 슬라이스 파일 내보내기"
@@ -14720,6 +14737,10 @@ msgstr "정렬"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "뒷면"
msgid "Random"
msgstr "무작위"
@@ -19528,6 +19549,9 @@ msgstr ""
"뒤틀림 방지\n"
"ABS와 같이 뒤틀림이 발생하기 쉬운 소재를 출력할 때, 히트베드 온도를 적절하게 높이면 뒤틀림 가능성을 줄일 수 있다는 사실을 알고 계셨나요?"
#~ msgid "Print"
#~ msgstr "출력"
#~ msgid "in"
#~ msgstr "인치"
@@ -21019,10 +21043,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "선택 취소"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "규모"
#~ msgid "Lift Z Enforcement"
#~ msgstr "강제 Z 올리기"
+27 -3
View File
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-07-02 14:13+0300\n"
"Last-Translator: Gintaras Kučinskas <sharanchius@gmail.com>\n"
"Language-Team: \n"
@@ -326,6 +326,7 @@ msgstr "Manipuliatorius – Pasukimas"
msgid "Optimize orientation"
msgstr "Optimizuoti orientaciją"
msgctxt "Verb"
msgid "Scale"
msgstr "Mastelis"
@@ -369,6 +370,9 @@ msgstr "Mastelio koeficientai"
msgid "Object operations"
msgstr ""
msgid "Scale"
msgstr "Mastelis"
msgid "Volume operations"
msgstr ""
@@ -414,6 +418,10 @@ msgstr "Atkurti dabartinį pasukimą iki vertės, buvusios atidarius pasukimo į
msgid "Reset current rotation to real zeros."
msgstr "Atstatyti dabartinį sukimąsi į tikrąsias nulines vertes."
msgctxt "Noun"
msgid "Scale"
msgstr "Mastelis"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Dydis"
@@ -3576,6 +3584,7 @@ msgstr "Kalibravimas baigtas. Raskite tolygiausią ekstruzijos liniją ant kaiti
msgid "Save"
msgstr "Išsaugoti"
msgctxt "Navigation"
msgid "Back"
msgstr "Atgal"
@@ -4906,6 +4915,7 @@ msgstr "Įrankio keitimai"
msgid "Color change"
msgstr "Spalvos keitimas"
msgctxt "Noun"
msgid "Print"
msgstr "Spausdinti"
@@ -5069,11 +5079,15 @@ msgstr "Vengti ekstruzijos kalibravimo srities"
msgid "Align to Y axis"
msgstr "Išlygiuoti pagal Y ašį"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Atgal"
msgctxt "Camera View"
msgid "Left"
msgstr "Kairė"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Dešinė"
@@ -5396,6 +5410,10 @@ msgstr "Spausdinti plokštę"
msgid "Export G-code file"
msgstr "Eksportuoti G-kodo failą"
msgctxt "Verb"
msgid "Print"
msgstr "Spausdinti"
msgid "Export plate sliced file"
msgstr "Eksportuoti supjaustytos plokštės failą"
@@ -14604,6 +14622,9 @@ msgstr "Sulygiuota"
msgid "Aligned back"
msgstr "Sulygiuota gale"
msgid "Back"
msgstr "Atgal"
msgid "Random"
msgstr "Atsitiktinė"
@@ -19346,6 +19367,9 @@ msgstr ""
"Venkite deformacijų (warping)\n"
"Ar žinojote, kad spausdinant medžiagas, kurios yra linkusios trauktis ir riestis (pvz., ABS), tinkamas kaitinamojo pagrindo temperatūros padidinimas gali sumažinti deformacijų (warping) tikimybę?"
#~ msgid "Print"
#~ msgstr "Spausdinti"
#~ msgid "in"
#~ msgstr "col."
+25 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: \n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "Roteren"
msgid "Optimize orientation"
msgstr "Oriëntatie optimaliseren"
msgctxt "Verb"
msgid "Scale"
msgstr "Schalen"
@@ -371,6 +372,9 @@ msgstr "Schaalverhoudingen"
msgid "Object operations"
msgstr "Objectbewerkingen"
msgid "Scale"
msgstr "Schalen"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Volumebewerkingen"
@@ -422,6 +426,10 @@ msgstr ""
msgid "Reset current rotation to real zeros."
msgstr ""
msgctxt "Noun"
msgid "Scale"
msgstr "Schalen"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Maat"
@@ -3611,7 +3619,7 @@ msgstr "Kalibratie voltooid. Zoek de meest uniforme extrusielijn op uw hotbed, z
msgid "Save"
msgstr "Bewaar"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Achterzijde"
@@ -4971,6 +4979,7 @@ msgstr "Toolwisselingen"
msgid "Color change"
msgstr "Kleur veranderen"
msgctxt "Noun"
msgid "Print"
msgstr ""
@@ -5129,11 +5138,15 @@ msgstr "Vermijd het extrusie kalibratie gebied"
msgid "Align to Y axis"
msgstr "Uitlijnen op Y-as"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Achterzijde"
msgctxt "Camera View"
msgid "Left"
msgstr "Links"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Rechts"
@@ -5457,6 +5470,10 @@ msgstr "Printplaat"
msgid "Export G-code file"
msgstr "G-codebestand exporteren"
msgctxt "Verb"
msgid "Print"
msgstr ""
msgid "Export plate sliced file"
msgstr "Exporteer plate sliced bestand"
@@ -14427,6 +14444,10 @@ msgstr "Uitgelijnd"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Achterzijde"
msgid "Random"
msgstr "Willekeurig"
@@ -20321,10 +20342,6 @@ msgstr ""
#~ msgid "Thick bridges"
#~ msgstr "Dikke bruggen"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Schalen"
#~ msgid "Z-hop when retract"
#~ msgstr "Z-hop tijdens terugtrekken (retraction)"
+28 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: \n"
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
"Language-Team: \n"
@@ -329,6 +329,7 @@ msgstr "Uchwyt-Obróć"
msgid "Optimize orientation"
msgstr "Optymalizuj orientację"
msgctxt "Verb"
msgid "Scale"
msgstr "Skaluj"
@@ -373,6 +374,9 @@ msgstr "Współczynniki skali"
msgid "Object operations"
msgstr "Operacje na obiekcie"
msgid "Scale"
msgstr "Skaluj"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Operacje na objętości"
@@ -424,6 +428,10 @@ msgstr "Zresetuj bieżący obrót do wartości ustawionej przy otwarciu narzędz
msgid "Reset current rotation to real zeros."
msgstr "Zresetuj bieżący obrót do wartości zerowej."
msgctxt "Noun"
msgid "Scale"
msgstr "Skaluj"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Rozmiar"
@@ -3649,7 +3657,7 @@ msgstr "Kalibracja zakończona. Proszę znaleźć na płycie roboczej, linie eks
msgid "Save"
msgstr "Zapisz"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Tył"
@@ -5023,6 +5031,7 @@ msgstr "Zmiany narzędzi"
msgid "Color change"
msgstr "Zmiana koloru"
msgctxt "Noun"
msgid "Print"
msgstr "Drukuj"
@@ -5186,11 +5195,15 @@ msgstr "Unikaj obszaru kalibracji ekstruzji"
msgid "Align to Y axis"
msgstr "Wyrównaj do osi Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Tył"
msgctxt "Camera View"
msgid "Left"
msgstr "Lewy"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Prawy"
@@ -5518,6 +5531,10 @@ msgstr "Drukuj aktualną płytę"
msgid "Export G-code file"
msgstr "Eksportuj plik G-code"
msgctxt "Verb"
msgid "Print"
msgstr "Drukuj"
msgid "Export plate sliced file"
msgstr "Eksportuj plik pociętej płyty"
@@ -14738,6 +14755,10 @@ msgstr "Wyrównany"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Tył"
msgid "Random"
msgstr "Losowo"
@@ -19542,6 +19563,9 @@ msgstr ""
"Unikaj odkształceń\n"
"Czy wiesz, że podczas drukowania filamentami podatnymi na odkształcenia, takimi jak ABS, odpowiednie zwiększenie temperatury podgrzewanej płyty może zmniejszyć prawdopodobieństwo odkształceń?"
#~ msgid "Print"
#~ msgstr "Drukuj"
#~ msgid "in"
#~ msgstr "cal"
@@ -21000,10 +21024,6 @@ msgstr ""
#~ msgid "Unselect"
#~ msgstr "Odznacz"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Skala"
#~ msgid "Lift Z Enforcement"
#~ msgstr "Wymuszenie podniesienia osi Z"
+27 -3
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-07-04 11:51-0300\n"
"Last-Translator: Alexandre Folle de Menezes\n"
"Language-Team: Portuguese, Brazilian\n"
@@ -326,6 +326,7 @@ msgstr "Gizmo-Rotacionar"
msgid "Optimize orientation"
msgstr "Otimizar orientação"
msgctxt "Verb"
msgid "Scale"
msgstr "Escala"
@@ -369,6 +370,9 @@ msgstr "Proporções de escala"
msgid "Object operations"
msgstr "Operações de objeto"
msgid "Scale"
msgstr "Escala"
msgid "Volume operations"
msgstr "Operações de volume"
@@ -414,6 +418,10 @@ msgstr "Redefinir rotação para o valor de abertura da ferramenta de rotação.
msgid "Reset current rotation to real zeros."
msgstr "Redefinir rotação atual para zeros reais."
msgctxt "Noun"
msgid "Scale"
msgstr "Escala"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Tamanho"
@@ -3580,6 +3588,7 @@ msgstr "Calibração concluída. Por favor, encontre a linha de extrusão mais u
msgid "Save"
msgstr "Salvar"
msgctxt "Navigation"
msgid "Back"
msgstr "Atrás"
@@ -4940,6 +4949,7 @@ msgstr "Trocas de ferramenta"
msgid "Color change"
msgstr "Mudança de cor"
msgctxt "Noun"
msgid "Print"
msgstr "Imprimir"
@@ -5102,11 +5112,15 @@ msgstr "Evitar a região de calibração da extrusão"
msgid "Align to Y axis"
msgstr "Alinhar com o eixo Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Atrás"
msgctxt "Camera View"
msgid "Left"
msgstr "Esquerda"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Direita"
@@ -5433,6 +5447,10 @@ msgstr "Imprimir placa"
msgid "Export G-code file"
msgstr "Exportar arquivo G-code"
msgctxt "Verb"
msgid "Print"
msgstr "Imprimir"
msgid "Export plate sliced file"
msgstr "Exportar arquivo de placa fatiada"
@@ -14720,6 +14738,9 @@ msgstr "Alinhada"
msgid "Aligned back"
msgstr "Alinhada atrás"
msgid "Back"
msgstr "Atrás"
msgid "Random"
msgstr "Aleatória"
@@ -19489,6 +19510,9 @@ msgstr ""
"Evitar empenamento\n"
"Você sabia que ao imprimir materiais propensos ao empenamento como ABS, aumentar adequadamente a temperatura da mesa aquecida pode reduzir a probabilidade de empenamento?"
#~ msgid "Print"
#~ msgstr "Imprimir"
#~ msgid "in"
#~ msgstr "pol"
+29 -5
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: OrcaSlicer V2.5.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-02-25 13:38+0300\n"
"Last-Translator: Felix14_v2\n"
"Language-Team: Felix14_v2 (ДС/ТГ: @felix14_v2, почта: aleks111001@list.ru), Andylg <andylg@yandex.ru>\n"
@@ -337,6 +337,7 @@ msgstr "Инструмент вращения"
msgid "Optimize orientation"
msgstr "Оптимизация положения модели"
msgctxt "Verb"
msgid "Scale"
msgstr "Масштаб"
@@ -380,6 +381,9 @@ msgstr "Коэф. масштаба"
msgid "Object operations"
msgstr "Операции с моделями"
msgid "Scale"
msgstr "Масштаб"
msgid "Volume operations"
msgstr "Булевы операции с телами"
@@ -425,6 +429,10 @@ msgstr "Сбросить последние изменения ориентац
msgid "Reset current rotation to real zeros."
msgstr "Сбросить ориентацию до изначальной"
msgctxt "Noun"
msgid "Scale"
msgstr "Масштаб"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Размер"
@@ -3657,9 +3665,9 @@ msgstr "Калибровка завершена. Теперь найдите н
msgid "Save"
msgstr "Сохранить"
# Используется в нескольких местах: в 2 местах в значении расположения (шва и камеры), в одном – на кнопке "назад" (калибровка бамбу)
msgctxt "Navigation"
msgid "Back"
msgstr "Сзади"
msgstr "Назад"
msgid "Example"
msgstr "Пример"
@@ -5065,6 +5073,7 @@ msgstr "Смена инструмента"
msgid "Color change"
msgstr "Смена цвета"
msgctxt "Noun"
msgid "Print"
msgstr "Печать"
@@ -5227,11 +5236,15 @@ msgstr "Избегать зону калибровки экструзии"
msgid "Align to Y axis"
msgstr "Выравнивать по оси Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Сзади"
msgctxt "Camera View"
msgid "Left"
msgstr "Слева"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Справа"
@@ -5589,6 +5602,10 @@ msgstr "Распечатать стол"
msgid "Export G-code file"
msgstr "Экспорт в G-код"
msgctxt "Verb"
msgid "Print"
msgstr "Печать"
msgid "Export plate sliced file"
msgstr "Экспорт стола в файл проекта"
@@ -15086,6 +15103,10 @@ msgstr "В углах"
msgid "Aligned back"
msgstr "В углах сзади"
# Используется в нескольких местах: в 2 местах в значении расположения (шва и камеры), в одном – на кнопке "назад" (калибровка бамбу)
msgid "Back"
msgstr "Сзади"
msgid "Random"
msgstr "Случайная"
@@ -20096,6 +20117,9 @@ msgstr ""
"Предотвращение коробления материала\n"
"Знаете ли вы, что при печати материалами, склонными к короблению, таких как ABS, повышение температуры подогреваемого стола может снизить эту вероятность?"
#~ msgid "Print"
#~ msgstr "Печать"
#~ msgid "in"
#~ msgstr "дюйм"
+28 -8
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"Language: sv\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -324,6 +324,7 @@ msgstr ""
msgid "Optimize orientation"
msgstr "Optimisera placering"
msgctxt "Verb"
msgid "Scale"
msgstr "Skala"
@@ -368,6 +369,9 @@ msgstr "Skalnings förhållande"
msgid "Object operations"
msgstr "Objekt Åtgärder"
msgid "Scale"
msgstr "Skala"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Volym Åtgärder"
@@ -418,6 +422,10 @@ msgstr ""
msgid "Reset current rotation to real zeros."
msgstr ""
msgctxt "Noun"
msgid "Scale"
msgstr "Skala"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Storlek"
@@ -3603,7 +3611,7 @@ msgstr "Kalibreringen klar. Vänligen hitta den mest enhetliga extruderingslinje
msgid "Save"
msgstr "Spara"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Tillbaka"
@@ -4961,6 +4969,7 @@ msgstr ""
msgid "Color change"
msgstr "Färg byte"
msgctxt "Noun"
msgid "Print"
msgstr "Skriv ut"
@@ -5120,11 +5129,15 @@ msgstr "Undvik kalibrerings området"
msgid "Align to Y axis"
msgstr "Justera mot Y-axeln"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Tillbaka"
msgctxt "Camera View"
msgid "Left"
msgstr "Vänster"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Höger"
@@ -5448,6 +5461,10 @@ msgstr "Skriv ut byggplattan"
msgid "Export G-code file"
msgstr "Exportera G-kod filen"
msgctxt "Verb"
msgid "Print"
msgstr "Skriv ut"
msgid "Export plate sliced file"
msgstr "Exportera byggplattans beredda fil"
@@ -14400,6 +14417,10 @@ msgstr "Linjerad"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Tillbaka"
msgid "Random"
msgstr "Slumpmässig"
@@ -19055,6 +19076,9 @@ msgstr ""
"Undvik vridning\n"
"Visste du att när du skriver ut material som är benägna att vrida, såsom ABS, kan en lämplig ökning av värmebäddens temperatur minska sannolikheten för vridning?"
#~ msgid "Print"
#~ msgstr "Skriv ut"
#~ msgid "in"
#~ msgstr "i"
@@ -20228,10 +20252,6 @@ msgstr ""
#~ msgid "Thick bridges"
#~ msgstr "Tjocka bridges"
#~ msgctxt "Verb"
#~ msgid "Scale"
#~ msgstr "Skala"
#~ msgid "Z-hop when retract"
#~ msgstr "Z-hopp vid retraktion"
+27 -3
View File
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-06-19 13:40+0700\n"
"Last-Translator: Icezaza\n"
"Language-Team: Thai\n"
@@ -324,6 +324,7 @@ msgstr "Gizmo-หมุน"
msgid "Optimize orientation"
msgstr "ปรับการวางแนวให้เหมาะสม"
msgctxt "Verb"
msgid "Scale"
msgstr "ปรับขนาด"
@@ -367,6 +368,9 @@ msgstr "อัตราส่วนการปรับขนาด"
msgid "Object operations"
msgstr "การทำงานกับวัตถุ"
msgid "Scale"
msgstr "ปรับขนาด"
msgid "Volume operations"
msgstr "การทำงานกับวอลลุ่ม"
@@ -412,6 +416,10 @@ msgstr "รีเซ็ตการหมุนปัจจุบันเป็
msgid "Reset current rotation to real zeros."
msgstr "รีเซ็ตการหมุนปัจจุบันให้เป็นศูนย์จริง"
msgctxt "Noun"
msgid "Scale"
msgstr "ปรับขนาด"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "ขนาด"
@@ -3559,6 +3567,7 @@ msgstr "การสอบเทียบเสร็จสิ้น โปร
msgid "Save"
msgstr "บันทึก"
msgctxt "Navigation"
msgid "Back"
msgstr "กลับ"
@@ -4907,6 +4916,7 @@ msgstr "การเปลี่ยนแปลงเครื่องมือ
msgid "Color change"
msgstr "เปลี่ยนสี"
msgctxt "Noun"
msgid "Print"
msgstr "พิมพ์"
@@ -5066,11 +5076,15 @@ msgstr "หลีกเลี่ยงบริเวณการสอบเท
msgid "Align to Y axis"
msgstr "จัดแนวตามแกน Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "กลับ"
msgctxt "Camera View"
msgid "Left"
msgstr "ซ้าย"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "ขวา"
@@ -5393,6 +5407,10 @@ msgstr "พิมพ์ฐานพิมพ์"
msgid "Export G-code file"
msgstr "ส่งออกไฟล์ G-code"
msgctxt "Verb"
msgid "Print"
msgstr "พิมพ์"
msgid "Export plate sliced file"
msgstr "ส่งออกไฟล์แผ่นสไลซ์บาง ๆ"
@@ -14591,6 +14609,9 @@ msgstr "จัดตำแหน่ง"
msgid "Aligned back"
msgstr "จัดแนวกลับ"
msgid "Back"
msgstr "กลับ"
msgid "Random"
msgstr "สุ่ม"
@@ -19345,6 +19366,9 @@ msgstr ""
"หลีกเลี่ยงการบิดเบี้ยว\n"
"คุณรู้หรือไม่ว่าเมื่อพิมพ์วัสดุที่มีแนวโน้มที่จะเกิดการบิดเบี้ยว เช่น ABS การเพิ่มอุณหภูมิฐานพิมพ์อย่างเหมาะสมสามารถลดความน่าจะเป็นของการบิดเบี้ยวได้"
#~ msgid "Print"
#~ msgstr "พิมพ์"
#~ msgid "in"
#~ msgstr "นิ้ว"
+28 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-04-08 23:59+0300\n"
"Last-Translator: GlauTech\n"
"Language-Team: \n"
@@ -327,6 +327,7 @@ msgstr "Gizmo-Döndür"
msgid "Optimize orientation"
msgstr "Yönü optimize edin"
msgctxt "Verb"
msgid "Scale"
msgstr "Ölçeklendir"
@@ -371,6 +372,9 @@ msgstr "Ölçek oranları"
msgid "Object operations"
msgstr "Nesne İşlemleri"
msgid "Scale"
msgstr "Ölçeklendir"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Hacim İşlemleri"
@@ -422,6 +426,10 @@ msgstr "Döndürme aracını açtığınızda mevcut döndürme değerini sıfı
msgid "Reset current rotation to real zeros."
msgstr "Mevcut dönüşü gerçek sıfırlara sıfırla."
msgctxt "Noun"
msgid "Scale"
msgstr "Ölçeklendir"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Boyut"
@@ -3644,7 +3652,7 @@ msgstr "Kalibrasyon tamamlandı. Lütfen sıcak yatağınızdaki en düzgün eks
msgid "Save"
msgstr "Kaydet"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Arka"
@@ -5027,6 +5035,7 @@ msgstr "Takım değişiklikleri"
msgid "Color change"
msgstr "Renk değişimi"
msgctxt "Noun"
msgid "Print"
msgstr "Yazdır"
@@ -5190,11 +5199,15 @@ msgstr "Ekstrüzyon kalibrasyon bölgesinden kaçın"
msgid "Align to Y axis"
msgstr "Y eksenine hizala"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Arka"
msgctxt "Camera View"
msgid "Left"
msgstr "Sol"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Sağ"
@@ -5522,6 +5535,10 @@ msgstr "Plakayı Yazdır"
msgid "Export G-code file"
msgstr "G-kod dosyasını dışa aktar"
msgctxt "Verb"
msgid "Print"
msgstr "Yazdır"
msgid "Export plate sliced file"
msgstr "Dilimlenmiş plaka dosyasını dışa aktar"
@@ -14776,6 +14793,10 @@ msgstr "Hizalı"
msgid "Aligned back"
msgstr "Arkaya hizalı"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Arka"
msgid "Random"
msgstr "Rastgele"
@@ -19610,6 +19631,9 @@ msgstr ""
"Eğilmeyi önleyin\n"
"ABS gibi bükülmeye yatkın malzemelere baskı yaparken, ısıtma yatağı sıcaklığının uygun şekilde arttırılmasının bükülme olasılığını azaltabileceğini biliyor muydunuz?"
#~ msgid "Print"
#~ msgstr "Yazdır"
#~ msgid "in"
#~ msgstr "in"
+28 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: orcaslicerua\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2025-03-07 09:30+0200\n"
"Last-Translator: \n"
"Language-Team: Ukrainian\n"
@@ -332,6 +332,7 @@ msgstr "Gizmo обертання"
msgid "Optimize orientation"
msgstr "Оптимізувати орієнтацію"
msgctxt "Verb"
msgid "Scale"
msgstr "Масштаб"
@@ -376,6 +377,9 @@ msgstr "Коефіцієнти масштабування"
msgid "Object operations"
msgstr "Операції з об'єктами"
msgid "Scale"
msgstr "Масштаб"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Операції з об’ємом"
@@ -427,6 +431,10 @@ msgstr "Скинути поточне обертання до значення
msgid "Reset current rotation to real zeros."
msgstr "Скинути поточне обертання до нульових значень."
msgctxt "Noun"
msgid "Scale"
msgstr "Масштаб"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Розмір"
@@ -3660,7 +3668,7 @@ msgstr "Калібрування завершено. Тепер знайдіть
msgid "Save"
msgstr "Зберегти"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Ззаду"
@@ -5030,6 +5038,7 @@ msgstr "Зміна інструменту"
msgid "Color change"
msgstr "Зміна кольору"
msgctxt "Noun"
msgid "Print"
msgstr "Друк"
@@ -5191,11 +5200,15 @@ msgstr "Уникайте області калібрування екструз
msgid "Align to Y axis"
msgstr "Розташувати вздовж осі Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Ззаду"
msgctxt "Camera View"
msgid "Left"
msgstr "Ліво"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Право"
@@ -5523,6 +5536,10 @@ msgstr "Друкувати пластину"
msgid "Export G-code file"
msgstr "Експорт файлу G-коду"
msgctxt "Verb"
msgid "Print"
msgstr "Друк"
msgid "Export plate sliced file"
msgstr "Експортувати файл нарізки пластини"
@@ -14753,6 +14770,10 @@ msgstr "Вирівняне"
msgid "Aligned back"
msgstr ""
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Ззаду"
msgid "Random"
msgstr "Випадкове"
@@ -19554,6 +19575,9 @@ msgstr ""
"Уникнення деформації\n"
"Чи знаєте ви, що при друку матеріалами, схильними до деформації, такими як ABS, відповідне підвищення температури гарячого ліжка може зменшити ймовірність деформації?"
#~ msgid "Print"
#~ msgstr "Друк"
#~ msgid "in"
#~ msgstr "в"
+28 -4
View File
@@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
"Last-Translator: \n"
"Language-Team: hainguyen.ts13@gmail.com\n"
@@ -328,6 +328,7 @@ msgstr "Gizmo - Xoay"
msgid "Optimize orientation"
msgstr "Tối ưu định hướng"
msgctxt "Verb"
msgid "Scale"
msgstr "Tỷ lệ"
@@ -372,6 +373,9 @@ msgstr "Tỷ lệ co giãn"
msgid "Object operations"
msgstr "Thao tác vật thể"
msgid "Scale"
msgstr "Tỷ lệ"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "Thao tác thể tích"
@@ -423,6 +427,10 @@ msgstr "Đặt lại xoay hiện tại về giá trị khi mở công cụ xoay.
msgid "Reset current rotation to real zeros."
msgstr "Đặt lại xoay hiện tại về số không thực."
msgctxt "Noun"
msgid "Scale"
msgstr "Tỷ lệ"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "Kích thước"
@@ -3630,7 +3638,7 @@ msgstr "Hiệu chỉnh hoàn tất. Vui lòng tìm đường đùn đồng đề
msgid "Save"
msgstr "Lưu"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "Sau"
@@ -5001,6 +5009,7 @@ msgstr ""
msgid "Color change"
msgstr "Đổi màu"
msgctxt "Noun"
msgid "Print"
msgstr "In"
@@ -5162,11 +5171,15 @@ msgstr "Tránh vùng hiệu chỉnh đùn"
msgid "Align to Y axis"
msgstr "Căn theo trục Y"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "Sau"
msgctxt "Camera View"
msgid "Left"
msgstr "Trái"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "Phải"
@@ -5490,6 +5503,10 @@ msgstr "In plate"
msgid "Export G-code file"
msgstr "Xuất file G-code"
msgctxt "Verb"
msgid "Print"
msgstr "In"
msgid "Export plate sliced file"
msgstr "Xuất file plate đã slice"
@@ -14668,6 +14685,10 @@ msgstr "Căn chỉnh"
msgid "Aligned back"
msgstr "Căn chỉnh sau"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "Sau"
msgid "Random"
msgstr "Ngẫu nhiên"
@@ -19475,6 +19496,9 @@ msgstr ""
"Tránh cong vênh\n"
"Bạn có biết rằng khi in vật liệu dễ cong vênh như ABS, tăng nhiệt độ bàn nóng một cách thích hợp có thể giảm xác suất cong vênh không?"
#~ msgid "Print"
#~ msgstr "In"
#~ msgid "in"
#~ msgstr "in"
+28 -4
View File
@@ -6,7 +6,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Slic3rPE\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
"Last-Translator: Handle <mail@bysb.net>\n"
"Language-Team: \n"
@@ -330,6 +330,7 @@ msgstr "Gizmo-旋转"
msgid "Optimize orientation"
msgstr "优化朝向"
msgctxt "Verb"
msgid "Scale"
msgstr "缩放"
@@ -374,6 +375,9 @@ msgstr "缩放比例"
msgid "Object operations"
msgstr "对象操作"
msgid "Scale"
msgstr "缩放"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "零件操作"
@@ -425,6 +429,10 @@ msgstr "重置当前旋转为打开旋转工具时的值"
msgid "Reset current rotation to real zeros."
msgstr "重置当前旋转为真实零位"
msgctxt "Noun"
msgid "Scale"
msgstr "缩放"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "大小"
@@ -3639,7 +3647,7 @@ msgstr "校准完成。如下图中的示例,请在您的热床上找到最均
msgid "Save"
msgstr "保存"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "背面"
@@ -5014,6 +5022,7 @@ msgstr "工具更换"
msgid "Color change"
msgstr "颜色更换"
msgctxt "Noun"
msgid "Print"
msgstr "打印"
@@ -5178,11 +5187,15 @@ msgstr "避开挤出校准区域"
msgid "Align to Y axis"
msgstr "对齐到Y轴"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "背面"
msgctxt "Camera View"
msgid "Left"
msgstr "左"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "右"
@@ -5510,6 +5523,10 @@ msgstr "打印单盘"
msgid "Export G-code file"
msgstr "导出G-code文件"
msgctxt "Verb"
msgid "Print"
msgstr "打印"
msgid "Export plate sliced file"
msgstr "导出单盘切片文件"
@@ -14896,6 +14913,10 @@ msgstr "对齐"
msgid "Aligned back"
msgstr "背部对齐"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "背面"
msgid "Random"
msgstr "随机"
@@ -19737,6 +19758,9 @@ msgstr ""
"避免翘曲\n"
"您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。"
#~ msgid "Print"
#~ msgstr "打印"
#~ msgid "in"
#~ msgstr "在"
+28 -4
View File
@@ -9,7 +9,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Orca Slicer\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-07-07 10:05-0300\n"
"POT-Creation-Date: 2026-07-07 16:46-0300\n"
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
"Language-Team: \n"
@@ -333,6 +333,7 @@ msgstr "Gizmo-旋轉"
msgid "Optimize orientation"
msgstr "最佳化方向"
msgctxt "Verb"
msgid "Scale"
msgstr "縮放"
@@ -377,6 +378,9 @@ msgstr "縮放比例"
msgid "Object operations"
msgstr "物件操作"
msgid "Scale"
msgstr "縮放"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Volume operations"
msgstr "零件操作"
@@ -428,6 +432,10 @@ msgstr "重設旋轉角度為開啟旋轉工具時的狀態。"
msgid "Reset current rotation to real zeros."
msgstr "將旋轉角度歸零"
msgctxt "Noun"
msgid "Scale"
msgstr "縮放"
#. TRN - Input label. Be short as possible
msgid "Size"
msgstr "尺寸"
@@ -3650,7 +3658,7 @@ msgstr "校正完成。如下圖中的範例,請在您的熱床上找到最均
msgid "Save"
msgstr "儲存"
# TODO: Review, changed by lang refactor. PR 14254
msgctxt "Navigation"
msgid "Back"
msgstr "背面"
@@ -5056,6 +5064,7 @@ msgstr "取代工具"
msgid "Color change"
msgstr "顏色更換"
msgctxt "Noun"
msgid "Print"
msgstr "列印"
@@ -5220,11 +5229,15 @@ msgstr "避開擠出校正區域"
msgid "Align to Y axis"
msgstr "與 Y 軸對齊"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Back"
msgstr "背面"
msgctxt "Camera View"
msgid "Left"
msgstr "左"
msgctxt "Camera"
msgctxt "Camera View"
msgid "Right"
msgstr "右"
@@ -5553,6 +5566,10 @@ msgstr "列印單一列印板"
msgid "Export G-code file"
msgstr "匯出 G-code 檔案"
msgctxt "Verb"
msgid "Print"
msgstr "列印"
msgid "Export plate sliced file"
msgstr "匯出單一列印板切片檔案"
@@ -14957,6 +14974,10 @@ msgstr "對齊"
msgid "Aligned back"
msgstr "背部對齊"
# TODO: Review, changed by lang refactor. PR 14254
msgid "Back"
msgstr "背面"
msgid "Random"
msgstr "隨機"
@@ -19808,6 +19829,9 @@ msgstr ""
"您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度\n"
"可以降低翹曲的機率。"
#~ msgid "Print"
#~ msgstr "列印"
#~ msgid "in"
#~ msgstr "在"
+11 -1
View File
@@ -4,11 +4,21 @@
# It should only require the directories build/tests, scripts/, and tests/ to function,
# and cmake (with ctest) installed.
# (otherwise, update the workflow too, but try to avoid to keep things self-contained)
#
# Usage: run_unit_tests.sh [TEST_DIR] [BUILD_CONFIG]
# TEST_DIR directory containing the built tests (default: build/tests)
# BUILD_CONFIG configuration to run; required for multi-config generators
# (Windows/macOS), harmless/omitted for single-config (Linux).
ROOT_DIR="$(dirname "$0")/.."
cd "${ROOT_DIR}" || exit 1
TEST_DIR="${1:-build/tests}"
BUILD_CONFIG="${2:-}"
# Run the whole suite, excluding tests tagged [NotWorking].
# --no-tests=error fails the job if the filter matches nothing (instead of passing green).
ctest --test-dir build/tests -LE "NotWorking" --no-tests=error --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j
args=(--test-dir "${TEST_DIR}" -LE "NotWorking" --no-tests=error --output-junit "$(pwd)/ctest_results.xml" --output-on-failure -j)
[ -n "${BUILD_CONFIG}" ] && args+=(--build-config "${BUILD_CONFIG}")
ctest "${args[@]}"
+1 -1
View File
@@ -7359,7 +7359,7 @@ bool CLI::export_project(Model *model, std::string& path, PlateDataPtrs &partpla
bool success = false;
StoreParams store_params;
store_params.path = path.c_str();
store_params.path = path;
store_params.model = model;
store_params.plate_data_list = partplate_data;
store_params.project_presets = project_presets;
@@ -1660,7 +1660,7 @@ void SkeletalTrapezoidation::propagateBeadingsDownward(edge_t* edge_to_peak, ptr
}
SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius) const
SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius)
{
assert(ratio_left_to_whole >= 0.0 && ratio_left_to_whole <= 1.0);
Beading ret = interpolate(left, ratio_left_to_whole, right);
@@ -1684,6 +1684,12 @@ SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beadin
{ // We cant adjust to fit the next edge because there is no previous one?!
return ret;
}
// ret follows the thicker of left/right, which can hold fewer insets than left when bead
// count and thickness disagree; skip the adjustment rather than index ret past its end.
if (next_inset_idx >= coord_t(ret.toolpath_locations.size()))
{
return ret;
}
assert(next_inset_idx < coord_t(left.toolpath_locations.size()));
assert(left.toolpath_locations[next_inset_idx] <= switching_radius);
assert(left.toolpath_locations[next_inset_idx + 1] >= switching_radius);
@@ -1703,7 +1709,7 @@ SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beadin
}
SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right) const
SkeletalTrapezoidation::Beading SkeletalTrapezoidation::interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right)
{
assert(ratio_left_to_whole >= 0.0 && ratio_left_to_whole <= 1.0);
float ratio_right_to_whole = 1.0 - ratio_left_to_whole;
@@ -488,7 +488,7 @@ protected:
* beads.
* \return The beading at the interpolated location.
*/
Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius) const;
static Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right, coord_t switching_radius);
/*!
* Subroutine of \ref interpolate(const Beading&, Ratio, const Beading&, coord_t)
@@ -501,7 +501,7 @@ protected:
* \param right One of the beadings to interpolate between.
* \return The beading at the interpolated location.
*/
Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right) const;
static Beading interpolate(const Beading& left, double ratio_left_to_whole, const Beading& right);
/*!
* Get the beading at a certain node of the skeletal graph, or create one if
+1
View File
@@ -221,6 +221,7 @@ set(lisbslic3r_sources
GCode/FanMover.hpp
GCode/GCodeProcessor.cpp
GCode/GCodeProcessor.hpp
GCode/ElegooGCodeProcessorHelper.cpp
GCode.hpp
GCode/PchipInterpolatorHelper.cpp
GCode/PchipInterpolatorHelper.hpp
+12
View File
@@ -188,6 +188,18 @@ ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta)
return results;
}
ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta, Clipper2Lib::JoinType joinType)
{
Clipper2Lib::Paths64 subject = Slic3rExPolygons_to_Paths64(expolygons);
Clipper2Lib::ClipperOffset offsetter;
offsetter.AddPaths(subject, joinType, Clipper2Lib::EndType::Polygon);
Clipper2Lib::PolyPath64 polytree;
offsetter.Execute(delta, polytree);
ExPolygons results = PolyTreeToExPolygons(std::move(polytree));
return results;
}
ExPolygons offset2_ex_2(const ExPolygons& expolygons, double delta1, double delta2)
{
// 1st offset
+1
View File
@@ -15,6 +15,7 @@ Slic3r::Polylines diff_pl_2(const Slic3r::Polylines& subject, const Slic3r::Pol
ExPolygons union_ex_2(const Polygons &expolygons);
ExPolygons union_ex_2(const ExPolygons &expolygons);
ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta);
ExPolygons offset_ex_2(const ExPolygons &expolygons, double delta, Clipper2Lib::JoinType joinType);
ExPolygons offset2_ex_2(const ExPolygons &expolygons, double delta1, double delta2);
}
+90 -2
View File
@@ -272,6 +272,10 @@ struct SurfaceFillParams
// For Gyroid: when true, use the parameterized "optimized" wave.
bool gyroid_optimized = false;
bool anisotropic_surfaces{false};
CenterOfSurfacePattern center_of_surface_pattern{CenterOfSurfacePattern::Each_Surface};
bool separated_infills{false};
bool operator<(const SurfaceFillParams &rhs) const {
#define RETURN_COMPARE_NON_EQUAL(KEY) if (this->KEY < rhs.KEY) return true; if (this->KEY > rhs.KEY) return false;
#define RETURN_COMPARE_NON_EQUAL_TYPED(TYPE, KEY) if (TYPE(this->KEY) < TYPE(rhs.KEY)) return true; if (TYPE(this->KEY) > TYPE(rhs.KEY)) return false;
@@ -301,8 +305,12 @@ struct SurfaceFillParams
RETURN_COMPARE_NON_EQUAL(lateral_lattice_angle_2);
RETURN_COMPARE_NON_EQUAL(symmetric_infill_y_axis);
RETURN_COMPARE_NON_EQUAL(infill_lock_depth);
RETURN_COMPARE_NON_EQUAL(skin_infill_depth); RETURN_COMPARE_NON_EQUAL(infill_overhang_angle);
RETURN_COMPARE_NON_EQUAL(skin_infill_depth);
RETURN_COMPARE_NON_EQUAL(infill_overhang_angle);
RETURN_COMPARE_NON_EQUAL(gyroid_optimized);
RETURN_COMPARE_NON_EQUAL(anisotropic_surfaces);
RETURN_COMPARE_NON_EQUAL(center_of_surface_pattern);
RETURN_COMPARE_NON_EQUAL(separated_infills);
return false;
}
@@ -329,6 +337,9 @@ struct SurfaceFillParams
this->infill_lock_depth == rhs.infill_lock_depth &&
this->skin_infill_depth == rhs.skin_infill_depth &&
this->infill_overhang_angle == rhs.infill_overhang_angle &&
this->anisotropic_surfaces == rhs.anisotropic_surfaces &&
this->center_of_surface_pattern == rhs.center_of_surface_pattern &&
this->separated_infills == rhs.separated_infills &&
this->gyroid_optimized == rhs.gyroid_optimized;
}
};
@@ -868,6 +879,9 @@ std::vector<SurfaceFill> group_fills(const Layer &layer, LockRegionParam &lock_p
params.lateral_lattice_angle_1 = region_config.lateral_lattice_angle_1;
params.lateral_lattice_angle_2 = region_config.lateral_lattice_angle_2;
params.infill_overhang_angle = region_config.infill_overhang_angle;
params.anisotropic_surfaces = region_config.anisotropic_surfaces;
params.center_of_surface_pattern = region_config.center_of_surface_pattern;
params.separated_infills = region_config.separated_infills;
if (params.pattern == ipLockedZag) {
params.infill_lock_depth = scale_(region_config.infill_lock_depth);
params.skin_infill_depth = scale_(region_config.skin_infill_depth);
@@ -1309,6 +1323,22 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
params.config = &region_config;
params.pattern = surface_fill.params.pattern;
// Orca: Checking the filling of a centered surface by drawing for each model parts
bool is_top_or_bottom = params.extrusion_role == erTopSolidInfill || params.extrusion_role == erBottomSurface;
bool is_centered_infill = surface_fill.params.pattern == ipArchimedeanChords || surface_fill.params.pattern == ipOctagramSpiral;
if (is_top_or_bottom) {
params.is_anisotropic = surface_fill.params.anisotropic_surfaces; // Orca: anisotropic surfaces
params.center_of_surface_pattern = surface_fill.params.center_of_surface_pattern; // Orca: center of surface pattern
}
// Orca: Each_Model centers the pattern on each model part's bbox; Each_Surface / Each_Assembly
// fall through to the default (whole-object) bounding box below.
bool is_per_model_center = is_top_or_bottom && params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Model && is_centered_infill;
bool is_separate_infill = !is_top_or_bottom && surface_fill.params.separated_infills &&
(
is_centered_infill ||
params.config->solid_infill_rotate_template != "" ||
params.config->sparse_infill_rotate_template != "" );
if( surface_fill.params.pattern == ipLockedZag ) {
params.locked_zag = true;
params.infill_lock_depth = surface_fill.params.infill_lock_depth;
@@ -1332,7 +1362,65 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
params.can_reverse = false;
for (ExPolygon& expoly : surface_fill.expolygons) {
f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes);
// Orca: separate infill / per-model pattern centering.
//
// First assign this fill region to the model part whose slice at this layer overlaps it
// the most. A strict "contains" test is ambiguous for assemblies whose parts overlap (a
// region may sit inside several parts, or straddle a boundary and be inside none), so we
// pick by intersection area instead.
//
// The center must belong to an *overlap group*, not a single part: parts that
// touch/overlap form one connected physical body that shares a single center, while a
// part detached from the rest of the assembly gets its own. This holds for both
// separated infills and Each_Model surface centering (Each_Model == per connected body).
// firstLayerObjGroups() already holds these connected components, so we widen the chosen
// part's bbox to the whole group it belongs to.
if (is_per_model_center || is_separate_infill) {
double best_overlap = 0.;
ObjectID best_vol_id;
const PrintInstance* best_instance = nullptr;
for (const auto& instance : this->object()->instances()) {
for (const auto& volume : instance.print_object->firstLayerObjSlice()) {
if (f->layer_id >= volume.slices.size())
continue;
const double overlap = area(intersection_ex(volume.slices[f->layer_id], ExPolygons{expoly}));
if (overlap > best_overlap) {
best_overlap = overlap;
best_vol_id = volume.volume_id;
best_instance = &instance;
}
}
}
if (best_instance) {
const Transform3d matrix = best_instance->model_instance->get_matrix();
Point shift = best_instance->shift; // get_volume_bbox takes a non-const ref
auto& volumes = best_instance->model_instance->get_object()->volumes;
// Volume ids to center on: the whole overlap group the winning part belongs to,
// falling back to just that part if it isn't part of any group.
std::vector<ObjectID> center_ids;
for (const auto& group : best_instance->print_object->firstLayerObjGroups()) {
bool in_group = false;
for (const ObjectID& vid : group.volume_ids)
if (vid == best_vol_id) { in_group = true; break; }
if (in_group) { center_ids = group.volume_ids; break; }
}
if (center_ids.empty())
center_ids.push_back(best_vol_id);
BoundingBox bbox;
for (const ObjectID& vid : center_ids)
for (auto model_volume : volumes)
if (vid.id == model_volume->id().id) {
bbox.merge(model_volume->get_volume_bbox(matrix, shift, true));
break;
}
if (bbox.defined)
f->set_bounding_box(bbox);
}
} // - End: separate infill / per-model pattern centering
f->no_overlap_expolygons = intersection_ex(surface_fill.no_overlap_expolygons, ExPolygons() = {expoly}, ApplySafetyOffset::Yes);
if (params.symmetric_infill_y_axis) {
params.symmetric_y_axis = f->extended_object_bounding_box().center().x();
expoly.symmetric_y(params.symmetric_y_axis);
+3 -2
View File
@@ -165,7 +165,7 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para
// ORCA: special flag for flow rate calibration
auto is_flow_calib = params.extrusion_role == erTopSolidInfill && this->print_object_config->has("calib_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool();
if (is_flow_calib) {
if (is_flow_calib || params.is_anisotropic) { // Orca: disable sorting while anisotropic surfaces
eec->no_sort = true;
}
size_t idx = eec->entities.size();
@@ -186,7 +186,8 @@ void Fill::fill_surface_extrusion(const Surface* surface, const FillParams& para
}
// Orca: run gap fill
this->_create_gap_fill(surface, params, eec);
if (!(params.is_anisotropic)) // Orca: Disable gap filling while anisotropic
this->_create_gap_fill(surface, params, eec);
}
}
+2
View File
@@ -106,6 +106,8 @@ struct FillParams
bool locked_zag{false};
float infill_lock_depth{0.0};
float skin_infill_depth{0.0};
bool is_anisotropic{false};
CenterOfSurfacePattern center_of_surface_pattern{CenterOfSurfacePattern::Each_Surface};
};
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
+54 -36
View File
@@ -77,20 +77,24 @@ void FillPlanePath::_fill_surface_single(
//FIXME Vojtech: We are not sure whether the user expects the fill patterns on visible surfaces to be aligned across all the islands of a single layer.
// One may align for this->centered() to align the patterns for Archimedean Chords and Octagram Spiral patterns.
const bool align = params.density < 0.995;
// Orca: the old implementation became obsolete when it became possible to change the density of the top and bottom surfaces
bool align = params.extrusion_role == ExtrusionRole::erInternalInfill;
BoundingBox bounding_box;
BoundingBox snug_bounding_box = get_extents(expolygon).inflated(SCALED_EPSILON);
// Expand the bounding box to avoid artifacts at the edges
snug_bounding_box.offset(scale_(this->spacing)*params.multiline);
snug_bounding_box.offset(scale_(this->spacing)*params.multiline);
// Rotated bounding box of the area to fill in with the pattern.
BoundingBox bounding_box = align ?
// Sparse infill needs to be aligned across layers. Align infill across layers using the object's bounding box.
this->bounding_box.rotated(-direction.first) :
// Solid infill does not need to be aligned across layers, generate the infill pattern
// around the clipping expolygon only.
snug_bounding_box;
// Sparse infill (or Internal where align == true) needs to be aligned across layers. Align infill across layers using the object's bounding box.
// Solid infill does not need to be aligned across layers, generate the infill pattern around the clipping expolygon only.
if (align)
bounding_box = this->bounding_box.rotated(-direction.first);
else if (params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Surface)
bounding_box = snug_bounding_box;
else if (params.center_of_surface_pattern == CenterOfSurfacePattern::Each_Model)
bounding_box = this->bounding_box.rotated(-direction.first);
else
bounding_box = extended_object_bounding_box();
Point shift = this->centered() ?
bounding_box.center() :
@@ -129,35 +133,49 @@ void FillPlanePath::_fill_surface_single(
polylines = intersection_pl(std::move(polylines), expolygon);
if (!polylines.empty()) {
Polylines chained;
if (params.dont_connect() || params.density > 0.5) {
// ORCA: special flag for flow rate calibration
auto is_flow_calib = params.extrusion_role == erTopSolidInfill &&
this->print_object_config->has("calib_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() &&
dynamic_cast<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out
// Find the center spiral line first, by looking for the longest one
auto it = std::max_element(polylines.begin(), polylines.end(),
[](const Polyline& a, const Polyline& b) { return a.length() < b.length(); });
Polyline center_spiral = std::move(*it);
if (!params.is_anisotropic) { // Orca: not anisotropic surface
if ((params.dont_connect() || params.density > 0.5)) {
// ORCA: special flag for flow rate calibration
auto is_flow_calib = params.extrusion_role == erTopSolidInfill &&
this->print_object_config->has("calib_flowrate_topinfill_special_order") &&
this->print_object_config->option("calib_flowrate_topinfill_special_order")->getBool() &&
dynamic_cast<FillArchimedeanChords*>(this);
if (is_flow_calib) {
// We want the spiral part to be printed inside-out
// Find the center spiral line first, by looking for the longest one
auto it = std::max_element(polylines.begin(), polylines.end(),
[](const Polyline& a, const Polyline& b) { return a.length() < b.length(); });
Polyline center_spiral = std::move(*it);
// Ensure the spiral is printed from inside to out
if (center_spiral.first_point().squaredNorm() > center_spiral.last_point().squaredNorm()) {
center_spiral.reverse();
// Ensure the spiral is printed from inside to out
if ((center_spiral.first_point().squaredNorm() > center_spiral.last_point().squaredNorm())) {
center_spiral.reverse();
}
// Chain the other polylines
polylines.erase(it);
chained = chain_polylines(std::move(polylines), nullptr);
// Then add the center spiral back
chained.push_back(std::move(center_spiral));
} else {
chained = chain_polylines(std::move(polylines), nullptr);
}
// Chain the other polylines
polylines.erase(it);
chained = chain_polylines(std::move(polylines));
// Then add the center spiral back
chained.push_back(std::move(center_spiral));
} else {
chained = chain_polylines(std::move(polylines));
} else
connect_infill(std::move(polylines), expolygon, chained, this->spacing, params);
} else { // Orca: anisotropic surface
const Point _center(0., 0.);
for (Polyline& segment : polylines) { // sort paths by its direction
if (segment.size() > 1) { // need at least two points to evaluate direction
if (segment.first_point().ccw(segment.points[1], _center) < 0)
segment.reverse();
}
chained.emplace_back(std::move(segment));
}
} else
connect_infill(std::move(polylines), expolygon, chained, this->spacing, params);
std::sort(chained.begin(), chained.end(), [&_center](const Polyline& a, const Polyline& b) { // just sort polylines from center to outside
return a.distance_to(_center) < b.distance_to(_center);
});
}
// paths must be repositioned and rotated back
for (Polyline& pl : chained) {
pl.translate(shift.x(), shift.y());
+2 -2
View File
@@ -5949,7 +5949,7 @@ void PlateData::parse_filament_info(GCodeProcessorResult *result)
m_thumbnail_middle = iter->second;
}
boost::system::error_code ec;
std::string filename = std::string(store_params.path);
std::string filename = store_params.path;
boost::filesystem::remove(filename + ".tmp", ec);
bool result = _save_model_to_file(filename + ".tmp", *store_params.model, store_params.plate_data_list, store_params.project_presets, store_params.config,
@@ -8988,7 +8988,7 @@ bool store_bbs_3mf(StoreParams& store_params)
// All export should use "C" locales for number formatting.
CNumericLocalesSetter locales_setter;
if (store_params.path == nullptr || store_params.model == nullptr)
if (store_params.path.empty() || store_params.model == nullptr)
return false;
_BBS_3MF_Exporter exporter;
+1 -1
View File
@@ -226,7 +226,7 @@ typedef std::map<int, PlateData*> PlateDataMaps;
struct StoreParams
{
const char* path;
std::string path;
Model* model = nullptr;
PlateDataPtrs plate_data_list;
int export_plate_idx = -1;
+2 -1
View File
@@ -6215,7 +6215,8 @@ std::string GCode::extrude_support(const ExtrusionEntityCollection &support_fill
static constexpr const char* support_transition_label = "support transition";
static constexpr const char* support_ironing_label = "support ironing";
static const auto speed_for_path = [&](double length, ExtrusionRole role, double default_speed = -1.0) {
// Not static: it captures `this` by reference.
const auto speed_for_path = [&](double length, ExtrusionRole role, double default_speed = -1.0) {
if (!is_support(role) || length > SMALL_PERIMETER_LENGTH(NOZZLE_CONFIG(small_support_perimeter_threshold)))
return default_speed;
@@ -0,0 +1,190 @@
#include "GCodeProcessor.hpp"
#include "libslic3r/libslic3r.h"
#include <algorithm>
#include <cctype>
#include <cmath>
#include <string_view>
namespace Slic3r {
namespace {
bool equals_case_insensitive(std::string_view lhs, std::string_view rhs)
{
return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin(), [](unsigned char l, unsigned char r) {
return std::tolower(l) == std::tolower(r);
});
}
float get_clamped_param(const GCodeReader::GCodeLine& line, char axis, float default_value, float min_value, float max_value)
{
float value = default_value;
line.has_value(axis, value);
return std::clamp(value, min_value, max_value);
}
float extrusion_time(float e_length, float feedrate)
{
return feedrate > 0.0f && e_length > 0.0f ? e_length / feedrate * 60.0f : 0.0f;
}
float retract_time(float e_length)
{
static constexpr float retract_feedrate = 1800.0f;
return extrusion_time(std::max(e_length, 0.0f), retract_feedrate);
}
float s819_time(float e_length, float feedrate)
{
static constexpr float s819_tail_flush_length = 10.0f;
static constexpr float s819_tail_feedrate = 400.0f;
const float tail_length = std::min(std::max(e_length, 0.0f), s819_tail_flush_length);
const float main_length = std::max(e_length - tail_length, 0.0f);
return extrusion_time(main_length, feedrate) + extrusion_time(tail_length, s819_tail_feedrate);
}
float estimate_M6211_time_for_centauri_carbon(const GCodeReader::GCodeLine& line, float length, double current_x,
double current_y)
{
static constexpr float max_segment_length = 73.0f;
static constexpr float wipe_after_flush_time = 2.8f;
static constexpr float main_feedrate = 500.0f;
static constexpr float tail_feedrate = 400.0f;
static constexpr float travel_feedrate = 5000.0f;
static constexpr double parking_x = 256.0;
static constexpr double parking_y = 0.0;
const float flush_length = std::clamp(length, 10.0f, 1000.0f);
const float cool_time = get_clamped_param(line, 'P', 5000.0f, 0.0f, 20000.0f) * 0.001f;
const float travel_time = static_cast<float>(std::abs(current_y - parking_y) + std::abs(current_x - parking_x)) /
travel_feedrate * 60.0f;
// Initial time, including: material change, heating, etc.
float m6211_time = 18.2f + travel_time;
float remaining_flush_length = std::max(flush_length, 0.0f);
while (remaining_flush_length > 0.0f) {
const float segment_length = std::min(remaining_flush_length, max_segment_length);
remaining_flush_length -= segment_length;
if (segment_length >= max_segment_length) {
// Full segment: 3-phase extrusion (30+35+10=75mm) + retract
m6211_time += extrusion_time(30.0f, main_feedrate) + extrusion_time(35.0f, main_feedrate) +
extrusion_time(10.0f, tail_feedrate) + extrusion_time(2.0f, tail_feedrate) + cool_time +
wipe_after_flush_time;
} else {
// Partial last segment: simple extrude at F500 + retract at F400
m6211_time += extrusion_time(segment_length, main_feedrate) + extrusion_time(2.0f, tail_feedrate) + cool_time +
wipe_after_flush_time;
}
}
return m6211_time;
}
float estimate_M6211_time_for_centauri_carbon_2(const GCodeReader::GCodeLine& line, float length, float new_extruder_temp)
{
const float flush_length = std::clamp(length, 10.0f, 1000.0f);
const float flush_length_single = get_clamped_param(line, 'K', 75.0f, 10.0f, 300.0f);
const float old_filament_e_feedrate = get_clamped_param(line, 'M', 300.0f, 10.0f, 600.0f);
const float new_filament_e_feedrate = get_clamped_param(line, 'N', 300.0f, 10.0f, 600.0f);
const float cool_time = get_clamped_param(line, 'P', 3000.0f, 0.0f, 20000.0f) * 0.001f;
// The flush length of the old material, unit: mm
static constexpr float e_flush_dist = 15.0f;
// Wipe time after flush, in seconds
static constexpr float wipe_after_flush_time = 5.0f;
const float flush_length_after_start = std::max(flush_length - e_flush_dist, 0.0f);
const int flush_times = std::max(1, static_cast<int>(std::ceil(flush_length_after_start / flush_length_single)));
const float flush_length_actual = flush_length_single;
// Initial time, including: material change, heating, moving, etc.
float m6211_time = 31.0f;
m6211_time += extrusion_time(std::min(e_flush_dist, flush_length), old_filament_e_feedrate);
const int intermediate_flush_times = flush_times - 1;
const float intermediate_flush_time = s819_time(flush_length_actual, new_filament_e_feedrate) + retract_time(6.0f) + cool_time +
wipe_after_flush_time;
m6211_time += static_cast<float>(intermediate_flush_times) * intermediate_flush_time;
m6211_time += s819_time(flush_length_actual, new_filament_e_feedrate * 0.8f) + retract_time(4.0f) + cool_time + wipe_after_flush_time;
static constexpr float cooling_rate = 1.36f;
const float r_temp = get_clamped_param(line, 'R', new_extruder_temp + 20.0f, 185.0f, 350.0f);
const float s_temp = get_clamped_param(line, 'S', 250.0f, 185.0f, 350.0f);
if (s_temp < r_temp)
m6211_time += (r_temp - s_temp) / cooling_rate;
return m6211_time;
}
float estimate_M6211_time(const GCodeReader::GCodeLine& line, std::string_view printer_model, float length, float new_extruder_temp, double current_x, double current_y)
{
if (equals_case_insensitive(printer_model, "Elegoo Centauri Carbon") || equals_case_insensitive(printer_model, "Elegoo Centauri")) {
return estimate_M6211_time_for_centauri_carbon(line, length, current_x, current_y);
} else if (equals_case_insensitive(printer_model, "Elegoo Centauri Carbon 2") ||
equals_case_insensitive(printer_model, "Elegoo Centauri 2")) {
return estimate_M6211_time_for_centauri_carbon_2(line, length, new_extruder_temp);
}
return 0.0f;
}
} // namespace
void GCodeProcessor::process_elegoo_M6211(const GCodeReader::GCodeLine& line)
{
float length = 0.0f;
if (!line.has_value('L', length) || length <= 0.0f)
return;
float t = -1.0f;
if (!line.has_value('T', t) || t < 0.0f)
return;
const int filament_id = static_cast<int>(std::round(t));
if (filament_id < 0 || filament_id >= m_result.filaments_count)
return;
const int extruder_id = m_filament_maps[filament_id];
float new_extruder_temp = 0.0f;
if (line.has_value('S', new_extruder_temp)) {
if (extruder_id >= 0 && static_cast<size_t>(extruder_id) < m_extruder_temps.size())
m_extruder_temps[static_cast<size_t>(extruder_id)] = new_extruder_temp;
}
const float m6211_time = estimate_M6211_time(line, m_printer_model, length, new_extruder_temp,
m_start_position[X], m_start_position[Y]);
const int curr_filament_id = get_filament_id(false);
const bool is_first_extrusion = (curr_filament_id == -1) || (filament_id == curr_filament_id);
m_time_processor.filament_unload_times = 0;
m_time_processor.filament_load_times = m6211_time;
process_filament_change(filament_id);
if (extruder_id >= 0 && static_cast<size_t>(extruder_id) < m_remaining_volume.size()) {
const float remaining_volume = static_cast<size_t>(extruder_id) < m_nozzle_volume.size() ?
m_nozzle_volume[extruder_id] :
0.0f;
const float filament_diameter = static_cast<size_t>(filament_id) < m_result.filament_diameters.size() ?
m_result.filament_diameters[filament_id] :
m_result.filament_diameters.back();
const float area_filament_cross_section = static_cast<float>(M_PI) * sqr(0.5f * filament_diameter);
const float volume_flushed_filament = area_filament_cross_section * length;
if (volume_flushed_filament >= remaining_volume) {
if (!is_first_extrusion)
m_used_filaments.update_flush_per_filament(curr_filament_id, remaining_volume);
m_used_filaments.update_flush_per_filament(filament_id, volume_flushed_filament - remaining_volume);
m_remaining_volume[extruder_id] = 0.0f;
} else {
m_used_filaments.update_flush_per_filament(filament_id, volume_flushed_filament);
m_remaining_volume[extruder_id] -= volume_flushed_filament;
}
}
}
} // namespace Slic3r
+13 -1
View File
@@ -1839,7 +1839,8 @@ void GCodeProcessor::register_commands()
{"VM104", [this](const GCodeReader::GCodeLine& line) { process_VM104(line); }},
{"VM109", [this](const GCodeReader::GCodeLine& line) { process_VM109(line); }},
{"M622", [this](const GCodeReader::GCodeLine& line) { process_M622(line);}},
{"M623", [this](const GCodeReader::GCodeLine& line) { process_M623(line);}}
{"M623", [this](const GCodeReader::GCodeLine& line) { process_M623(line);}},
{"M6211", [this](const GCodeReader::GCodeLine& line) { process_M6211(line); }}
};
std::unordered_set<std::string>early_quit_commands = {
@@ -1863,6 +1864,12 @@ void GCodeProcessor::register_commands()
}
}
void GCodeProcessor::process_M6211(const GCodeReader::GCodeLine& line)
{
if (boost::algorithm::istarts_with(m_printer_model, "elegoo"))
process_elegoo_M6211(line);
}
bool GCodeProcessor::check_multi_extruder_gcode_valid(const int extruder_size,
const Pointfs plate_printable_area,
const double plate_printable_height,
@@ -2027,6 +2034,7 @@ void GCodeProcessor::apply_config(const PrintConfig& config)
m_parser.apply_config(config);
m_flavor = config.gcode_flavor;
m_printer_model = config.printer_model.value;
m_single_extruder_multi_material = config.single_extruder_multi_material;
@@ -2213,6 +2221,10 @@ void GCodeProcessor::apply_config(const DynamicPrintConfig& config)
if (printer_settings_id != nullptr)
m_result.settings_ids.printer = printer_settings_id->value;
const ConfigOptionString* printer_model = config.option<ConfigOptionString>("printer_model");
if (printer_model != nullptr)
m_printer_model = printer_model->value;
// BBS
m_result.filaments_count = config.option<ConfigOptionFloats>("filament_diameter")->values.size();
+5
View File
@@ -846,6 +846,7 @@ class Print;
float m_preheat_time;
int m_preheat_steps;
bool m_disable_m73;
std::string m_printer_model;
enum class EProducer
{
@@ -1084,6 +1085,10 @@ class Print;
// Unload the current filament into the MK3 MMU2 unit at the end of print.
void process_M702(const GCodeReader::GCodeLine& line);
//Used for Elegoo printer to change tool head
void process_M6211(const GCodeReader::GCodeLine& line);
void process_elegoo_M6211(const GCodeReader::GCodeLine& line);
void process_SYNC(const GCodeReader::GCodeLine& line);
// Processes T line (Select Tool)
+60 -17
View File
@@ -187,6 +187,10 @@ static void apply_first_layer_order(const DynamicPrintConfig* config, std::vecto
void ToolOrdering::handle_dontcare_extruder(const std::vector<unsigned int>& tool_order_layer0)
{
const PrintConfig* print_config = m_print_config_ptr;
if (!print_config && m_print_object_ptr)
print_config = &m_print_object_ptr->print()->config();
if(m_layer_tools.empty() || tool_order_layer0.empty())
return;
@@ -221,6 +225,8 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector<unsigned int>& too
for (int i = 1; i < m_layer_tools.size(); i++) {
LayerTools& lt = m_layer_tools[i];
// Extruders in lt.extruders are already sorted.
if (lt.extruders.empty())
continue;
if (lt.extruders.size() == 1 && lt.extruders.front() == 0)
@@ -229,14 +235,23 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector<unsigned int>& too
if (lt.extruders.front() == 0)
// Pop the "don't care" extruder, the "don't care" region will be merged with the next one.
lt.extruders.erase(lt.extruders.begin());
// Reorder the extruders to start with the last one.
for (size_t i = 1; i < lt.extruders.size(); ++i)
if (lt.extruders[i] == last_extruder_id) {
// Move the last extruder to the front.
memmove(lt.extruders.data() + 1, lt.extruders.data(), i * sizeof(unsigned int));
lt.extruders.front() = last_extruder_id;
break;
if (print_config == nullptr
|| print_config->toolchange_ordering == ToolChangeOrderingType::Default)
{
// Reorder the extruders to start with the last one.
for (size_t i = 1; i < lt.extruders.size(); ++i) {
if (lt.extruders[i] == last_extruder_id) {
// Move the last extruder to the front.
std::rotate(
lt.extruders.begin(),
lt.extruders.begin() + i,
lt.extruders.begin() + i + 1
);
break;
}
}
}
}
last_extruder_id = lt.extruders.back();
}
@@ -252,6 +267,10 @@ void ToolOrdering::handle_dontcare_extruder(const std::vector<unsigned int>& too
void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id)
{
const PrintConfig* print_config = m_print_config_ptr;
if (!print_config && m_print_object_ptr)
print_config = &m_print_object_ptr->print()->config();
if(m_layer_tools.empty())
return;
if(last_extruder_id == (unsigned int)-1){
@@ -275,6 +294,8 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id)
}
for (LayerTools &lt : m_layer_tools) {
// Extruders in lt.extruders are already sorted.
if (lt.extruders.empty())
continue;
if (lt.extruders.size() == 1 && lt.extruders.front() == 0)
@@ -283,21 +304,30 @@ void ToolOrdering::handle_dontcare_extruder(unsigned int last_extruder_id)
if (lt.extruders.front() == 0)
// Pop the "don't care" extruder, the "don't care" region will be merged with the next one.
lt.extruders.erase(lt.extruders.begin());
// Reorder the extruders to start with the last one.
for (size_t i = 1; i < lt.extruders.size(); ++ i)
if (lt.extruders[i] == last_extruder_id) {
// Move the last extruder to the front.
memmove(lt.extruders.data() + 1, lt.extruders.data(), i * sizeof(unsigned int));
lt.extruders.front() = last_extruder_id;
break;
if (print_config == nullptr
|| print_config->toolchange_ordering == ToolChangeOrderingType::Default)
{
// Reorder the extruders to start with the last one.
for (size_t i = 1; i < lt.extruders.size(); ++i) {
if (lt.extruders[i] == last_extruder_id) {
// Move the last extruder to the front.
std::rotate(
lt.extruders.begin(),
lt.extruders.begin() + i,
lt.extruders.begin() + i + 1
);
break;
}
}
}
if (lt == m_layer_tools[0]) {
// On first layer with wipe tower, prefer a soluble extruder
// at the beginning, so it is not wiped on the first layer.
if (m_print_config_ptr && m_print_config_ptr->enable_prime_tower) {
if (print_config && print_config->enable_prime_tower) {
for (size_t i = 0; i<lt.extruders.size(); ++i)
if (m_print_config_ptr->filament_soluble.get_at(lt.extruders[i]-1)) { // 1-based...
if (print_config->filament_soluble.get_at(lt.extruders[i]-1)) { // 1-based...
std::swap(lt.extruders[i], lt.extruders.front());
break;
}
@@ -396,6 +426,7 @@ void ToolOrdering::sort_and_build_data(const PrintObject& object , unsigned int
ToolOrdering::ToolOrdering(const PrintObject &object, unsigned int first_extruder, bool prime_multi_material)
{
m_print_full_config = &object.print()->full_print_config();
m_print_config_ptr = &object.print()->config();
m_print_object_ptr = &object;
m_print = const_cast<Print*>(object.print());
if (object.layers().empty())
@@ -1329,8 +1360,11 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
if (!m_layer_tools.empty())
first_layer_filaments = m_layer_tools[0].extruders;
const bool use_cyclic_ordering =
(print_config->toolchange_ordering == ToolChangeOrderingType::Cyclic);
// other_layers_seq: the layer_idx and extruder_idx are base on 1
auto get_custom_seq = [&other_layers_seqs, &reorder_first_layer, &first_layer_filaments](int layer_idx, std::vector<int>& out_seq) -> bool {
auto get_custom_seq = [&other_layers_seqs, &reorder_first_layer, &first_layer_filaments, &layer_filaments, use_cyclic_ordering](int layer_idx, std::vector<int>& out_seq) -> bool {
if (!reorder_first_layer && layer_idx == 0) {
out_seq.resize(first_layer_filaments.size());
std::transform(first_layer_filaments.begin(), first_layer_filaments.end(), out_seq.begin(), [](auto item) {return item + 1; });
@@ -1343,6 +1377,15 @@ void ToolOrdering::reorder_extruders_for_minimum_flush_volume(bool reorder_first
return true;
}
}
if (use_cyclic_ordering && layer_idx >= 0 && size_t(layer_idx) < layer_filaments.size()) {
std::vector<unsigned int> ordered = layer_filaments[size_t(layer_idx)];
std::sort(ordered.begin(), ordered.end());
out_seq.resize(ordered.size());
std::transform(ordered.begin(), ordered.end(), out_seq.begin(), [](auto item) { return int(item) + 1; });
return true;
}
return false;
};
+17
View File
@@ -2708,6 +2708,23 @@ const TriangleMesh& ModelVolume::get_convex_hull() const
return *m_convex_hull.get();
}
// Orca: get volume bbox for separate infill
static std::mutex mtx_model;
BoundingBox ModelVolume::get_volume_bbox(const Transform3d &matrix, Point &shift, bool apply_cache = false) {
std::unique_lock l(mtx_model); // locks function here
// Orca: the cache is keyed by the instance transform/shift; a ModelVolume is shared
// across instances, so returning the cache blindly would hand back another instance's bbox.
if (m_cached_volume_bbox.defined && apply_cache
&& matrix.isApprox(m_cached_volume_bbox_matrix)
&& shift == m_cached_volume_bbox_shift)
return m_cached_volume_bbox;
auto hull = get_convex_hull_2d(matrix);
hull.translate(-shift);
m_cached_volume_bbox_matrix = matrix;
m_cached_volume_bbox_shift = shift;
return m_cached_volume_bbox = hull.bounding_box().polygon().bounding_box();
}
//BBS: refine the model part names
ModelVolumeType ModelVolume::type_from_string(const std::string &s)
{
+24 -10
View File
@@ -920,6 +920,14 @@ public:
// Extruder ID is only valid for FFF. Returns -1 for SLA or if the extruder ID is not applicable (support volumes).
int extruder_id() const;
//Orca: cache clearing procedure to ensure that the shape is positioned accurately when manipulating it
void clear_cache() {
m_cached_trans_matrix = Transform3d::Identity().inverse(); // get unvelivable matrix
m_cached_volume_bbox.reset();
m_convex_hull_2d.clear();
m_cached_2d_polygon.clear();
};
bool is_splittable() const;
// BBS
@@ -961,39 +969,42 @@ public:
// Get count of errors in the mesh
int get_repaired_errors_count() const;
BoundingBox get_volume_bbox(const Transform3d &matrix, Point &shift, bool apply_cache);
void reset_volume_bbox() { m_cached_volume_bbox.reset(); };
// Helpers for loading / storing into AMF / 3MF files.
static ModelVolumeType type_from_string(const std::string &s);
static std::string type_to_string(const ModelVolumeType t);
const Geometry::Transformation& get_transformation() const { return m_transformation; }
void set_transformation(const Geometry::Transformation& transformation) { m_transformation = transformation; }
void set_transformation(const Transform3d& trafo) { m_transformation.set_matrix(trafo); }
void set_transformation(const Geometry::Transformation& transformation) { clear_cache(); m_transformation = transformation; }
void set_transformation(const Transform3d& trafo) { clear_cache(); m_transformation.set_matrix(trafo); }
Vec3d get_offset() const { return m_transformation.get_offset(); }
double get_offset(Axis axis) const { return m_transformation.get_offset(axis); }
void set_offset(const Vec3d& offset) { m_transformation.set_offset(offset); }
void set_offset(Axis axis, double offset) { m_transformation.set_offset(axis, offset); }
void set_offset(const Vec3d& offset) { clear_cache(); m_transformation.set_offset(offset); }
void set_offset(Axis axis, double offset) { clear_cache(); m_transformation.set_offset(axis, offset); }
Vec3d get_rotation() const { return m_transformation.get_rotation(); }
double get_rotation(Axis axis) const { return m_transformation.get_rotation(axis); }
void set_rotation(const Vec3d& rotation) { m_transformation.set_rotation(rotation); }
void set_rotation(Axis axis, double rotation) { m_transformation.set_rotation(axis, rotation); }
void set_rotation(const Vec3d& rotation) { clear_cache(); m_transformation.set_rotation(rotation); }
void set_rotation(Axis axis, double rotation) { clear_cache(); m_transformation.set_rotation(axis, rotation); }
Vec3d get_scaling_factor() const { return m_transformation.get_scaling_factor(); }
double get_scaling_factor(Axis axis) const { return m_transformation.get_scaling_factor(axis); }
void set_scaling_factor(const Vec3d& scaling_factor) { m_transformation.set_scaling_factor(scaling_factor); }
void set_scaling_factor(Axis axis, double scaling_factor) { m_transformation.set_scaling_factor(axis, scaling_factor); }
void set_scaling_factor(const Vec3d& scaling_factor) { clear_cache(); m_transformation.set_scaling_factor(scaling_factor); }
void set_scaling_factor(Axis axis, double scaling_factor) {clear_cache(); m_transformation.set_scaling_factor(axis, scaling_factor); }
Vec3d get_mirror() const { return m_transformation.get_mirror(); }
double get_mirror(Axis axis) const { return m_transformation.get_mirror(axis); }
bool is_left_handed() const { return m_transformation.is_left_handed(); }
void set_mirror(const Vec3d& mirror) { m_transformation.set_mirror(mirror); }
void set_mirror(Axis axis, double mirror) { m_transformation.set_mirror(axis, mirror); }
void set_mirror(const Vec3d& mirror) { clear_cache(); m_transformation.set_mirror(mirror); }
void set_mirror(Axis axis, double mirror) { clear_cache(); m_transformation.set_mirror(axis, mirror); }
void convert_from_imperial_units();
void convert_from_meters();
@@ -1048,6 +1059,9 @@ private:
mutable Transform3d m_cached_trans_matrix; //BBS, used for convex_hell_2d acceleration
mutable Polygon m_cached_2d_polygon; //BBS, used for convex_hell_2d acceleration
Geometry::Transformation m_transformation;
mutable BoundingBox m_cached_volume_bbox; //Orca: used for separated infills
mutable Transform3d m_cached_volume_bbox_matrix{Transform3d::Identity()}; //Orca: cache key for m_cached_volume_bbox
mutable Point m_cached_volume_bbox_shift{Point(0, 0)}; //Orca: cache key for m_cached_volume_bbox
//BBS: add convex_hell_2d related logic
void calculate_convex_hull_2d(const Geometry::Transformation &transformation) const;
+16
View File
@@ -571,6 +571,19 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator& p
return extrusion_coll;
}
// ORCA: only_one_wall_top detects the top as "slice − upper", so a feature rising from the middle of a
// top surface becomes an enclosed hole that gets ringed with extra inner walls. Fill those holes back
// into the top. Only holes that are both covered by the upper layer (excludes bridges) and backed by
// solid material (excludes voids) are filled.
static ExPolygons fill_enclosed_top_feature_holes(const ExPolygons &top, const Polygons &covered_by_upper, const ExPolygons &solid)
{
ExPolygons filled = top;
for (ExPolygon &ex : filled)
ex.holes.clear();
const ExPolygons feature_holes = intersection_ex(intersection_ex(diff_ex(filled, top), covered_by_upper), solid);
return feature_holes.empty() ? top : union_ex(top, feature_holes);
}
void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExPolygons &top_fills,
ExPolygons &non_top_polygons, ExPolygons &fill_clip) const {
// other perimeters
@@ -636,6 +649,8 @@ void PerimeterGenerator::split_top_surfaces(const ExPolygons &orig_polygons, ExP
ExPolygons delete_bridge = diff_ex(orig_polygons, bridge_checker, ApplySafetyOffset::Yes);
ExPolygons top_polygons = diff_ex(delete_bridge, upper_polygons_series_clipped, ApplySafetyOffset::Yes);
top_polygons = fill_enclosed_top_feature_holes(top_polygons, upper_polygons_series_clipped, orig_polygons);
// get the not-top surface, from the "real top" but enlarged by external_infill_margin (and the
// min_width_top_surface we removed a bit before)
ExPolygons temp_gap = diff_ex(top_polygons, fill_clip);
@@ -2194,6 +2209,7 @@ void PerimeterGenerator::process_arachne()
upper_slices_clipped = ClipperUtils::clip_clipper_polygons_with_subject_bbox(*upper_slices, infill_contour_bbox);
top_expolygons = diff_ex(infill_contour, upper_slices_clipped);
top_expolygons = fill_enclosed_top_feature_holes(top_expolygons, upper_slices_clipped, infill_contour);
if (!top_expolygons.empty()) {
if (lower_slices != nullptr) {
+19
View File
@@ -188,6 +188,12 @@ static t_config_enum_values s_keys_map_PowerLossRecoveryMode {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PowerLossRecoveryMode)
static t_config_enum_values s_keys_map_CenterOfSurfacePattern{
{"each_surface", int(CenterOfSurfacePattern::Each_Surface)},
{"each_model", int(CenterOfSurfacePattern::Each_Model)},
{"each_assembly", int(CenterOfSurfacePattern::Each_Assembly)}};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(CenterOfSurfacePattern)
static t_config_enum_values s_keys_map_FuzzySkinType {
{ "none", int(FuzzySkinType::None) },
{ "external", int(FuzzySkinType::External) },
@@ -221,6 +227,13 @@ static t_config_enum_values s_keys_map_FuzzySkinMode {
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(FuzzySkinMode)
static t_config_enum_values s_keys_map_TopSurfaceExpansionDirection {
{ "inward_and_outward", int(TopSurfaceExpansionDirection::InwardAndOutward) },
{ "inward", int(TopSurfaceExpansionDirection::Inward) },
{ "outward", int(TopSurfaceExpansionDirection::Outward) }
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(TopSurfaceExpansionDirection)
static t_config_enum_values s_keys_map_InfillPattern {
{ "monotonic", ipMonotonic },
{ "monotonicline", ipMonotonicLine },
@@ -522,6 +535,12 @@ static t_config_enum_values s_keys_map_PerimeterGeneratorType{
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(PerimeterGeneratorType)
static t_config_enum_values s_keys_map_ToolChangeOrderingType {
{ "default", int(ToolChangeOrderingType::Default) },
{ "cyclic", int(ToolChangeOrderingType::Cyclic) }
};
CONFIG_OPTION_ENUM_DEFINE_STATIC_MAPS(ToolChangeOrderingType)
static const t_config_enum_values s_keys_map_ZHopType = {
{ "Auto Lift", zhtAuto },
{ "Normal Lift", zhtNormal },
+28
View File
@@ -62,6 +62,19 @@ enum class FuzzySkinMode {
Combined,
};
// ORCA: direction in which top_surface_expansion grows the top surfaces.
enum class TopSurfaceExpansionDirection {
InwardAndOutward,
Inward,
Outward,
};
enum class CenterOfSurfacePattern {
Each_Surface,
Each_Model,
Each_Assembly,
};
enum class NoiseType {
Classic,
Perlin,
@@ -300,6 +313,12 @@ enum class PerimeterGeneratorType
Arachne
};
enum class ToolChangeOrderingType
{
Default,
Cyclic,
};
// BBS
enum OverhangFanThreshold {
Overhang_threshold_none = 0,
@@ -534,6 +553,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrinterTechnology)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(GCodeFlavor)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(FuzzySkinMode)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(TopSurfaceExpansionDirection)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WipeTowerType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(NoiseType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(InfillPattern)
@@ -561,6 +581,7 @@ CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PrintHostType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(AuthorizationType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(WipeTowerWallType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PerimeterGeneratorType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(ToolChangeOrderingType)
CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS(PowerLossRecoveryMode)
#undef CONFIG_OPTION_ENUM_DECLARE_STATIC_MAPS
@@ -1122,6 +1143,9 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloat, lightning_prune_angle))
((ConfigOptionFloat, lightning_straightening_angle))
((ConfigOptionBool, align_infill_direction_to_model))
((ConfigOptionBool, anisotropic_surfaces))
((ConfigOptionEnum<CenterOfSurfacePattern>, center_of_surface_pattern))
((ConfigOptionBool, separated_infills))
((ConfigOptionString, extra_solid_infills))
((ConfigOptionEnum<FuzzySkinType>, fuzzy_skin))
((ConfigOptionFloat, fuzzy_skin_thickness))
@@ -1187,6 +1211,9 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionFloatOrPercent, top_surface_line_width))
((ConfigOptionInt, top_shell_layers))
((ConfigOptionFloat, top_shell_thickness))
((ConfigOptionFloat, top_surface_expansion))
((ConfigOptionFloat, top_surface_expansion_margin))
((ConfigOptionEnum<TopSurfaceExpansionDirection>, top_surface_expansion_direction))
((ConfigOptionFloatsNullable, top_surface_speed))
//BBS
((ConfigOptionBoolsNullable, enable_overhang_speed))
@@ -1413,6 +1440,7 @@ PRINT_CONFIG_CLASS_DEFINE(
((ConfigOptionBool, single_extruder_multi_material))
((ConfigOptionBool, manual_filament_change))
((ConfigOptionBool, single_extruder_multi_material_priming))
((ConfigOptionEnum<ToolChangeOrderingType>, toolchange_ordering))
((ConfigOptionBool, wipe_tower_no_sparse_layers))
((ConfigOptionString, change_filament_gcode))
((ConfigOptionString, change_extrusion_role_gcode))
+75
View File
@@ -4,6 +4,7 @@
#include "Print.hpp"
#include "BoundingBox.hpp"
#include "ClipperUtils.hpp"
#include "Clipper2Utils.hpp"
#include "ElephantFootCompensation.hpp"
#include "Geometry.hpp"
#include "I18N.hpp"
@@ -562,6 +563,11 @@ void PrintObject::prepare_infill()
{
if (! this->set_started(posPrepareInfill))
return;
// Orca: clear all volume bbox caches
for (auto volume : this->model_object()->volumes)
volume->reset_volume_bbox();
m_print->set_status(25, L("Generating infill regions"));
if (m_typed_slices) {
// To improve robustness of detect_surfaces_type() when reslicing (working with typed slices), see GH issue #7442.
@@ -1297,6 +1303,9 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "infill_combination_max_layer_height"
|| opt_key == "bottom_shell_thickness"
|| opt_key == "top_shell_thickness"
|| opt_key == "top_surface_expansion"
|| opt_key == "top_surface_expansion_margin"
|| opt_key == "top_surface_expansion_direction"
|| opt_key == "minimum_sparse_infill_area"
|| opt_key == "sparse_infill_filament_id"
|| opt_key == "internal_solid_filament_id"
@@ -1330,6 +1339,9 @@ bool PrintObject::invalidate_state_by_config_options(
|| opt_key == "top_surface_line_width"
|| opt_key == "top_surface_density"
|| opt_key == "bottom_surface_density"
|| opt_key == "anisotropic_surfaces"
|| opt_key == "center_of_surface_pattern"
|| opt_key == "separated_infills"
|| opt_key == "initial_layer_line_width"
|| opt_key == "small_area_infill_flow_compensation"
|| opt_key == "lateral_lattice_angle_1"
@@ -1686,6 +1698,69 @@ void PrintObject::detect_surfaces_type()
}
}
// ORCA: Expand the top surfaces outward by top_surface_expansion in every direction. This
// enlarges the top solid infill and, in particular, grows it over the covered material left
// by features rising from the middle of a top surface (filling holes and joining tops so the
// features rest on it). The expansion stays inside the section it belongs to: each connected
// solid island has its own outer wall, so the top is grown within each island separately and
// clipped to it - growing one island's top across the gap into another island (which may have
// no top surface, leaving a partially filled layer) is never allowed. The top infill sits
// inside the perimeters, so the margin is measured from the walls: the island is inset by the
// band the walls consume (outer wall + inner walls) plus the configured margin, making that
// value the real clearance between the expanded top and the walls (avoiding a hull line). The
// original top is unioned back in, so where it already sits within that band it is kept as-is.
// Never claims a bottom surface.
const double top_expansion = layerm->region().config().top_surface_expansion.value;
if (top_expansion > 0. && ! top.empty()) {
const double d = scale_(top_expansion);
const auto jt = Clipper2Lib::JoinType::Miter;
const ExPolygons T = union_ex(to_expolygons(top));
const int wall_loops = layerm->region().config().wall_loops.value;
const double wall_band = wall_loops <= 0 ? 0. :
double(layerm->flow(frExternalPerimeter).scaled_width()) +
double(layerm->flow(frPerimeter).scaled_width()) * double(wall_loops - 1);
const double margin = scale_(layerm->region().config().top_surface_expansion_margin.value);
// minimum real top to act on: ignore anything thinner than ~2 top-infill lines
const float min_top = float(layerm->flow(frTopSolidInfill).scaled_width());
const auto direction = layerm->region().config().top_surface_expansion_direction.value;
ExPolygons grown;
for (const ExPolygon &island : union_ex(layerm_slices_surfaces)) {
// The top infill only exists inside the perimeters, so seed and measure from the infill
// region (the island minus the wall band), not the raw slice. A section whose only
// exposed top lies in the wall band - i.e. a layer where the top is just the walls
// themselves - has no infill here and is skipped, instead of being flooded inward by
// the expansion. Thin slivers inside the infill region are dropped by the opening too.
const ExPolygons infill_region = wall_band > 0. ? offset_ex(island, -float(wall_band)) : ExPolygons{ island };
const ExPolygons island_top = intersection_ex(T, infill_region);
if (opening_ex(island_top, min_top).empty())
continue; // no real top infill in this section - never expand into it
// grow by d, then keep only the part allowed by the configured direction: inward fills
// the holes/gaps left by features (clip the growth back to the top's own filled outline,
// which leaves the outer edge fixed), outward grows the outer edge toward the walls (drop
// the growth that fell into the original holes), and inward+outward keeps both.
ExPolygons expanded = offset_ex_2(island_top, d, jt);
if (direction != TopSurfaceExpansionDirection::InwardAndOutward) {
ExPolygons outline; // the top with its holes filled (same outer edge)
outline.reserve(island_top.size());
for (const ExPolygon &ex : island_top)
outline.emplace_back(ex.contour);
outline = union_ex(outline);
expanded = direction == TopSurfaceExpansionDirection::Inward ?
intersection_ex(expanded, outline) : // only growth into the holes
diff_ex(expanded, diff_ex(outline, island_top)); // only growth past the outer edge
}
// hold the expansion clear of the walls by the configured margin
const ExPolygons allowed = margin > 0. ? offset_ex(infill_region, -float(margin)) : infill_region;
append(grown, intersection_ex(expanded, allowed));
}
ExPolygons new_top = diff_ex(union_ex(T, grown), to_expolygons(bottom));
top.clear();
surfaces_append(top, std::move(new_top), stTop);
}
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
{
static int iRun = 0;
+39
View File
@@ -1,6 +1,8 @@
#include <exception>
#include <cstdint>
#include "miniz_extension.hpp"
#include "Utils.hpp"
#if defined(_MSC_VER) || defined(__MINGW64__)
#include "boost/nowide/cstdio.hpp"
@@ -15,6 +17,33 @@
namespace Slic3r {
namespace {
std::string decode_zip_unicode_path_extra_field(const std::string& extra, const std::string& path)
{
size_t offset = 0;
const mz_uint32 path_crc = mz_crc32(0, reinterpret_cast<const unsigned char*>(path.data()), path.size());
while (offset + 4 <= extra.size()) {
const unsigned char* field = reinterpret_cast<const unsigned char*>(extra.data() + offset);
const std::uint16_t len = field[2] | (static_cast<std::uint16_t>(field[3]) << 8);
if (offset + 4 + len > extra.size())
break;
if (field[0] == 0x75 && field[1] == 0x70 && len >= 5 && field[4] == 0x01) {
const mz_uint32 stored_crc =
static_cast<mz_uint32>(field[5]) |
(static_cast<mz_uint32>(field[6]) << 8) |
(static_cast<mz_uint32>(field[7]) << 16) |
(static_cast<mz_uint32>(field[8]) << 24);
if (stored_crc == path_crc)
return std::string(extra.data() + offset + 9, extra.data() + offset + 4 + len);
}
offset += 4 + len;
}
return Slic3r::decode_path(path.c_str());
}
bool open_zip(mz_zip_archive *zip, const char *fname, bool isread)
{
if (!zip) return false;
@@ -76,6 +105,16 @@ bool open_zip_writer(mz_zip_archive *zip, const std::string &fname)
bool close_zip_reader(mz_zip_archive *zip) { return close_zip(zip, true); }
bool close_zip_writer(mz_zip_archive *zip) { return close_zip(zip, false); }
std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat)
{
if (stat.m_is_utf8)
return stat.m_filename;
std::string extra(1024, 0);
const size_t extra_size = mz_zip_reader_get_extra(zip, stat.m_file_index, extra.data(), extra.size());
return decode_zip_unicode_path_extra_field(extra.substr(0, extra_size > 0 ? extra_size - 1 : 0), stat.m_filename);
}
MZ_Archive::MZ_Archive()
{
mz_zip_zero_struct(&arch);
+1
View File
@@ -10,6 +10,7 @@ bool open_zip_reader(mz_zip_archive *zip, const std::string &fname_utf8);
bool open_zip_writer(mz_zip_archive *zip, const std::string &fname_utf8);
bool close_zip_reader(mz_zip_archive *zip);
bool close_zip_writer(mz_zip_archive *zip);
std::string decode_archive_entry_path(mz_zip_archive *zip, const mz_zip_archive_file_stat &stat);
class MZ_Archive {
public:
+30
View File
@@ -713,6 +713,36 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig *config, in
toggle_field("top_layer_direction", has_top_shell);
toggle_field("bottom_layer_direction", has_bottom_shell);
toggle_line("top_surface_expansion", has_top_shell);
toggle_line("top_surface_expansion_margin", has_top_shell);
bool has_top_surface_expansion = config->opt_float("top_surface_expansion") > 0;
toggle_field("top_surface_expansion_margin", has_top_surface_expansion);
toggle_line("top_surface_expansion_direction", has_top_shell);
toggle_field("top_surface_expansion_direction", has_top_surface_expansion);
// Orca: Archimedean Chords and Octagram Spiral are the centered surface patterns that the
// pattern-centering, anisotropic-surface and separated-infill features act on.
auto is_centered_pattern = [](InfillPattern p) {
return p == InfillPattern::ipArchimedeanChords || p == InfillPattern::ipOctagramSpiral;
};
bool is_top_centered = is_centered_pattern(config->option<ConfigOptionEnum<InfillPattern>>("top_surface_pattern")->value);
bool is_bottom_centered = is_centered_pattern(config->option<ConfigOptionEnum<InfillPattern>>("bottom_surface_pattern")->value);
bool has_centered_surface = (has_top_shell && is_top_centered) || (has_bottom_shell && is_bottom_centered);
// Orca: center of surface pattern / anisotropic surfaces
toggle_line("center_of_surface_pattern", has_centered_surface);
toggle_line("anisotropic_surfaces", has_centered_surface);
// Orca: separate infills
bool is_internal_infill_centered = is_centered_pattern(config->option<ConfigOptionEnum<InfillPattern>>("sparse_infill_pattern")->value) ||
config->opt_string("sparse_infill_rotate_template") != "" ||
config->opt_string("solid_infill_rotate_template") != "";
toggle_line("separated_infills", is_internal_infill_centered);
// Orca: no need gaps
for (auto el : {"gap_fill_target", "filter_out_gap_fill"})
toggle_field(el, !config->opt_bool("anisotropic_surfaces"));
for (auto el : { "infill_direction", "sparse_infill_line_width", "gap_fill_target","filter_out_gap_fill","infill_wall_overlap",
"bridge_angle", "internal_bridge_angle", "relative_bridge_angle",
"solid_infill_direction", "solid_infill_rotate_template", "internal_solid_infill_pattern", "internal_solid_filament_id", "top_surface_filament_id", "bottom_surface_filament_id",
+1 -1
View File
@@ -239,7 +239,7 @@ void ExtrusionCalibration::create()
m_button_save_result->SetStyle(ButtonStyle::Confirm, ButtonType::Choice);
m_button_save_result->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_save, this);
m_button_last_step = new Button(m_step_2_panel, _L("Back")); // Back for english
m_button_last_step = new Button(m_step_2_panel, _CTX("Back", "Navigation")); // Back for english
m_button_last_step->SetStyle(ButtonStyle::Regular, ButtonType::Choice);
m_button_last_step->Bind(wxEVT_BUTTON, &ExtrusionCalibration::on_click_last, this);
+1 -10
View File
@@ -221,16 +221,7 @@ FileArchiveDialog::FileArchiveDialog(wxWindow* parent_window, mz_zip_archive* ar
std::vector<std::pair<boost::filesystem::path, size_t>> filtered_entries; // second is unzipped size
for (mz_uint i = 0; i < num_entries; ++i) {
if (mz_zip_reader_file_stat(archive, i, &stat)) {
std::string extra(1024, 0);
boost::filesystem::path path;
size_t extra_size = mz_zip_reader_get_filename_from_extra(archive, i, extra.data(), extra.size());
if (extra_size > 0) {
path = boost::filesystem::path(extra.substr(0, extra_size));
} else {
wxString wname = boost::nowide::widen(stat.m_filename);
std::string name = into_u8(wname);
path = boost::filesystem::path(name);
}
boost::filesystem::path path = Slic3r::decode_archive_entry_path(archive, stat);
assert(!path.empty());
if (!path.has_extension())
continue;
+2 -2
View File
@@ -4258,7 +4258,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
};
auto append_print = [&imgui, imperial_units](const ColorRGBA& color, const std::array<float, 4>& offsets, const Times& times, std::pair<double, double> used_filament) {
imgui.text(_u8L("Print"));
imgui.text(_CTX_utf8("Print", "Noun"));
ImGui::SameLine();
float icon_size = ImGui::GetTextLineHeight();
@@ -4292,7 +4292,7 @@ void GCodeViewer::render_legend(float &legend_height, int canvas_width, int canv
for (const PartialTime& item : partial_times) {
switch (item.type)
{
case PartialTime::EType::Print: { labels.push_back(_u8L("Print")); break; }
case PartialTime::EType::Print: { labels.push_back(_CTX_utf8("Print", "Noun")); break; }
case PartialTime::EType::Pause: { labels.push_back(_u8L("Pause")); break; }
case PartialTime::EType::ColorChange: { labels.push_back(_u8L("Color change")); break; }
}
+3 -3
View File
@@ -6036,11 +6036,11 @@ void GLCanvas3D::_render_3d_navigator()
strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Y], "Z"); // ORCA use uppercase to match text on tranform widgets
strcpy(style.AxisLabels[ImGuizmo::Axis::Axis_Z], "X"); // ORCA use uppercase to match text on tranform widgets
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_FRONT], _utf8("Front").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BACK], _utf8("Back").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BACK], _CTX_utf8("Back", "Camera View").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_TOP], _utf8("Top").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_BOTTOM], _utf8("Bottom").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_LEFT], _CTX_utf8(L_CONTEXT("Left", "Camera"), "Camera").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_RIGHT], _CTX_utf8(L_CONTEXT("Right", "Camera"), "Camera").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_LEFT], _CTX_utf8("Left", "Camera View").c_str());
strcpy(style.FaceLabels[ImGuizmo::FACES::FACE_RIGHT], _CTX_utf8("Right", "Camera View").c_str());
float sc = get_scale();
#ifdef WIN32
+4 -1
View File
@@ -132,6 +132,9 @@ std::map<std::string, std::vector<SimpleSettingData>> SettingsFactory::PART_CATE
{"infill_anchor", "", 1},
{"infill_anchor_max", "", 1},
{"top_surface_pattern", "", 1},
{"top_surface_expansion", "", 1},
{"top_surface_expansion_margin", "", 1},
{"top_surface_expansion_direction", "", 1},
{"bottom_surface_pattern", "", 1},
{"internal_solid_infill_pattern", "", 1},
{"align_infill_direction_to_model", "", 1},
@@ -187,7 +190,7 @@ std::vector<SimpleSettingData> SettingsFactory::get_visible_options(const std::s
//Quality
"wall_infill_order", "ironing_type", "inner_wall_line_width", "outer_wall_line_width", "top_surface_line_width",
//Shell
"wall_loops", "top_shell_layers", "bottom_shell_layers", "top_shell_thickness", "bottom_shell_thickness",
"wall_loops", "top_shell_layers", "bottom_shell_layers", "top_shell_thickness", "bottom_shell_thickness", "top_surface_expansion", "top_surface_expansion_margin", "top_surface_expansion_direction",
//Infill
"sparse_infill_density", "sparse_infill_pattern", "top_surface_pattern", "bottom_surface_pattern", "infill_combination", "infill_direction", "infill_wall_overlap",
//speed
+1 -1
View File
@@ -1303,7 +1303,7 @@ void GLGizmoMeasure::render_dimensioning()
return;
const double ratio = new_value / old_value;
wxGetApp().plater()->take_snapshot(_u8L("Scale"), UndoRedo::SnapshotType::GizmoAction);
wxGetApp().plater()->take_snapshot(_CTX_utf8("Scale", "Verb"), UndoRedo::SnapshotType::GizmoAction);
// apply scale
TransformationType type;
type.set_world();
+2 -2
View File
@@ -143,9 +143,9 @@ bool GLGizmoScale3D::on_init()
std::string GLGizmoScale3D::on_get_name() const
{
if (!on_is_activable() && m_state == EState::Off) {
return _u8L("Scale") + ":\n" + _u8L("Please select at least one object.");
return _CTX_utf8("Scale", "Verb") + ":\n" + _u8L("Please select at least one object.");
} else {
return _u8L("Scale");
return _CTX_utf8("Scale", "Verb");
}
}
@@ -1161,7 +1161,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
imgui_wrapper->calc_text_size(_L("Part")).x
}) + imgui_wrapper->calc_text_size("xxx"sv).x + imgui_wrapper->scaled(3.5f);
float label_max = std::max({
imgui_wrapper->calc_text_size(_L("Scale")).x,
imgui_wrapper->calc_text_size(_CTX("Scale", "Noun")).x,
imgui_wrapper->calc_text_size(_L("Size")).x
});
float caption_max = std::max(label_max, coord_combo_width - 3 * space_size);
@@ -1218,7 +1218,7 @@ void GizmoObjectManipulation::do_render_scale_input_window(ImGuiWrapper* imgui_w
//ImGui::PushItemWidth(unit_size * 2);
ImGui::AlignTextToFramePadding();
imgui_wrapper->text(_L("Scale"));
imgui_wrapper->text(_CTX("Scale", "Noun"));
ImGui::SameLine(caption_max + space_size);
ImGui::PushItemWidth(unit_size);
ImGui::BBLInputDouble(label_scale_values[0][0], &scale[0], 0.0f, 0.0f, "%.2f");
+1 -1
View File
@@ -644,7 +644,7 @@ void Slic3r::GUI::ImageGrid::renderContent1(wxDC &dc, wxPoint const &pt, int ind
if (m_file_sys->GetFileType() == PrinterFileSystem::F_MODEL) {
if (secondAction != _L("Play"))
thirdAction = secondAction;
secondAction = _L("Print");
secondAction = _CTX("Print", "Verb");
}
// Draw buttons on hovered item
wxRect rect{pt.x, pt.y + m_content_rect.GetBottom() - m_buttons_background.GetHeight(), m_content_rect.GetWidth(), m_buttons_background.GetHeight()};
+5 -5
View File
@@ -2013,10 +2013,10 @@ wxBoxSizer* MainFrame::create_side_tools()
});
// upload and print
SideButton* send_gcode_btn = new SideButton(p, _L("Print"), "");
SideButton* send_gcode_btn = new SideButton(p, _CTX("Print", "Verb"), "");
send_gcode_btn->SetCornerRadius(0);
send_gcode_btn->Bind(wxEVT_BUTTON, [this, p](wxCommandEvent&) {
m_print_btn->SetLabel(_L("Print"));
m_print_btn->SetLabel(_CTX("Print", "Verb"));
m_print_select = eSendGcode;
m_print_enable = get_enable_print_status();
m_print_btn->Enable(m_print_enable);
@@ -2662,9 +2662,9 @@ static void add_common_view_menu_items(wxMenu* view_menu, MainFrame* mainFrame,
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
append_menu_item(view_menu, wxID_ANY, _L("Rear") + "\t" + ctrl + "4", _L("Rear View"), [mainFrame](wxCommandEvent&) { mainFrame->select_view("rear"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
append_menu_item(view_menu, wxID_ANY, _CTX(L_CONTEXT("Left", "Camera"), "Camera") + "\t" + ctrl + "5", _L("Left View"),[mainFrame](wxCommandEvent &) {mainFrame->select_view("left"); },
append_menu_item(view_menu, wxID_ANY, _CTX("Left", "Camera View") + "\t" + ctrl + "5", _L("Left View"),[mainFrame](wxCommandEvent &) {mainFrame->select_view("left"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
append_menu_item(view_menu, wxID_ANY, _CTX(L_CONTEXT("Right", "Camera"), "Camera") + "\t" + ctrl + "6", _L("Right View"),[mainFrame](wxCommandEvent &) { mainFrame->select_view("right"); },
append_menu_item(view_menu, wxID_ANY, _CTX("Right", "Camera View") + "\t" + ctrl + "6", _L("Right View"),[mainFrame](wxCommandEvent &) { mainFrame->select_view("right"); },
"", nullptr, [can_change_view]() { return can_change_view(); }, mainFrame);
}
@@ -4040,7 +4040,7 @@ void MainFrame::set_print_button_to_default(PrintSelectType select_type)
m_print_btn->Enable(m_print_enable);
this->Layout();
} else if (select_type == PrintSelectType::eSendGcode) {
m_print_btn->SetLabel(_L("Print"));
m_print_btn->SetLabel(_CTX("Print", "Verb"));
m_print_select = eSendGcode;
if (m_print_enable)
m_print_enable = get_enable_print_status() && can_send_gcode();
+3 -3
View File
@@ -556,7 +556,7 @@ void MediaFilePanel::doAction(size_t index, int action)
} else if (action == 1) {
if (fs->GetFileType() == PrinterFileSystem::F_MODEL) {
if (index != -1) {
auto dlg = new MediaProgressDialog(_L("Print"), this, [fs] { fs->FetchModelCancel(); });
auto dlg = new MediaProgressDialog(_CTX("Print", "Verb"), this, [fs] { fs->FetchModelCancel(); });
dlg->Update(0, _L("Fetching model information..."));
fs->FetchModel(index, [this, fs, dlg, index](int result, std::string const &data) {
dlg->Destroy();
@@ -566,7 +566,7 @@ void MediaFilePanel::doAction(size_t index, int action)
wxString msg = data.empty() ? _L("Failed to fetch model information from printer.") :
from_u8(data);
CallAfter([this, msg] {
MessageDialog(this, msg, _L("Print"), wxOK).ShowModal();
MessageDialog(this, msg, _CTX("Print", "Verb"), wxOK).ShowModal();
});
return;
}
@@ -579,7 +579,7 @@ void MediaFilePanel::doAction(size_t index, int action)
|| plate_data_list.empty()) {
MessageDialog(this,
_L("Failed to parse model information."),
_L("Print"), wxOK).ShowModal();
_CTX("Print", "Verb"), wxOK).ShowModal();
return;
}
+5 -10
View File
@@ -13113,6 +13113,9 @@ void adjust_settings_for_flowrate_calib(ModelObjectPtrs& objects, bool linear, i
_obj->config.set_key_value("top_solid_infill_flow_ratio", new ConfigOptionFloat(1.0f));
_obj->config.set_key_value("infill_direction", new ConfigOptionFloat(45));
_obj->config.set_key_value("solid_infill_direction", new ConfigOptionFloat(135));
_obj->config.set_key_value("anisotropic_surfaces", new ConfigOptionBool(false));
_obj->config.set_key_value("center_of_surface_pattern", new ConfigOptionEnum<CenterOfSurfacePattern>(CenterOfSurfacePattern::Each_Surface));
_obj->config.set_key_value("separated_infills", new ConfigOptionBool(false));
_obj->config.set_key_value("align_infill_direction_to_model", new ConfigOptionBool(true));
_obj->config.set_key_value("ironing_type", new ConfigOptionEnum<IroningType>(IroningType::NoIroning));
_obj->config.set_key_value("internal_solid_infill_speed", new ConfigOptionFloatsNullable(internal_solid_speeds));
@@ -13923,17 +13926,9 @@ bool Plater::preview_zip_archive(const boost::filesystem::path& archive_path)
if (mz_zip_reader_file_stat(&archive, i, &stat)) {
if (size != stat.m_uncomp_size) // size must fit
continue;
wxString wname = boost::nowide::widen(stat.m_filename);
std::string name = into_u8(wname);
std::string name = Slic3r::decode_archive_entry_path(&archive, stat);
fs::path archive_path(name);
std::string extra(1024, 0);
size_t extra_size = mz_zip_reader_get_filename_from_extra(&archive, i, extra.data(), extra.size());
if (extra_size > 0) {
archive_path = fs::path(extra.substr(0, extra_size));
name = archive_path.string();
}
if (archive_path.empty())
continue;
if (path != archive_path)
@@ -15750,7 +15745,7 @@ int Plater::export_3mf(const boost::filesystem::path& output_path, SaveStrategy
std::vector<Preset*> project_presets = preset_bundle.get_current_project_embedded_presets();
StoreParams store_params;
store_params.path = path_u8.c_str();
store_params.path = path_u8;
store_params.model = &p->model;
store_params.plate_data_list = plate_data_list;
store_params.export_plate_idx = export_plate_idx;
+1 -1
View File
@@ -138,7 +138,7 @@ SelectMachineDialog::SelectMachineDialog(Plater *plater)
/*mode switch*/
/*auto m_sizer_mode_switch = new wxBoxSizer(wxHORIZONTAL);
m_mode_print = new SendModeSwitchButton(scroll_area, _L("Print"), true);
m_mode_print = new SendModeSwitchButton(scroll_area, _CTX("Print", "Verb"), true);
m_mode_send = new SendModeSwitchButton(scroll_area,_L("Save to printer"), false);
m_sizer_mode_switch->Add(m_mode_print, 0, wxALIGN_CENTER, 0);
m_sizer_mode_switch->Add(0, 0, 0, wxLEFT, FromDIP(8));
+1 -1
View File
@@ -6694,7 +6694,7 @@ bool Tab::validate_filament_temperature_pairs()
RichMessageDialog dialog(parent(), msg_text, _L("Temperature Safety Check"), wxYES | wxNO | wxICON_WARNING);
dialog.SetButtonLabel(wxID_YES, _L("Continue"), true);
dialog.SetButtonLabel(wxID_NO, _L("Back"));
dialog.SetButtonLabel(wxID_NO, _CTX("Back", "Navigation"));
dialog.ShowCheckBox(_L("Don't warn again for this preset"));
const int answer = dialog.ShowModal();
// Session-only suppression (does not modify/save filament preset data).
+1 -1
View File
@@ -47,7 +47,7 @@ WebViewPanel::WebViewPanel(wxWindow *parent)
// Create the button
bSizer_toolbar = new wxBoxSizer(wxHORIZONTAL);
m_button_back = new wxButton(this, wxID_ANY, _L("Back"), wxDefaultPosition, wxDefaultSize, 0);
m_button_back = new wxButton(this, wxID_ANY, _CTX("Back", "Navigation"), wxDefaultPosition, wxDefaultSize, 0);
m_button_back->Enable(false);
bSizer_toolbar->Add(m_button_back, 0, wxALL, 5);
+24 -15
View File
@@ -7,6 +7,7 @@
#include "../GUI/PartPlate.hpp"
#include "libslic3r/CutUtils.hpp"
#include "libslic3r/ClipperUtils.hpp"
#include "libslic3r/Utils.hpp"
#include "libslic3r/Model.hpp"
#include "slic3r/GUI/Jobs/BoostThreadWorker.hpp"
@@ -27,11 +28,19 @@ const double MIN_PA_K_VALUE = 0.0;
const double MAX_PA_K_VALUE = 2.0;
std::unique_ptr<Worker> CalibUtils::print_worker;
wxString wxstr_temp_dir = fs::path(fs::temp_directory_path() / "calib").wstring();
static const std::string temp_dir = wxstr_temp_dir.utf8_string();
static const std::string temp_gcode_path = temp_dir + "/temp.gcode";
static const std::string path = temp_dir + "/test.3mf";
static const std::string config_3mf_path = temp_dir + "/test_config.3mf";
// Built lazily so temporary_dir() is read on first use, after set_temporary_dir()
// has run at startup (it isolates the temp root per user to avoid cross-user collisions).
static const std::string& calib_temp_dir()
{
static const std::string dir = temporary_dir() + "/calib";
return dir;
}
static std::string calib_temp_file(const std::string& name) { return calib_temp_dir() + "/" + name; }
static const std::string gcode_filename = "temp.gcode";
static const std::string model_filename = "test.3mf";
static const std::string config_filename = "test_config.3mf";
static std::string MachineBedTypeString[7] = {
"auto",
@@ -1599,7 +1608,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
part_plate->update_slice_result_valid_state(true);
gcode_result->reset();
fff_print->export_gcode(temp_gcode_path, gcode_result, nullptr);
fff_print->export_gcode(calib_temp_file(gcode_filename), gcode_result, nullptr);
std::vector<ThumbnailData*> thumbnails;
PlateDataPtrs plate_data_list;
@@ -1618,7 +1627,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
}
for (auto plate_data : plate_data_list) {
plate_data->gcode_file = temp_gcode_path;
plate_data->gcode_file = calib_temp_file(gcode_filename);
plate_data->is_sliced_valid = true;
plate_data->printer_model_id = obj_->printer_type;
FilamentInfo& filament_info = plate_data->slice_filaments_info.front();
@@ -1681,7 +1690,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
}
StoreParams store_params;
store_params.path = path.c_str();
store_params.path = calib_temp_file(model_filename);
store_params.model = model;
store_params.plate_data_list = plate_data_list;
store_params.config = &new_print_config;
@@ -1695,7 +1704,7 @@ bool CalibUtils::process_and_store_3mf(Model *model, const DynamicPrintConfig &f
bool success = Slic3r::store_bbs_3mf(store_params);
store_params.strategy = SaveStrategy::Silence | SaveStrategy::SplitModel | SaveStrategy::WithSliceInfo | SaveStrategy::SkipAuxiliary;
store_params.path = config_3mf_path.c_str();
store_params.path = calib_temp_file(config_filename);
success = Slic3r::store_bbs_3mf(store_params);
release_PlateData_list(plate_data_list);
@@ -1784,9 +1793,9 @@ void CalibUtils::send_to_print(const CalibInfo &calib_info, wxString &error_mess
PrintPrepareData job_data;
job_data.is_from_plater = false;
job_data.plate_idx = 0;
job_data._3mf_config_path = config_3mf_path;
job_data._3mf_path = path;
job_data._temp_path = temp_dir;
job_data._3mf_config_path = calib_temp_file(config_filename);
job_data._3mf_path = calib_temp_file(model_filename);
job_data._temp_path = calib_temp_dir();
PlateListData plate_data;
plate_data.is_valid = true;
@@ -1889,9 +1898,9 @@ void CalibUtils::send_to_print(const std::vector<CalibInfo> &calib_infos, wxStri
PrintPrepareData job_data;
job_data.is_from_plater = false;
job_data.plate_idx = 0;
job_data._3mf_config_path = config_3mf_path;
job_data._3mf_path = path;
job_data._temp_path = temp_dir;
job_data._3mf_config_path = calib_temp_file(config_filename);
job_data._3mf_path = calib_temp_file(model_filename);
job_data._temp_path = calib_temp_dir();
PlateListData plate_data;
plate_data.is_valid = true;
+11
View File
@@ -93,3 +93,14 @@ SCENARIO("Support layer Z honors contact distance", "[SupportMaterial]")
}
}
}
// extrude_support once held a `static` lambda capturing `this`, so a second export in the
// same process dereferenced a returned stack frame (ASan: stack-use-after-return).
TEST_CASE("Support G-code emission survives a second slice in the same process", "[SupportMaterial][Regression]")
{
const std::string first = slice({ TestMesh::overhang }, { { "enable_support", 1 } });
REQUIRE(! layers_with_role(first, "support").empty());
const std::string second = slice({ TestMesh::overhang }, { { "enable_support", 1 } });
REQUIRE(! layers_with_role(second, "support").empty());
}
+44
View File
@@ -18,6 +18,7 @@
#include <catch2/catch_all.hpp>
#include "libslic3r/Arachne/WallToolPaths.hpp"
#include "libslic3r/Arachne/SkeletalTrapezoidation.hpp"
#include "libslic3r/Arachne/utils/ExtrusionLine.hpp"
#include "libslic3r/Arachne/BeadingStrategy/BeadingStrategyFactory.hpp"
#include "libslic3r/Arachne/BeadingStrategy/BeadingStrategy.hpp"
@@ -265,3 +266,46 @@ TEST_CASE("Arachne widening keeps two beads in transition band (#14376)", "[Arac
for (const coord_t w : beading.bead_widths)
CHECK(w <= inner_width);
}
namespace {
// Exposes the protected static interpolate() for a focused unit test.
struct InterpolateProbe : SkeletalTrapezoidation {
using SkeletalTrapezoidation::interpolate;
};
} // anonymous namespace
// interpolate() indexes the merged beading with an index derived from `left`. The merged beading
// follows the thicker of left/right, so when the thicker side has fewer insets the index runs past
// its end.
TEST_CASE("Beading interpolation tolerates a thicker side with fewer insets", "[Arachne][Regression]") {
using Beading = BeadingStrategy::Beading;
// Thicker side (right) has fewer insets, so the merged beading holds only 2 toolpath locations.
const coord_t w = scaled<coord_t>(0.42);
Beading left;
left.total_thickness = scaled<coord_t>(1.0);
left.bead_widths = { w, w, w, w };
left.toolpath_locations = { scaled<coord_t>(0.1), scaled<coord_t>(0.3), scaled<coord_t>(0.5), scaled<coord_t>(0.7) };
left.left_over = 0;
Beading right;
right.total_thickness = scaled<coord_t>(2.0);
right.bead_widths = { w, w };
right.toolpath_locations = { scaled<coord_t>(0.1), scaled<coord_t>(0.3) };
right.left_over = 0;
// Just past left's location [2] (0.5), so the derived index is 2, past the end of the 2-inset merged beading.
const coord_t switching_radius = scaled<coord_t>(0.6);
Beading result;
REQUIRE_NOTHROW(result = InterpolateProbe::interpolate(left, 0.5, right, switching_radius));
// With the guard the adjustment is skipped, so the result is the plain interpolation.
const Beading expected = InterpolateProbe::interpolate(left, 0.5, right);
REQUIRE(result.toolpath_locations.size() == expected.toolpath_locations.size());
REQUIRE(result.bead_widths.size() == expected.bead_widths.size());
for (size_t i = 0; i < expected.toolpath_locations.size(); ++i) {
CHECK(result.toolpath_locations[i] == expected.toolpath_locations[i]);
CHECK(result.bead_widths[i] == expected.bead_widths[i]);
}
}
@@ -52,6 +52,11 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
SECTION("math: round(-13.4)") { REQUIRE(parser.process("{round(-13.4)}") == "-13"); }
SECTION("math: round(13.6)") { REQUIRE(parser.process("{round(13.6)}") == "14"); }
SECTION("math: round(-13.6)") { REQUIRE(parser.process("{round(-13.6)}") == "-14"); }
SECTION("math: round(13.5)") { REQUIRE(parser.process("{round(13.5)}") == "14"); }
SECTION("math: floor(13.9)") { REQUIRE(parser.process("{floor(13.9)}") == "13"); }
SECTION("math: floor(-13.1)") { REQUIRE(parser.process("{floor(-13.1)}") == "-14"); }
SECTION("math: ceil(13.1)") { REQUIRE(parser.process("{ceil(13.1)}") == "14"); }
SECTION("math: ceil(-13.9)") { REQUIRE(parser.process("{ceil(-13.9)}") == "-13"); }
SECTION("math: digits(5, 15)") { REQUIRE(parser.process("{digits(5, 15)}") == " 5"); }
SECTION("math: digits(5., 15)") { REQUIRE(parser.process("{digits(5., 15)}") == " 5"); }
SECTION("math: zdigits(5, 15)") { REQUIRE(parser.process("{zdigits(5, 15)}") == "000000000000005"); }
@@ -65,6 +70,8 @@ SCENARIO("Placeholder parser scripting", "[PlaceholderParser]") {
SECTION("math: interpolate_table(13.84375892476, (0, 0), (20, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13.84375892476, (0, 0), (20, 20))}")) == Catch::Approx(13.84375892476)); }
SECTION("math: interpolate_table(13, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(13, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(13.)); }
SECTION("math: interpolate_table(25, (0, 0), (20, 20), (30, 20))") { REQUIRE(std::stod(parser.process("{interpolate_table(25, (0, 0), (20, 20), (30, 20))}")) == Catch::Approx(20.)); }
// Only the grammar's built-in functions are callable; any other name is an undefined variable and throws.
SECTION("math: a non-built-in function name throws") { REQUIRE_THROWS(parser.process("{sqrt(16)}")); }
// regex_replace(subject, /pattern/, replacement): the string-transform primitive.
SECTION("regex_replace: strips a file extension") { REQUIRE(parser.process("{regex_replace(\"part.stl\", /\\.[^.]*$/, \"\")}") == "part"); }