Compare commits
326 Commits
v2.5.0-dev
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2f96072d55 | ||
|
|
5c5a22c44f | ||
|
|
15b094540f | ||
|
|
2d7a3165d4 | ||
|
|
a827f9358b | ||
|
|
7595d76158 | ||
|
|
bef6de4863 | ||
|
|
08bee0f34c | ||
|
|
0794e23b43 | ||
|
|
5659a83c44 | ||
|
|
bcc3f1eb44 | ||
|
|
19998ae487 | ||
|
|
d8190d474e | ||
|
|
e75ae87295 | ||
|
|
acc3db79f9 | ||
|
|
f64cb21f73 | ||
|
|
ad4ac71be4 | ||
|
|
05cb4ecf48 | ||
|
|
f5b71de932 | ||
| 8d48947b8e | |||
|
|
514cd26bca | ||
|
|
c02df26328 | ||
|
|
8500fcdcca | ||
|
|
c95887a93f | ||
|
|
d3405cf461 | ||
|
|
a524ec7dde | ||
|
|
55d0108cd3 | ||
|
|
d91972e576 | ||
|
|
ccf28f394b | ||
|
|
6888f9d806 | ||
|
|
07a87b4129 | ||
|
|
23555f8df2 | ||
|
|
116658de29 | ||
|
|
a8f2fea5e2 | ||
|
|
7c80ea1fc1 | ||
|
|
b5d46a3e7c | ||
|
|
fa0a08d8f3 | ||
|
|
a38d9ccb21 | ||
|
|
92ea1ce57e | ||
|
|
2c029402d7 | ||
|
|
f8dc94ab7f | ||
|
|
76e16d8db4 | ||
|
|
feeea3e651 | ||
|
|
128068cb65 | ||
|
|
2f13fd82b1 | ||
|
|
dafc223d1a | ||
|
|
19db9aa9c3 | ||
|
|
73aaeaa549 | ||
|
|
d1369e45c8 | ||
|
|
3808f95a26 | ||
|
|
2a1fdcc0b9 | ||
|
|
66d4850399 | ||
|
|
6d7eeb89dc | ||
|
|
8ccae50e1b | ||
|
|
148228f67c | ||
|
|
e3eca45f3d | ||
|
|
98831ac27f | ||
|
|
c7d1331991 | ||
|
|
f344cf78f3 | ||
|
|
0086ed0ddc | ||
|
|
3e9784321d | ||
|
|
451d2f946f | ||
|
|
a4546b2d05 | ||
|
|
b5143767f4 | ||
|
|
ceb63575a6 | ||
|
|
ae14fda37c | ||
|
|
698e8e297c | ||
|
|
97f196aa76 | ||
|
|
dbd9e12d5d | ||
|
|
02ea6a37a1 | ||
|
|
fd985c71c5 | ||
|
|
a16a28c5da | ||
|
|
96d46e7f82 | ||
|
|
85ae6156f0 | ||
|
|
a723c53ee0 | ||
|
|
b44a267d34 | ||
|
|
e34e9a19c4 | ||
|
|
b1e6c0a64c | ||
|
|
42392fa71e | ||
|
|
41b7a4c295 | ||
|
|
1ff08f8614 | ||
|
|
b371c68fbf | ||
|
|
7dc088a8b4 | ||
|
|
6a50902150 | ||
|
|
9c76d7d71c | ||
|
|
a2e188294e | ||
|
|
6aa2686bfe | ||
|
|
e8444445e8 | ||
|
|
4606acea73 | ||
|
|
3fd02ef899 | ||
|
|
83d3ec97f5 | ||
|
|
27d5ab6acb | ||
|
|
036ffba307 | ||
|
|
b4a532622f | ||
|
|
83c287d6f4 | ||
|
|
b3764c8454 | ||
|
|
8cc4040f5d | ||
|
|
4084c0a8d8 | ||
|
|
0493de8084 | ||
|
|
b1e3f265b0 | ||
|
|
3a7f52398c | ||
|
|
3249a2ccee | ||
|
|
5ecc99c321 | ||
|
|
b8cc3c077d | ||
|
|
055c3cde9a | ||
|
|
f72d1fc6ac | ||
|
|
cac5f7b562 | ||
|
|
e9a4aae68a | ||
|
|
a58b964e52 | ||
|
|
f474af2348 | ||
|
|
c6802c73dc | ||
|
|
b5685b34f8 | ||
|
|
29525e652f | ||
|
|
94accf7a94 | ||
|
|
5540971e7f | ||
|
|
f6c56bf2bb | ||
|
|
1a6bb9d652 | ||
|
|
25aeaec0e5 | ||
|
|
2738e5d474 | ||
|
|
e9fe58b348 | ||
|
|
63bc97e9ee | ||
|
|
42d79dffbd | ||
|
|
2bc65951b3 | ||
|
|
64ad2eb2e8 | ||
|
|
3503f0613f | ||
|
|
9aed9a4e6a | ||
|
|
ffd4732dd6 | ||
|
|
d6323f3924 | ||
|
|
07d1a85464 | ||
|
|
5accfa52ea | ||
|
|
138406a483 | ||
|
|
8cdb5b0272 | ||
|
|
6401c87c3a | ||
|
|
00555687a7 | ||
|
|
e1884ea0b4 | ||
|
|
df8f231168 | ||
|
|
28e51216f9 | ||
|
|
9e010689aa | ||
|
|
e55c775c18 | ||
|
|
6cd8fec603 | ||
|
|
c831e78177 | ||
|
|
8b7da48ae2 | ||
|
|
5ca2f24732 | ||
|
|
afbcab395f | ||
|
|
29abec47b1 | ||
|
|
fdf97b19dd | ||
|
|
dcf79e332c | ||
|
|
646f558560 | ||
|
|
1aae13641a | ||
|
|
012062a189 | ||
|
|
f41a18bcb9 | ||
|
|
11cacfabab | ||
|
|
1fcd74ac77 | ||
|
|
68460338d4 | ||
|
|
1f3fe6d6a1 | ||
|
|
7b209131d4 | ||
|
|
2d762be590 | ||
|
|
a75b8b69e3 | ||
|
|
2ea7239849 | ||
|
|
ef4ba55320 | ||
|
|
01c915be65 | ||
|
|
c519c107e7 | ||
|
|
15498a6942 | ||
|
|
10c5d14be4 | ||
|
|
f6f5123501 | ||
|
|
1ef400bbf1 | ||
|
|
36658ee005 | ||
|
|
cb298296eb | ||
|
|
5d02c827e3 | ||
|
|
b9c73d7a41 | ||
|
|
bf81236bc5 | ||
|
|
21c64595a6 | ||
|
|
3cfd8c656b | ||
|
|
8e9a0cbfdc | ||
|
|
bd28850f70 | ||
|
|
9e27af3032 | ||
|
|
24ab0b81a2 | ||
|
|
a32bcfda35 | ||
|
|
d9e74f22f6 | ||
|
|
359693fa89 | ||
|
|
8668114350 | ||
|
|
054ae4f903 | ||
|
|
06f3511b2d | ||
|
|
679ed9b8d1 | ||
|
|
63f5828425 | ||
|
|
c6035a7c91 | ||
|
|
14e61db633 | ||
|
|
31969e8ae0 | ||
|
|
06e7a6d611 | ||
|
|
64d24c755f | ||
|
|
4e06e9d30b | ||
|
|
2500828c58 | ||
|
|
b938ed363d | ||
|
|
3f9638ce86 | ||
|
|
60fed30069 | ||
|
|
0bdefc5d8b | ||
|
|
26f84bdc1b | ||
|
|
b86100aa14 | ||
|
|
6646aba3cf | ||
|
|
b6e70a886d | ||
|
|
29be1d396e | ||
|
|
0adef6ec19 | ||
|
|
11a6b694d8 | ||
|
|
ade01c68d3 | ||
|
|
49424433df | ||
|
|
87e3897a7f | ||
|
|
e77452e2e3 | ||
|
|
532de0f04a | ||
|
|
a3e979ab8a | ||
|
|
bf7e4a1f6d | ||
|
|
6af1dbf3c0 | ||
|
|
bf7341fcc3 | ||
|
|
5841df8c19 | ||
|
|
1844a83e8e | ||
|
|
fa68f7653e | ||
|
|
591e7b940f | ||
|
|
d37697d492 | ||
|
|
1dd0532026 | ||
|
|
6a3e29b21c | ||
|
|
396cca82bb | ||
|
|
c26d06125d | ||
|
|
372496d10f | ||
|
|
b60e841cc7 | ||
|
|
47f8d15e0b | ||
|
|
a1b37455f3 | ||
|
|
a01ec22be4 | ||
|
|
a0b522628a | ||
|
|
53164d063b | ||
|
|
281f81d1c7 | ||
|
|
277e0f83c2 | ||
|
|
1692778cda | ||
|
|
0bad0d4fd4 | ||
|
|
e8c305e4cd | ||
|
|
8a550bb513 | ||
|
|
5775c81167 | ||
|
|
9da925fa52 | ||
|
|
cf129f9ded | ||
|
|
aea4282633 | ||
|
|
7066faa9d7 | ||
|
|
f473f3e7f1 | ||
|
|
ec0d6406e9 | ||
|
|
b3622f5f9e | ||
|
|
10c338fe38 | ||
|
|
a7ba31adea | ||
|
|
0e724d1801 | ||
|
|
be63704600 | ||
|
|
d7c66ac575 | ||
|
|
fdbbf5f135 | ||
|
|
8c7a3b55bb | ||
|
|
643a39976d | ||
|
|
122196730f | ||
|
|
9468e8b335 | ||
|
|
1de6aec92d | ||
|
|
2dc5c697bc | ||
|
|
f27801b4ef | ||
|
|
4b33dae806 | ||
|
|
aecead1f8c | ||
|
|
7667cd8c96 | ||
|
|
5823c83691 | ||
|
|
d7603ed561 | ||
|
|
6952711491 | ||
|
|
0aed75461f | ||
|
|
346d40ba24 | ||
|
|
57cd99b950 | ||
|
|
6ab2e96c0a | ||
|
|
fd67e4a421 | ||
|
|
9dfda06442 | ||
|
|
1b5a300cb3 | ||
|
|
e93ce996d3 | ||
|
|
380cc025cd | ||
|
|
3cc3cba664 | ||
|
|
d532c447c2 | ||
|
|
b42f3666a4 | ||
|
|
ed260a8055 | ||
|
|
8f898cc6ea | ||
|
|
de81550309 | ||
|
|
d115824d6a | ||
|
|
aee6db8e27 | ||
|
|
0664e47a70 | ||
|
|
30dee1911c | ||
|
|
4d03044159 | ||
|
|
684747a8b9 | ||
|
|
dd2c0f9b29 | ||
|
|
2343e8ff26 | ||
|
|
76d5e99483 | ||
|
|
5f840fdba4 | ||
|
|
6960168c07 | ||
|
|
7580532c6a | ||
|
|
f8a90ec89c | ||
|
|
303ec41cb2 | ||
|
|
4ac7f4380e | ||
|
|
7f4d3097a5 | ||
|
|
42af381c2a | ||
|
|
86094ffd9b | ||
|
|
0c39ef1c43 | ||
|
|
e2372ac5d5 | ||
|
|
33a391185c | ||
|
|
0927e9fda1 | ||
|
|
c0801f5773 | ||
|
|
ef40a49431 | ||
|
|
6e0a3486a2 | ||
|
|
770358653a | ||
|
|
c1d5c06744 | ||
|
|
988718a091 | ||
|
|
81b0e61845 | ||
|
|
61a1c232c5 | ||
|
|
d18043291f | ||
|
|
711ac44cb1 | ||
|
|
1134d45530 | ||
|
|
5d93d333dd | ||
|
|
9923664212 | ||
|
|
7899f15b58 | ||
|
|
e70831f5b5 | ||
|
|
c7390ef970 | ||
|
|
a9dc1858b1 | ||
|
|
6df4c7f16a | ||
|
|
f8338a498a | ||
|
|
548aa1ac98 | ||
|
|
f41f2136c2 | ||
|
|
7cb92e2502 | ||
|
|
7530e344d7 | ||
|
|
f719d895f5 | ||
|
|
195b5868ac | ||
|
|
0fbc85c0a0 | ||
|
|
6222bd0f23 | ||
|
|
33325df15d |
9
.devcontainer/devcontainer-lock.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/desktop-lite:1": {
|
||||
"version": "1.2.9",
|
||||
"resolved": "ghcr.io/devcontainers/features/desktop-lite@sha256:d8649bc8ca8e50a52fbee29d281739ea05dc1022905b185434d6bbe9afc8f221",
|
||||
"integrity": "sha256:d8649bc8ca8e50a52fbee29d281739ea05dc1022905b185434d6bbe9afc8f221"
|
||||
}
|
||||
}
|
||||
}
|
||||
71
.github/workflows/build_deps.yml
vendored
@@ -22,11 +22,28 @@ jobs:
|
||||
key: ${{ inputs.cache-key }}
|
||||
|
||||
- uses: lukka/get-cmake@latest
|
||||
# The windows-11-arm runner needs CMake <= 3.31 (handled in the next step).
|
||||
if: ${{ !(runner.os == 'Windows' && inputs.arch == 'arm64') }}
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true # <--= Use the local cache (default is 'false').
|
||||
useCloudCache: true
|
||||
|
||||
- name: Install CMake 3.31.x (Windows ARM64)
|
||||
# windows-11-arm ships CMake 4.x, which removed pre-3.5 policy
|
||||
# compatibility AND has incomplete ASM_ARMASM linker modules
|
||||
# (breaks Boost.Context on ARM64). Pin to the last 3.x release.
|
||||
if: runner.os == 'Windows' && inputs.arch == 'arm64'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ver = "3.31.6"
|
||||
$url = "https://github.com/Kitware/CMake/releases/download/v$ver/cmake-$ver-windows-arm64.zip"
|
||||
Invoke-WebRequest -Uri $url -OutFile "$env:RUNNER_TEMP\cmake.zip"
|
||||
Expand-Archive -Path "$env:RUNNER_TEMP\cmake.zip" -DestinationPath "$env:RUNNER_TEMP\cmake" -Force
|
||||
$cmakeBin = "$env:RUNNER_TEMP\cmake\cmake-$ver-windows-arm64\bin"
|
||||
if (-not (Test-Path "$cmakeBin\cmake.exe")) { throw "cmake.exe not found at $cmakeBin" }
|
||||
Add-Content -Path $env:GITHUB_PATH -Value $cmakeBin
|
||||
|
||||
- name: setup dev on Windows
|
||||
if: runner.os == 'Windows'
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
@@ -42,6 +59,50 @@ jobs:
|
||||
shell: pwsh
|
||||
|
||||
|
||||
- name: Install MSYS2 (clangarm64) with GMP/MPFR and LLVM tools
|
||||
if: runner.os == 'Windows' && inputs.arch == 'arm64'
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: CLANGARM64
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-clang-aarch64-gmp
|
||||
mingw-w64-clang-aarch64-mpfr
|
||||
mingw-w64-clang-aarch64-llvm
|
||||
|
||||
- name: Stage ARM64 GMP/MPFR (no prebuilt blobs exist for win-arm64)
|
||||
# GMP/MPFR ship prebuilt x64/x86 blobs in-tree but none for ARM64.
|
||||
# Pull them from MSYS2 clangarm64 and generate MSVC import libs via
|
||||
# llvm-dlltool, then stage into deps/{GMP,MPFR}/.../win-arm64 where the
|
||||
# MSVC branch of GMP.cmake/MPFR.cmake copies them into the dep prefix.
|
||||
if: runner.os == 'Windows' && inputs.arch == 'arm64'
|
||||
shell: msys2 {0}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
BIN=/clangarm64/bin
|
||||
REPO=$(cygpath -u "$GITHUB_WORKSPACE")
|
||||
|
||||
make_import_lib() {
|
||||
local dll="$1"; local lib="$2"; local def="/tmp/${dll%.dll}.def"
|
||||
echo "EXPORTS" > "$def"
|
||||
llvm-readobj --coff-exports "$BIN/$dll" | awk '/Name: /{print $2}' >> "$def"
|
||||
llvm-dlltool -m arm64 -D "$dll" -d "$def" -l "$BIN/$lib"
|
||||
}
|
||||
|
||||
make_import_lib libgmp-10.dll libgmp-10.lib
|
||||
|
||||
# MPFR 4.x ships as libmpfr-6.dll; rename to libmpfr-4 BEFORE generating
|
||||
# the import lib so the baked-in runtime DLL name is correct.
|
||||
MPFR_DLL=$(ls $BIN/libmpfr-*.dll | head -1 | xargs basename)
|
||||
if [ "$MPFR_DLL" != "libmpfr-4.dll" ]; then cp "$BIN/$MPFR_DLL" "$BIN/libmpfr-4.dll"; fi
|
||||
make_import_lib libmpfr-4.dll libmpfr-4.lib
|
||||
|
||||
mkdir -p $REPO/deps/GMP/gmp/lib/win-arm64 $REPO/deps/MPFR/mpfr/lib/win-arm64
|
||||
cp $BIN/libgmp-10.dll $BIN/libgmp-10.lib $REPO/deps/GMP/gmp/lib/win-arm64/
|
||||
cp $BIN/libmpfr-4.dll $BIN/libmpfr-4.lib $REPO/deps/MPFR/mpfr/lib/win-arm64/
|
||||
cp /clangarm64/include/gmp.h $REPO/deps/GMP/gmp/include/
|
||||
cp /clangarm64/include/mpfr.h $REPO/deps/MPFR/mpfr/include/ || true
|
||||
|
||||
# Build Dependencies
|
||||
- name: Build on Windows
|
||||
if: runner.os == 'Windows'
|
||||
@@ -50,8 +111,14 @@ jobs:
|
||||
if (-not "${{ vars.SELF_HOSTED }}") {
|
||||
choco install strawberryperl
|
||||
}
|
||||
.\build_release_vs.bat deps
|
||||
.\build_release_vs.bat pack
|
||||
$arch = "${{ inputs.arch }}"
|
||||
if ($arch -eq "arm64") {
|
||||
.\build_release_vs.bat deps arm64
|
||||
.\build_release_vs.bat pack arm64
|
||||
} else {
|
||||
.\build_release_vs.bat deps
|
||||
.\build_release_vs.bat pack
|
||||
}
|
||||
shell: pwsh
|
||||
|
||||
- name: Build on Mac ${{ inputs.arch }}
|
||||
|
||||
128
.github/workflows/build_orca.yml
vendored
@@ -11,6 +11,11 @@ jobs:
|
||||
ubuntu-ver: '2404'
|
||||
ubuntu-ver-str: '_Ubuntu2404'
|
||||
ORCA_UPDATER_SIG_KEY: ${{ secrets.ORCA_UPDATER_SIG_KEY }}
|
||||
# Branches whose builds are published to the nightly release. The
|
||||
# belt-printer branch ships alongside main but its assets carry a `_belt`
|
||||
# suffix (nightly_suffix) so they never overwrite the main nightly assets.
|
||||
deploy_nightly: ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' }}
|
||||
nightly_suffix: ${{ github.ref == 'refs/heads/belt-printer' && '_belt' || '' }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -27,11 +32,28 @@ jobs:
|
||||
fail-on-cache-miss: true
|
||||
|
||||
- uses: lukka/get-cmake@latest
|
||||
# The windows-11-arm runner needs CMake <= 3.31 (handled in the next step).
|
||||
if: ${{ !(runner.os == 'Windows' && inputs.arch == 'arm64') }}
|
||||
with:
|
||||
cmakeVersion: "~4.3.0" # use most recent 4.3.x version
|
||||
useLocalCache: true # <--= Use the local cache (default is 'false').
|
||||
useCloudCache: true
|
||||
|
||||
- name: Install CMake 3.31.x (Windows ARM64)
|
||||
# windows-11-arm ships CMake 4.x, which removed pre-3.5 policy
|
||||
# compatibility AND has incomplete ASM_ARMASM linker modules
|
||||
# (breaks Boost.Context on ARM64). Pin to the last 3.x release.
|
||||
if: runner.os == 'Windows' && inputs.arch == 'arm64'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ver = "3.31.6"
|
||||
$url = "https://github.com/Kitware/CMake/releases/download/v$ver/cmake-$ver-windows-arm64.zip"
|
||||
Invoke-WebRequest -Uri $url -OutFile "$env:RUNNER_TEMP\cmake.zip"
|
||||
Expand-Archive -Path "$env:RUNNER_TEMP\cmake.zip" -DestinationPath "$env:RUNNER_TEMP\cmake" -Force
|
||||
$cmakeBin = "$env:RUNNER_TEMP\cmake\cmake-$ver-windows-arm64\bin"
|
||||
if (-not (Test-Path "$cmakeBin\cmake.exe")) { throw "cmake.exe not found at $cmakeBin" }
|
||||
Add-Content -Path $env:GITHUB_PATH -Value $cmakeBin
|
||||
|
||||
- name: Get the version and date on Ubuntu and macOS
|
||||
if: runner.os != 'Windows'
|
||||
run: |
|
||||
@@ -140,17 +162,9 @@ jobs:
|
||||
run: |
|
||||
./build_release_macos.sh -u -x ${{ !vars.SELF_HOSTED && '-1' || '' }} -a universal -t 10.15
|
||||
|
||||
- name: Delete intermediate per-arch artifacts
|
||||
if: runner.os == 'macOS' && inputs.macos-combine-only
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: |
|
||||
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
|
||||
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
|
||||
|
||||
# Thanks to RaySajuuk, it's working now
|
||||
- name: Sign app and notary
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/belt-printer' || startsWith(github.ref, 'refs/heads/release/')) && runner.os == 'macOS' && inputs.macos-combine-only
|
||||
working-directory: ${{ github.workspace }}
|
||||
env:
|
||||
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
|
||||
@@ -158,6 +172,8 @@ jobs:
|
||||
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
|
||||
CERTIFICATE_ID: ${{ secrets.MACOS_CERTIFICATE_ID }}
|
||||
run: |
|
||||
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
|
||||
source ${{ github.workspace }}/scripts/retry.sh
|
||||
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
|
||||
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
|
||||
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode --output $CERTIFICATE_PATH
|
||||
@@ -180,7 +196,7 @@ jobs:
|
||||
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
|
||||
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
|
||||
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
|
||||
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
|
||||
# Create separate OrcaSlicer_profile_validator DMG if the app exists
|
||||
@@ -189,7 +205,7 @@ jobs:
|
||||
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
|
||||
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
|
||||
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
|
||||
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
|
||||
retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
|
||||
codesign --deep --force --verbose --options runtime --timestamp --entitlements ${{ github.workspace }}/scripts/disable_validation.entitlements --sign "$CERTIFICATE_ID" OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
|
||||
fi
|
||||
|
||||
@@ -204,14 +220,16 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Create DMG without notary
|
||||
if: github.ref != 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only
|
||||
if: github.ref != 'refs/heads/main' && github.ref != 'refs/heads/belt-printer' && runner.os == 'macOS' && inputs.macos-combine-only
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
# Load the `retry` helper (retries flaky commands such as `hdiutil create`).
|
||||
source ${{ github.workspace }}/scripts/retry.sh
|
||||
mkdir -p ${{ github.workspace }}/build/universal/OrcaSlicer_dmg
|
||||
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/*
|
||||
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer.app ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/
|
||||
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_dmg/Applications
|
||||
hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
retry hdiutil create -volname "OrcaSlicer" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_dmg -ov -format UDZO OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
|
||||
# Create separate OrcaSlicer_profile_validator DMG if the app exists
|
||||
if [ -f "${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app/Contents/MacOS/OrcaSlicer_profile_validator" ]; then
|
||||
@@ -219,9 +237,19 @@ jobs:
|
||||
rm -rf ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/*
|
||||
cp -R ${{ github.workspace }}/build/universal/OrcaSlicer/OrcaSlicer_profile_validator.app ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/
|
||||
ln -sfn /Applications ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg/Applications
|
||||
hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
|
||||
retry hdiutil create -volname "OrcaSlicer Profile Validator" -srcfolder ${{ github.workspace }}/build/universal/OrcaSlicer_profile_validator_dmg -ov -format UDZO OrcaSlicer_profile_validator_Mac_universal_${{ env.ver }}.dmg
|
||||
fi
|
||||
|
||||
# Delete the per-arch bundles only after signing/DMG creation succeeded, so a
|
||||
# failed run keeps them available for a re-run instead of forcing a full rebuild.
|
||||
- name: Delete intermediate per-arch artifacts
|
||||
if: success() && runner.os == 'macOS' && inputs.macos-combine-only
|
||||
uses: geekyeggo/delete-artifact@v6
|
||||
with:
|
||||
name: |
|
||||
OrcaSlicer_Mac_bundle_arm64_${{ github.sha }}
|
||||
OrcaSlicer_Mac_bundle_x86_64_${{ github.sha }}
|
||||
|
||||
- name: Upload artifacts mac
|
||||
if: runner.os == 'macOS' && inputs.macos-combine-only
|
||||
uses: actions/upload-artifact@v7
|
||||
@@ -238,13 +266,13 @@ jobs:
|
||||
if-no-files-found: ignore
|
||||
|
||||
- name: Deploy Mac release
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'macOS' && inputs.macos-combine-only && !vars.SELF_HOSTED
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
release_id: 137995723
|
||||
asset_path: ${{ github.workspace }}/OrcaSlicer_Mac_universal_${{ env.ver }}.dmg
|
||||
asset_name: OrcaSlicer_Mac_universal_nightly.dmg
|
||||
asset_name: OrcaSlicer_Mac_universal_nightly${{ env.nightly_suffix }}.dmg
|
||||
asset_content_type: application/octet-stream
|
||||
max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted
|
||||
|
||||
@@ -260,6 +288,18 @@ jobs:
|
||||
max_releases: 1
|
||||
|
||||
# Windows
|
||||
- name: Set Windows build variables
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
if ("${{ inputs.arch }}" -eq "arm64") {
|
||||
"BUILD_DIR=build-arm64" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
|
||||
"ARCH_SUFFIX=_arm64" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
|
||||
} else {
|
||||
"BUILD_DIR=build" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
|
||||
"ARCH_SUFFIX=_x64" | Out-File -Append -FilePath $env:GITHUB_ENV -Encoding utf8
|
||||
}
|
||||
|
||||
- name: setup MSVC
|
||||
if: runner.os == 'Windows'
|
||||
uses: microsoft/setup-msbuild@v3
|
||||
@@ -277,23 +317,28 @@ jobs:
|
||||
# env:
|
||||
# WindowsSdkDir: 'C:\Program Files (x86)\Windows Kits\10\'
|
||||
# WindowsSDKVersion: '10.0.26100.0\'
|
||||
run: .\build_release_vs.bat slicer
|
||||
run: |
|
||||
$arch = "${{ inputs.arch }}"
|
||||
if ($arch -eq "arm64") { .\build_release_vs.bat slicer arm64 } else { .\build_release_vs.bat slicer }
|
||||
shell: pwsh
|
||||
|
||||
# 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
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}
|
||||
run: |
|
||||
cpack -G NSIS
|
||||
|
||||
- name: Pack app
|
||||
if: runner.os == 'Windows'
|
||||
working-directory: ${{ github.workspace }}/build
|
||||
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}
|
||||
shell: cmd
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -tzip OrcaSlicer_Windows_${{ env.ver }}_portable.zip ${{ github.workspace }}/build/OrcaSlicer'
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -tzip OrcaSlicer_Windows_${{ env.ver }}${{ env.ARCH_SUFFIX }}_portable.zip ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer'
|
||||
|
||||
- name: Pack PDB
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/build/src/Release
|
||||
if: runner.os == 'Windows' && inputs.arch != 'arm64' && !vars.SELF_HOSTED
|
||||
working-directory: ${{ github.workspace }}/${{ env.BUILD_DIR }}/src/Release
|
||||
shell: cmd
|
||||
run: '"C:/Program Files/7-Zip/7z.exe" a -m0=lzma2 -mx9 Debug_PDB_${{ env.ver }}_for_developers_only.7z *.pdb'
|
||||
|
||||
@@ -301,54 +346,54 @@ jobs:
|
||||
if: runner.os == 'Windows'
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}_portable
|
||||
path: ${{ github.workspace }}/build/OrcaSlicer
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}${{ env.ARCH_SUFFIX }}_portable
|
||||
path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer
|
||||
|
||||
- name: Upload artifacts Win installer
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}
|
||||
path: ${{ github.workspace }}/build/OrcaSlicer*.exe
|
||||
name: OrcaSlicer_Windows_${{ env.ver }}${{ env.ARCH_SUFFIX }}
|
||||
path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer*.exe
|
||||
|
||||
- name: Upload artifacts Win PDB
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
if: runner.os == 'Windows' && inputs.arch != 'arm64' && !vars.SELF_HOSTED
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: PDB
|
||||
path: ${{ github.workspace }}/build/src/Release/Debug_PDB_${{ env.ver }}_for_developers_only.7z
|
||||
|
||||
- name: Upload OrcaSlicer_profile_validator Win
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
if: runner.os == 'Windows' && inputs.arch != 'arm64' && !vars.SELF_HOSTED
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: OrcaSlicer_profile_validator_Windows_${{ env.ver }}
|
||||
path: ${{ github.workspace }}/build/src/Release/OrcaSlicer_profile_validator.exe
|
||||
|
||||
- name: Deploy Windows release portable
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
release_id: 137995723
|
||||
asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_${{ env.ver }}_portable.zip
|
||||
asset_name: OrcaSlicer_Windows_nightly_portable.zip
|
||||
asset_path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer_Windows_${{ env.ver }}${{ env.ARCH_SUFFIX }}_portable.zip
|
||||
asset_name: OrcaSlicer_Windows${{ env.ARCH_SUFFIX }}_nightly${{ env.nightly_suffix }}_portable.zip
|
||||
asset_content_type: application/x-zip-compressed
|
||||
max_releases: 1
|
||||
|
||||
- name: Deploy Windows release installer
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && env.deploy_nightly == 'true' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
release_id: 137995723
|
||||
asset_path: ${{ github.workspace }}/build/OrcaSlicer_Windows_Installer_${{ env.ver }}.exe
|
||||
asset_name: OrcaSlicer_Windows_Installer_nightly.exe
|
||||
asset_path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer_Windows_Installer_${{ env.ver }}${{ env.ARCH_SUFFIX }}.exe
|
||||
asset_name: OrcaSlicer_Windows_Installer${{ env.ARCH_SUFFIX }}_nightly${{ env.nightly_suffix }}.exe
|
||||
asset_content_type: application/x-msdownload
|
||||
max_releases: 1
|
||||
|
||||
- name: Deploy Windows OrcaSlicer_profile_validator release
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
if: github.repository == 'OrcaSlicer/OrcaSlicer' && github.ref == 'refs/heads/main' && runner.os == 'Windows' && inputs.arch != 'arm64' && !vars.SELF_HOSTED
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
@@ -364,8 +409,9 @@ jobs:
|
||||
shell: pwsh
|
||||
run: |
|
||||
./scripts/msix/build_msix.ps1 `
|
||||
-InstallDir "${{ github.workspace }}/build/OrcaSlicer" `
|
||||
-OutputPath "${{ github.workspace }}/build/OrcaSlicer_Windows_MSIX_${{ env.ver }}.msix" `
|
||||
-InstallDir "${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer" `
|
||||
-OutputPath "${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer_Windows_MSIX_${{ env.ver }}${{ env.ARCH_SUFFIX }}.msix" `
|
||||
-Architecture "${{ inputs.arch }}" `
|
||||
-IdentityName "${{ vars.ORCA_MSIX_IDENTITY_NAME || 'OrcaSlicer.OrcaSlicer' }}" `
|
||||
-Publisher "${{ vars.ORCA_MSIX_PUBLISHER || 'CN=38F7EA55-C73B-4072-B3B2-C8E0EA15BB82' }}" `
|
||||
-PublisherDisplayName "${{ vars.ORCA_MSIX_PUBLISHER_DISPLAY_NAME || 'OrcaSlicer' }}"
|
||||
@@ -374,8 +420,8 @@ jobs:
|
||||
if: runner.os == 'Windows' && !vars.SELF_HOSTED
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: OrcaSlicer_Windows_MSIX_${{ env.ver }}
|
||||
path: ${{ github.workspace }}/build/OrcaSlicer_Windows_MSIX_${{ env.ver }}.msix
|
||||
name: OrcaSlicer_Windows_MSIX_${{ env.ver }}${{ env.ARCH_SUFFIX }}
|
||||
path: ${{ github.workspace }}/${{ env.BUILD_DIR }}/OrcaSlicer_Windows_MSIX_${{ env.ver }}${{ env.ARCH_SUFFIX }}.msix
|
||||
|
||||
# Ubuntu
|
||||
- name: Apt-Install Dependencies
|
||||
@@ -447,13 +493,13 @@ jobs:
|
||||
path: './build/src/Release/OrcaSlicer_profile_validator'
|
||||
|
||||
- name: Deploy Ubuntu release
|
||||
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && github.ref == 'refs/heads/main' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
|
||||
if: ${{ github.repository == 'OrcaSlicer/OrcaSlicer' && ! env.ACT && env.deploy_nightly == 'true' && runner.os == 'Linux' && !vars.SELF_HOSTED }}
|
||||
uses: WebFreak001/deploy-nightly@v3.2.0
|
||||
with:
|
||||
upload_url: https://uploads.github.com/repos/OrcaSlicer/OrcaSlicer/releases/137995723/assets{?name,label}
|
||||
release_id: 137995723
|
||||
asset_path: ./build/OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_${{ env.ver }}.AppImage
|
||||
asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_nightly.AppImage
|
||||
asset_name: OrcaSlicer_Linux_AppImage${{ env.ubuntu-ver-str }}${{ env.arch_suffix }}_nightly${{ env.nightly_suffix }}.AppImage
|
||||
asset_content_type: application/octet-stream
|
||||
max_releases: 1 # optional, if there are more releases than this matching the asset_name, the oldest ones are going to be deleted
|
||||
- name: Deploy Ubuntu release
|
||||
|
||||
125
.github/workflows/check_profiles.yml
vendored
@@ -25,10 +25,10 @@ jobs:
|
||||
- name: Download
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
curl -LJO https://github.com/SoftFever/Orca_tools/releases/download/1/OrcaSlicer_profile_validator
|
||||
curl -L -o OrcaSlicer_profile_validator https://github.com/OrcaSlicer/OrcaSlicer/releases/download/nightly-builds/OrcaSlicer_profile_validator_Linux_Ubuntu2404_nightly
|
||||
chmod +x ./OrcaSlicer_profile_validator
|
||||
|
||||
# validate profiles
|
||||
# Validate all system profiles.
|
||||
- name: validate system profiles
|
||||
id: validate_system
|
||||
continue-on-error: true
|
||||
@@ -36,17 +36,115 @@ jobs:
|
||||
set +e
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 2>&1 | tee ${{ runner.temp }}/validate_system.log
|
||||
exit ${PIPESTATUS[0]}
|
||||
# For now run filament subtype check only for BBL profiles until we fix other vendors' profiles.
|
||||
- name: validate filament subtype check for BBL profiles
|
||||
id: validate_filament_subtypes
|
||||
continue-on-error: true
|
||||
run: |
|
||||
set +e
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 -v BBL -f 2>&1 | tee ${{ runner.temp }}/validate_filament_subtypes.log
|
||||
exit ${PIPESTATUS[0]}
|
||||
|
||||
- name: validate custom presets
|
||||
id: validate_custom
|
||||
continue-on-error: true
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: |
|
||||
set +e
|
||||
curl -LJO https://github.com/OrcaSlicer/OrcaSlicer/releases/download/nightly-builds/orca_custom_preset_tests.zip
|
||||
unzip -q ./orca_custom_preset_tests.zip -d ${{ github.workspace }}/resources/profiles
|
||||
./OrcaSlicer_profile_validator -p ${{ github.workspace }}/resources/profiles -l 2 2>&1 | tee ${{ runner.temp }}/validate_custom.log
|
||||
exit ${PIPESTATUS[0]}
|
||||
fixtures_dir="${{ runner.temp }}/profile-fixtures"
|
||||
output_dir="${{ runner.temp }}/custom-preset-validation"
|
||||
combined_log="${{ runner.temp }}/validate_custom.log"
|
||||
summary="${output_dir}/summary.md"
|
||||
release_url="https://github.com/OrcaSlicer/OrcaSlicer-profile-validator/releases/download/fixture-archive"
|
||||
|
||||
rm -rf "${fixtures_dir}" "${output_dir}"
|
||||
mkdir -p "${fixtures_dir}" "${output_dir}"
|
||||
|
||||
curl -fsSL -o "${fixtures_dir}/manifest.json" "${release_url}/manifest.json"
|
||||
|
||||
MANIFEST_PATH="${fixtures_dir}/manifest.json" python3 <<'PY' > "${fixtures_dir}/fixtures.tsv"
|
||||
import json
|
||||
import os
|
||||
|
||||
with open(os.environ["MANIFEST_PATH"], encoding="utf-8") as fh:
|
||||
manifest = json.load(fh)
|
||||
|
||||
if isinstance(manifest, dict):
|
||||
entries = manifest.get("fixtures", [])
|
||||
else:
|
||||
entries = manifest
|
||||
|
||||
for entry in entries:
|
||||
version = entry.get("version", "")
|
||||
asset = entry.get("asset", "")
|
||||
sha256 = entry.get("asset_sha256", "")
|
||||
if not version or not asset:
|
||||
continue
|
||||
print(f"{version}\t{asset}\t{sha256}")
|
||||
PY
|
||||
|
||||
if [ ! -s "${fixtures_dir}/fixtures.tsv" ]; then
|
||||
echo "No custom preset fixtures found in ${release_url}/manifest.json" | tee "${combined_log}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
echo "## Custom Preset Fixture Validation"
|
||||
echo ""
|
||||
echo "| Version | Status | Log |"
|
||||
echo "| --- | --- | --- |"
|
||||
} > "${summary}"
|
||||
|
||||
status=0
|
||||
failed_logs=()
|
||||
|
||||
while IFS=$'\t' read -r version asset expected_sha256; do
|
||||
fixture_zip="${fixtures_dir}/${asset}"
|
||||
asset_url_name="$(python3 -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "${asset}")"
|
||||
profile_tree="${output_dir}/profiles-${version}"
|
||||
log_path="${output_dir}/${version}.log"
|
||||
|
||||
curl -fsSL -o "${fixture_zip}" "${release_url}/${asset_url_name}"
|
||||
|
||||
if [ -n "${expected_sha256}" ] && [ "${expected_sha256}" != "<sha256>" ]; then
|
||||
echo "${expected_sha256} ${fixture_zip}" | sha256sum -c -
|
||||
fi
|
||||
|
||||
rm -rf "${profile_tree}"
|
||||
mkdir -p "${profile_tree}"
|
||||
cp -a "${{ github.workspace }}/resources/profiles/." "${profile_tree}/"
|
||||
rm -rf "${profile_tree}/user"
|
||||
unzip -q "${fixture_zip}" -d "${profile_tree}"
|
||||
|
||||
set +e
|
||||
./OrcaSlicer_profile_validator -p "${profile_tree}" -l 2 > "${log_path}" 2>&1
|
||||
result=$?
|
||||
set -e
|
||||
|
||||
if [ "${result}" -eq 0 ]; then
|
||||
echo "| ${version} | PASS | ${version}.log |" >> "${summary}"
|
||||
else
|
||||
echo "| ${version} | FAIL | ${version}.log |" >> "${summary}"
|
||||
failed_logs+=("${log_path}")
|
||||
status=1
|
||||
fi
|
||||
done < "${fixtures_dir}/fixtures.tsv"
|
||||
|
||||
{
|
||||
cat "${summary}"
|
||||
if [ "${#failed_logs[@]}" -gt 0 ]; then
|
||||
echo ""
|
||||
echo "## Failed Fixture Logs"
|
||||
for log_path in "${failed_logs[@]}"; do
|
||||
echo ""
|
||||
echo "### $(basename "${log_path}" .log)"
|
||||
echo '```'
|
||||
head -c 12000 "${log_path}" || echo "No output captured"
|
||||
echo '```'
|
||||
done
|
||||
fi
|
||||
} | tee "${combined_log}"
|
||||
|
||||
exit "${status}"
|
||||
|
||||
- name: Prepare PR number for comment workflow
|
||||
if: ${{ always() && github.event_name == 'pull_request' }}
|
||||
@@ -55,7 +153,7 @@ jobs:
|
||||
echo "${{ github.event.pull_request.number }}" > ${{ runner.temp }}/profile-check-results/pr_number.txt
|
||||
|
||||
- name: Prepare comment artifact
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && github.event_name == 'pull_request' && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
{
|
||||
# Marker matched by check_profiles_comment.yml to delete prior comments.
|
||||
@@ -81,6 +179,15 @@ jobs:
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_filament_subtypes.outcome }}" = "failure" ]; then
|
||||
echo "### BBL Filament Subtype Validation Failed"
|
||||
echo ""
|
||||
echo '```'
|
||||
head -c 30000 ${{ runner.temp }}/validate_filament_subtypes.log || echo "No output captured"
|
||||
echo '```'
|
||||
echo ""
|
||||
fi
|
||||
|
||||
if [ "${{ steps.validate_custom.outcome }}" = "failure" ]; then
|
||||
echo "### Custom Preset Validation Failed"
|
||||
echo ""
|
||||
@@ -103,7 +210,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
- name: Fail if any check failed
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
if: ${{ always() && (steps.extra_json_check.outcome == 'failure' || steps.validate_system.outcome == 'failure' || steps.validate_filament_subtypes.outcome == 'failure' || steps.validate_custom.outcome == 'failure') }}
|
||||
run: |
|
||||
echo "One or more profile checks failed. See above for details."
|
||||
exit 1
|
||||
|
||||
4
.github/workflows/pr-label-bot.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Ask PR author for label
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
function isPermissionDenied(error) {
|
||||
@@ -81,7 +81,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Apply label command from PR author
|
||||
uses: actions/github-script@v7
|
||||
uses: actions/github-script@v9
|
||||
with:
|
||||
script: |
|
||||
function isPermissionDenied(error) {
|
||||
|
||||
23
.github/workflows/publish_release.yml
vendored
@@ -82,9 +82,11 @@ jobs:
|
||||
# binaries are already unzipped. Copy the inner binary for each platform.
|
||||
# -type f is required (some artifact *folders* are named "*.flatpak").
|
||||
|
||||
# Windows installer: the .exe inside the installer artifact, NOT the
|
||||
# orca-slicer.exe that lives in the portable app folder.
|
||||
find artifacts -type f -name '*.exe' -path '*OrcaSlicer_Windows_*' ! -path '*_portable*' -exec cp -v {} upload/ \;
|
||||
# Windows installers (x64 + arm64): the .exe inside each installer
|
||||
# artifact, NOT the orca-slicer.exe in the portable app folder. CPack
|
||||
# now bakes the arch into the filename (…_x64.exe / …_arm64.exe), so
|
||||
# copy them straight through.
|
||||
find artifacts -type f -name '*.exe' -path '*OrcaSlicer_Windows_V*' ! -path '*_portable*' -exec cp -v {} upload/ \;
|
||||
# macOS universal DMG (profile-validator DMG isn't downloaded).
|
||||
find artifacts -type f -name '*.dmg' -path '*OrcaSlicer_Mac_universal_*' -exec cp -v {} upload/ \;
|
||||
# Linux AppImage.
|
||||
@@ -94,15 +96,16 @@ jobs:
|
||||
# Windows debug symbols (PDB archive, for developers).
|
||||
find artifacts -type f -name 'Debug_PDB_*.7z' -exec cp -v {} upload/ \;
|
||||
|
||||
# Portable Windows build is an unzipped folder artifact; re-zip it to the
|
||||
# released filename (this one stays a .zip on the release).
|
||||
portable_dir=$(find artifacts -maxdepth 1 -type d -name 'OrcaSlicer_Windows_*_portable' | head -n1)
|
||||
if [ -n "${portable_dir:-}" ]; then
|
||||
( cd "$portable_dir" && zip -qr "$GITHUB_WORKSPACE/upload/$(basename "$portable_dir").zip" . )
|
||||
echo "Zipped portable -> $(basename "$portable_dir").zip"
|
||||
else
|
||||
# Portable Windows builds (x64 + arm64) are unzipped folder artifacts;
|
||||
# re-zip each to its released filename (these stay .zip on the release).
|
||||
mapfile -t portable_dirs < <(find artifacts -maxdepth 1 -type d -name 'OrcaSlicer_Windows_*_portable')
|
||||
if [ ${#portable_dirs[@]} -eq 0 ]; then
|
||||
echo "::warning::Windows portable artifact not found."
|
||||
fi
|
||||
for portable_dir in "${portable_dirs[@]}"; do
|
||||
( cd "$portable_dir" && zip -qr "$GITHUB_WORKSPACE/upload/$(basename "$portable_dir").zip" . )
|
||||
echo "Zipped portable -> $(basename "$portable_dir").zip"
|
||||
done
|
||||
|
||||
echo "Assets to upload:"
|
||||
ls -lh upload
|
||||
|
||||
7
.gitignore
vendored
@@ -45,4 +45,9 @@ test.js
|
||||
.clangd
|
||||
internal_docs/
|
||||
*.flatpak
|
||||
/flatpak-repo/
|
||||
/flatpak-repo/
|
||||
# Python bytecode
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.3mf
|
||||
*.gcode
|
||||
|
||||
@@ -85,6 +85,7 @@ else ()
|
||||
endif ()
|
||||
|
||||
find_package(Git)
|
||||
set(GIT_COMMIT_HASH "0000000")
|
||||
if(DEFINED ENV{git_commit_hash} AND NOT "$ENV{git_commit_hash}" STREQUAL "")
|
||||
message(STATUS "Specified git commit hash: $ENV{git_commit_hash}")
|
||||
if(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
@@ -99,7 +100,6 @@ if(DEFINED ENV{git_commit_hash} AND NOT "$ENV{git_commit_hash}" STREQUAL "")
|
||||
# No .git directory (e.g., Flatpak sandbox) — truncate directly
|
||||
string(SUBSTRING "$ENV{git_commit_hash}" 0 7 GIT_COMMIT_HASH)
|
||||
endif()
|
||||
add_definitions("-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
|
||||
elseif(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
# Check current Git commit hash
|
||||
execute_process(
|
||||
@@ -108,7 +108,6 @@ elseif(GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
add_definitions("-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
|
||||
endif()
|
||||
|
||||
if(DEFINED ENV{SLIC3R_STATIC})
|
||||
@@ -434,8 +433,8 @@ if (NOT MSVC AND ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_CXX_COMP
|
||||
|
||||
if((${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "AppleClang") AND ${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER 15)
|
||||
include(CheckCXXCompilerFlag)
|
||||
check_cxx_compiler_flag(-Wno-error=enum-constexpr-conversion HAS_WNO_ERROR_ENUM_CONSTEXPR_CONV)
|
||||
if(HAS_WNO_ERROR_ENUM_CONSTEXPR_CONV)
|
||||
check_cxx_compiler_flag("-Werror=unknown-warning-option -Wno-error=enum-constexpr-conversion" HAS_WNO_ERROR_ENUM_CONSTEXPR_CONV_STRICT)
|
||||
if(HAS_WNO_ERROR_ENUM_CONSTEXPR_CONV_STRICT)
|
||||
add_compile_options(-Wno-error=enum-constexpr-conversion)
|
||||
endif()
|
||||
endif()
|
||||
@@ -510,10 +509,10 @@ include_directories(SYSTEM ${LIBDIR_BIN}/dev-utils/platform)
|
||||
include_directories(SYSTEM ${LIBDIR}/libigl)
|
||||
|
||||
if(WIN32)
|
||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS)
|
||||
add_definitions(-D_USE_MATH_DEFINES -D_WIN32 -D_CRT_SECURE_NO_WARNINGS -D_SCL_SECURE_NO_WARNINGS -DNOMINMAX)
|
||||
if(MSVC)
|
||||
# BOOST_ALL_NO_LIB: Avoid the automatic linking of Boost libraries on Windows. Rather rely on explicit linking.
|
||||
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x602 -DBOOST_SYSTEM_USE_UTF8 )
|
||||
add_definitions(-DBOOST_ALL_NO_LIB -DBOOST_USE_WINAPI_VERSION=0x602 -DBOOST_SYSTEM_USE_UTF8 -DBOOST_REGEX_NO_WIN32_LOCALE)
|
||||
# Force the source code encoding to UTF-8. See OrcaSlicer GH pull request #5583
|
||||
add_compile_options("$<$<C_COMPILER_ID:MSVC>:/utf-8>")
|
||||
add_compile_options("$<$<CXX_COMPILER_ID:MSVC>:/utf-8>")
|
||||
@@ -578,7 +577,7 @@ endif()
|
||||
# boost::process was introduced first in version 1.64.0,
|
||||
# boost::beast::detail::base64 was introduced first in version 1.66.0
|
||||
if(POLICY CMP0167)
|
||||
cmake_policy(SET CMP0167 NEW)
|
||||
cmake_policy(SET CMP0167 OLD)
|
||||
endif()
|
||||
set(Boost_NO_SYSTEM_PATHS TRUE)
|
||||
find_package(Boost 1.83.0 REQUIRED COMPONENTS system filesystem thread log log_setup locale regex chrono atomic date_time iostreams program_options nowide)
|
||||
@@ -934,6 +933,16 @@ set (CPACK_PACKAGE_VERSION_MAJOR "${ORCA_VERSION_MAJOR}")
|
||||
set (CPACK_PACKAGE_VERSION_MINOR "${ORCA_VERSION_MINOR}")
|
||||
set (CPACK_PACKAGE_VERSION_PATCH "${ORCA_VERSION_PATCH}")
|
||||
set (CPACK_PACKAGE_FILE_NAME "OrcaSlicer_Windows_Installer_V${SoftFever_VERSION}")
|
||||
# Suffix the Windows installer with its target arch so the x64 and arm64 builds
|
||||
# produce distinct filenames (matches ARCH_SUFFIX in build_orca.yml). Same
|
||||
# CMAKE_SYSTEM_PROCESSOR mapping used by orcaslicer_copy_dlls() above.
|
||||
if (WIN32)
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
|
||||
string (APPEND CPACK_PACKAGE_FILE_NAME "_arm64")
|
||||
else ()
|
||||
string (APPEND CPACK_PACKAGE_FILE_NAME "_x64")
|
||||
endif ()
|
||||
endif ()
|
||||
set (CPACK_PACKAGE_DESCRIPTION_SUMMARY "Orca Slicer is an open source slicer for FDM printers")
|
||||
set (CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/OrcaSlicer/OrcaSlicer")
|
||||
set (CPACK_PACKAGE_INSTALL_DIRECTORY ${CPACK_PACKAGE_NAME})
|
||||
@@ -946,7 +955,7 @@ set (CPACK_PACKAGE_INSTALL_REGISTRY_KEY "OrcaSlicer")
|
||||
set (CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON)
|
||||
set (CPACK_NSIS_EXECUTABLES_DIRECTORY ".")
|
||||
# set (CPACK_NSIS_MODIFY_PATH "ON")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "orca-slicer;OrcaSlicer")
|
||||
set(CPACK_PACKAGE_EXECUTABLES "orca-slicer;OrcaSlicer-ImageMap")
|
||||
set(CPACK_CREATE_DESKTOP_LINKS "orca-slicer")
|
||||
set (CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt) # must also include in install command
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Fertige Binaries von [OrcaSlicer](https://github.com/SoftFever/OrcaSlicer) mit i
|
||||
|
||||
## Download
|
||||
|
||||
Aktuelle Version: **2.4.0-kx1** (Basis: OrcaSlicer 2.4.0 stable)
|
||||
Aktuelle Version: **2.4.2-kx1** (Basis: OrcaSlicer 2.4.2 stable)
|
||||
|
||||
| Plattform | Datei | Hinweis |
|
||||
|-----------|-------|---------|
|
||||
@@ -27,6 +27,7 @@ macOS wird nicht bereitgestellt — bitte aus dem Upstream selbst bauen.
|
||||
- **AMS-Leerslot-Fix:** leere AMS-Slots werden korrekt grau dargestellt (kein Absturz / falsches Filament)
|
||||
- **Filament-ID:** eindeutige `filament_id` für abgeleitete User-Presets (korrekte Bridge-Synchronisation)
|
||||
- **Kobra X Profile:** Drucker- und G-Code-Profile für den Anycubic Kobra X
|
||||
- **Kobra X Bett-Temp-Fix:** `bed_temperature_formula` auf `by_first_filament` gesetzt — G9111-Makro heizt jetzt auf die korrekte Temperatur des gedruckten Filaments statt auf den Höchstwert aller Projekt-Filamente
|
||||
|
||||
---
|
||||
|
||||
@@ -40,7 +41,7 @@ macOS wird nicht bereitgestellt — bitte aus dem Upstream selbst bauen.
|
||||
|
||||
| Branch | Version | Rolle |
|
||||
|--------|---------|-------|
|
||||
| `stable` / `kx-v2.4` | 2.4.0-kx1 | **aktuell stabil** |
|
||||
| `stable` / `kx-v2.4` | 2.4.1-kx1 | **aktuell stabil** |
|
||||
| `kx-v2.3` | 2.3.2-kx4 | eingefroren (Altstand) |
|
||||
|
||||
---
|
||||
|
||||
@@ -237,6 +237,7 @@ function build_slicer() {
|
||||
resources_path=$(readlink ./OrcaSlicer.app/Contents/Resources)
|
||||
rm ./OrcaSlicer.app/Contents/Resources
|
||||
cp -R "$resources_path" ./OrcaSlicer.app/Contents/Resources
|
||||
plutil -replace CFBundleIconFile -string "images/OrcaSlicer.icns" ./OrcaSlicer.app/Contents/Info.plist
|
||||
# delete .DS_Store file
|
||||
find ./OrcaSlicer.app/ -name '.DS_Store' -delete
|
||||
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
set WP=%CD%
|
||||
set _START_TIME=%TIME%
|
||||
|
||||
@REM Default target architecture to the host CPU arch; override by passing
|
||||
@REM "x64" or "arm64" as an argument. PROCESSOR_ARCHITEW6432 covers a 32-bit
|
||||
@REM shell running on a 64-bit OS, where PROCESSOR_ARCHITECTURE reads "x86".
|
||||
set arch=x64
|
||||
if /I "%PROCESSOR_ARCHITECTURE%"=="ARM64" set arch=ARM64
|
||||
if /I "%PROCESSOR_ARCHITEW6432%"=="ARM64" set arch=ARM64
|
||||
if /I "%1"=="arm64" set arch=ARM64
|
||||
if /I "%2"=="arm64" set arch=ARM64
|
||||
if /I "%1"=="x64" set arch=x64
|
||||
if /I "%2"=="x64" set arch=x64
|
||||
|
||||
@REM Check for Ninja Multi-Config option (-x)
|
||||
set USE_NINJA=0
|
||||
for %%a in (%*) do (
|
||||
@@ -68,12 +79,13 @@ echo Using CMake generator: %CMAKE_GENERATOR%
|
||||
|
||||
@REM Pack deps
|
||||
if "%1"=="pack" (
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
setlocal ENABLEDELAYEDEXPANSION
|
||||
cd %WP%/deps/build
|
||||
if "%arch%"=="ARM64" cd %WP%/deps/build-arm64
|
||||
for /f "tokens=2-4 delims=/ " %%a in ('date /t') do set build_date=%%c%%b%%a
|
||||
echo packing deps: OrcaSlicer_dep_win64_!build_date!_vs!VS_VERSION!.zip
|
||||
echo packing deps: OrcaSlicer_dep_win-!arch!_!build_date!_vs!VS_VERSION!.zip
|
||||
|
||||
%WP%/tools/7z.exe a OrcaSlicer_dep_win64_!build_date!_vs!VS_VERSION!.zip OrcaSlicer_dep
|
||||
%WP%/tools/7z.exe a OrcaSlicer_dep_win-!arch!_!build_date!_vs!VS_VERSION!.zip OrcaSlicer_dep
|
||||
goto :done
|
||||
)
|
||||
|
||||
@@ -95,9 +107,10 @@ if "%debug%"=="ON" (
|
||||
set build_dir=build
|
||||
)
|
||||
)
|
||||
echo build type set to %build_type%
|
||||
if "%arch%"=="ARM64" set build_dir=%build_dir%-arm64
|
||||
echo build type set to %build_type%, arch=%arch%
|
||||
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
cd deps
|
||||
mkdir %build_dir%
|
||||
cd %build_dir%
|
||||
@@ -116,7 +129,7 @@ if "%USE_NINJA%"=="1" (
|
||||
cmake ../ -G %CMAKE_GENERATOR% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target deps
|
||||
) else (
|
||||
cmake ../ -G %CMAKE_GENERATOR% -A x64 -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake ../ -G %CMAKE_GENERATOR% -A %arch% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target deps -- -m
|
||||
)
|
||||
@echo off
|
||||
@@ -135,7 +148,7 @@ if "%USE_NINJA%"=="1" (
|
||||
cmake .. -G %CMAKE_GENERATOR% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target ALL_BUILD
|
||||
) else (
|
||||
cmake .. -G %CMAKE_GENERATOR% -A x64 -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake .. -G %CMAKE_GENERATOR% -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target ALL_BUILD -- -m
|
||||
)
|
||||
@echo off
|
||||
|
||||
@@ -15,10 +15,18 @@ if "%1"=="pack" (
|
||||
|
||||
set debug=OFF
|
||||
set debuginfo=OFF
|
||||
@REM Default target architecture to the host CPU arch; override with x64/arm64 arg.
|
||||
set arch=x64
|
||||
if /I "%PROCESSOR_ARCHITECTURE%"=="ARM64" set arch=ARM64
|
||||
if /I "%PROCESSOR_ARCHITEW6432%"=="ARM64" set arch=ARM64
|
||||
if "%1"=="debug" set debug=ON
|
||||
if "%2"=="debug" set debug=ON
|
||||
if "%1"=="debuginfo" set debuginfo=ON
|
||||
if "%2"=="debuginfo" set debuginfo=ON
|
||||
if /I "%1"=="arm64" set arch=ARM64
|
||||
if /I "%2"=="arm64" set arch=ARM64
|
||||
if /I "%1"=="x64" set arch=x64
|
||||
if /I "%2"=="x64" set arch=x64
|
||||
if "%debug%"=="ON" (
|
||||
set build_type=Debug
|
||||
set build_dir=build-dbg
|
||||
@@ -31,7 +39,8 @@ if "%debug%"=="ON" (
|
||||
set build_dir=build
|
||||
)
|
||||
)
|
||||
echo build type set to %build_type%
|
||||
if "%arch%"=="ARM64" set build_dir=%build_dir%-arm64
|
||||
echo build type set to %build_type%, arch=%arch%
|
||||
|
||||
setlocal DISABLEDELAYEDEXPANSION
|
||||
cd deps
|
||||
@@ -48,7 +57,7 @@ echo "building deps.."
|
||||
echo on
|
||||
REM Set minimum CMake policy to avoid <3.5 errors
|
||||
set CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
cmake ../ -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake ../ -G "Visual Studio 17 2022" -A %arch% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target deps -- -m
|
||||
@echo off
|
||||
|
||||
@@ -62,7 +71,7 @@ cd %build_dir%
|
||||
|
||||
echo on
|
||||
set CMAKE_POLICY_VERSION_MINIMUM=3.5
|
||||
cmake .. -G "Visual Studio 17 2022" -A x64 -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake .. -G "Visual Studio 17 2022" -A %arch% -DORCA_TOOLS=ON %SIG_FLAG% -DCMAKE_BUILD_TYPE=%build_type%
|
||||
cmake --build . --config %build_type% --target ALL_BUILD -- -m
|
||||
@echo off
|
||||
cd ..
|
||||
|
||||
34
cmake/GenerateSoftFeverVersion.cmake
Normal file
@@ -0,0 +1,34 @@
|
||||
if(NOT DEFINED INPUT)
|
||||
message(FATAL_ERROR "INPUT is required")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED OUTPUT)
|
||||
message(FATAL_ERROR "OUTPUT is required")
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED GIT_COMMIT_HASH)
|
||||
set(GIT_COMMIT_HASH "0000000")
|
||||
endif()
|
||||
|
||||
file(STRINGS "${INPUT}" SOFTFEVER_VERSION LIMIT_COUNT 1)
|
||||
string(STRIP "${SOFTFEVER_VERSION}" SOFTFEVER_VERSION)
|
||||
|
||||
set(CONTENT [=[
|
||||
#include "libslic3r_version.h"
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
const char* softfever_version()
|
||||
{
|
||||
return "@SOFTFEVER_VERSION@";
|
||||
}
|
||||
|
||||
const char* git_commit_hash()
|
||||
{
|
||||
return "@GIT_COMMIT_HASH@";
|
||||
}
|
||||
|
||||
} // namespace Slic3r
|
||||
]=])
|
||||
string(CONFIGURE "${CONTENT}" CONTENT @ONLY)
|
||||
file(WRITE "${OUTPUT}" "${CONTENT}")
|
||||
@@ -124,6 +124,8 @@ endif()
|
||||
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" MATCHES "x64" OR "${CMAKE_GENERATOR}" MATCHES "Win64")
|
||||
set(_arch "x64")
|
||||
elseif("${CMAKE_GENERATOR_PLATFORM}" MATCHES "ARM64")
|
||||
set(_arch "x64") # GLEW ships one header set; ARM64 uses the x64 import path
|
||||
else()
|
||||
set(_arch "Win32")
|
||||
endif()
|
||||
|
||||
15
deps/Boost/Boost.cmake
vendored
@@ -10,6 +10,20 @@ if (APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
set(_context_arch_line "-DBOOST_CONTEXT_ARCHITECTURE:STRING=${CMAKE_OSX_ARCHITECTURES}")
|
||||
endif ()
|
||||
|
||||
# Windows ARM64: Boost.Context's default fcontext implementation assembles .asm
|
||||
# via armasm64, which trips a CMake ASM_ARMASM linker-module bug under the VS
|
||||
# generator. The winfib implementation (Windows Fiber API) avoids assembly while
|
||||
# keeping the Boost::context target that Boost.Asio's stackful coroutines need.
|
||||
set(_context_impl_line "")
|
||||
if (MSVC AND "${DEPS_ARCH}" STREQUAL "arm64")
|
||||
set(_context_impl_line "-DBOOST_CONTEXT_IMPLEMENTATION:STRING=winfib")
|
||||
endif ()
|
||||
|
||||
set(_options "")
|
||||
if (MSVC AND DEP_DEBUG)
|
||||
set(_options "FORWARD_CONFIG")
|
||||
endif ()
|
||||
|
||||
orcaslicer_add_cmake_project(Boost
|
||||
URL "https://github.com/boostorg/boost/releases/download/boost-1.84.0/boost-1.84.0.tar.gz"
|
||||
URL_HASH SHA256=4d27e9efed0f6f152dc28db6430b9d3dfb40c0345da7342eaa5a987dde57bd95
|
||||
@@ -22,6 +36,7 @@ orcaslicer_add_cmake_project(Boost
|
||||
-DBOOST_IOSTREAMS_ENABLE_ZSTD:BOOL=OFF
|
||||
"${_context_abi_line}"
|
||||
"${_context_arch_line}"
|
||||
"${_context_impl_line}"
|
||||
)
|
||||
|
||||
set(DEP_Boost_DEPENDS ZLIB)
|
||||
BIN
deps/GMP/gmp/lib/win-arm64/libgmp-10.dll
vendored
Normal file
BIN
deps/GMP/gmp/lib/win-arm64/libgmp-10.lib
vendored
Normal file
BIN
deps/MPFR/mpfr/lib/win-arm64/libmpfr-4.dll
vendored
Normal file
BIN
deps/MPFR/mpfr/lib/win-arm64/libmpfr-4.lib
vendored
Normal file
4
deps/OpenCV/OpenCV.cmake
vendored
@@ -1,4 +1,6 @@
|
||||
if (MSVC)
|
||||
# Intel IPP / IPP-ICV is x86/x64 only — there is no ARM64 build, so enabling it
|
||||
# leaves ~200 unresolved ippicv* externals at link time on Windows ARM64.
|
||||
if (MSVC AND NOT "${DEPS_ARCH}" STREQUAL "arm64")
|
||||
set(_use_IPP "-DWITH_IPP=ON")
|
||||
else ()
|
||||
set(_use_IPP "-DWITH_IPP=OFF")
|
||||
|
||||
12
deps/OpenEXR/OpenEXR.cmake
vendored
@@ -32,6 +32,17 @@ else()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
set(_patch_cmd ${PATCH_CMD} ${CMAKE_CURRENT_LIST_DIR}/0001-OpenEXR-GCC13.patch)
|
||||
elseif (MSVC AND "${DEPS_ARCH}" STREQUAL "arm64")
|
||||
# Windows ARM64: OpenEXR 2.5.5 hard-codes IMF_HAVE_SSE2 for any MSVC
|
||||
# (ImfSimd.h: `_MSC_VER >= 1300`), pulling in <emmintrin.h> (x86-only) -> C1189.
|
||||
# Patch the header to require an x86 target, and force the SSE cache vars off.
|
||||
set(_patch_cmd ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_LIST_DIR}/patch_openexr_arm64.cmake)
|
||||
set(_openexr_arm64_args
|
||||
-DOPENEXR_IMF_HAVE_SSE2:BOOL=OFF
|
||||
-DOPENEXR_IMF_HAVE_SSSE3:BOOL=OFF
|
||||
-DILMBASE_HAVE_SSE:BOOL=OFF
|
||||
-DILMBASE_FORCE_DISABLE_INTEL_SSE:BOOL=ON
|
||||
)
|
||||
else ()
|
||||
set(_patch_cmd "")
|
||||
endif ()
|
||||
@@ -49,6 +60,7 @@ orcaslicer_add_cmake_project(OpenEXR
|
||||
-DPYILMBASE_ENABLE:BOOL=OFF
|
||||
-DOPENEXR_VIEWERS_ENABLE:BOOL=OFF
|
||||
-DOPENEXR_BUILD_UTILS:BOOL=OFF
|
||||
${_openexr_arm64_args}
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
29
deps/OpenEXR/patch_openexr_arm64.cmake
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
# Applied as PATCH_COMMAND for OpenEXR 2.5.5 on Windows ARM64.
|
||||
#
|
||||
# Root cause of the ARM64 build failure: OpenEXR/IlmImf/ImfSimd.h hard-codes
|
||||
# #if defined __SSE2__ || (_MSC_VER >= 1300 && !_M_CEE_PURE)
|
||||
# #define IMF_HAVE_SSE2 1
|
||||
# #endif
|
||||
# The `_MSC_VER >= 1300` arm is true for *every* MSVC, including ARM64, so
|
||||
# IMF_HAVE_SSE2 gets defined and <emmintrin.h> (an x86-only header) is pulled
|
||||
# in -> error C1189. This is a pure-preprocessor decision, so no CMake cache
|
||||
# variable can suppress it. Patch the header to also require an x86 target.
|
||||
|
||||
set(_simd "OpenEXR/IlmImf/ImfSimd.h")
|
||||
if(EXISTS "${_simd}")
|
||||
file(READ "${_simd}" _content)
|
||||
set(_old "#if defined __SSE2__ || (_MSC_VER >= 1300 && !_M_CEE_PURE)")
|
||||
set(_new "#if (defined __SSE2__ || (_MSC_VER >= 1300 && !_M_CEE_PURE)) && (defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || defined(__x86_64__))")
|
||||
if(_content MATCHES "_M_IX86")
|
||||
message(STATUS "[ARM64 patch] ImfSimd.h already guarded")
|
||||
else()
|
||||
string(REPLACE "${_old}" "${_new}" _patched "${_content}")
|
||||
if(_patched STREQUAL _content)
|
||||
message(FATAL_ERROR "[ARM64 patch] Failed to match SSE2 guard in ${_simd}")
|
||||
endif()
|
||||
file(WRITE "${_simd}" "${_patched}")
|
||||
message(STATUS "[ARM64 patch] Guarded IMF_HAVE_SSE2 with x86 arch check in ${_simd}")
|
||||
endif()
|
||||
else()
|
||||
message(FATAL_ERROR "[ARM64 patch] Not found: ${_simd}")
|
||||
endif()
|
||||
6
deps/OpenSSL/OpenSSL.cmake
vendored
@@ -6,7 +6,11 @@ if(DEFINED OPENSSL_ARCH)
|
||||
set(_cross_arch ${OPENSSL_ARCH})
|
||||
else()
|
||||
if(WIN32)
|
||||
set(_cross_arch "VC-WIN64A")
|
||||
if("${CMAKE_GENERATOR_PLATFORM}" STREQUAL "ARM64")
|
||||
set(_cross_arch "VC-WIN64-ARM")
|
||||
else()
|
||||
set(_cross_arch "VC-WIN64A")
|
||||
endif()
|
||||
elseif(APPLE)
|
||||
set(_cross_arch "darwin64-${CMAKE_OSX_ARCHITECTURES}-cc")
|
||||
endif()
|
||||
|
||||
@@ -30,6 +30,10 @@ add_subdirectory(md4c)
|
||||
add_subdirectory(mdns)
|
||||
add_subdirectory(miniz)
|
||||
add_subdirectory(minilzo)
|
||||
add_subdirectory(pigment-painter)
|
||||
add_subdirectory(prusa-fdm-mixer)
|
||||
add_subdirectory(colorsolver)
|
||||
add_subdirectory(qhull)
|
||||
add_subdirectory(qoi)
|
||||
add_subdirectory(semver) # Semver static library
|
||||
add_subdirectory(tinygltf)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(Clipper2 VERSION 1.5.2 LANGUAGES C CXX)
|
||||
project(Clipper2 VERSION 2.0.1 LANGUAGES C CXX)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
@@ -19,6 +19,7 @@ set(CLIPPER2_INC
|
||||
Clipper2Lib/include/clipper2/clipper.minkowski.h
|
||||
Clipper2Lib/include/clipper2/clipper.offset.h
|
||||
Clipper2Lib/include/clipper2/clipper.rectclip.h
|
||||
Clipper2Lib/include/clipper2/clipper.triangulation.h
|
||||
Clipper2Lib/include/clipper2/clipper2_z.hpp
|
||||
)
|
||||
|
||||
@@ -26,6 +27,7 @@ set(CLIPPER2_SRC
|
||||
Clipper2Lib/src/clipper.engine.cpp
|
||||
Clipper2Lib/src/clipper.offset.cpp
|
||||
Clipper2Lib/src/clipper.rectclip.cpp
|
||||
Clipper2Lib/src/clipper.triangulation.cpp
|
||||
Clipper2Lib/src/clipper2_z.cpp
|
||||
)
|
||||
|
||||
@@ -51,4 +53,3 @@ set_target_properties(Clipper2 PROPERTIES FOLDER Libraries
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
PUBLIC_HEADER "${CLIPPER2_INC}"
|
||||
)
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 12 May 2024 *
|
||||
* Date : 12 October 2025 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2024 *
|
||||
* Copyright : Angus Johnson 2010-2025 *
|
||||
* Purpose : Core Clipper Library structures and functions *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
@@ -141,7 +141,7 @@ namespace Clipper2Lib {
|
||||
}
|
||||
}
|
||||
|
||||
explicit Point() : x(0), y(0), z(0) {};
|
||||
explicit Point() : x(0), y(0), z(0) {}
|
||||
|
||||
template <typename T2>
|
||||
Point(const T2 x_, const T2 y_, const z_type z_ = 0)
|
||||
@@ -193,7 +193,7 @@ namespace Clipper2Lib {
|
||||
}
|
||||
}
|
||||
|
||||
explicit Point() : x(0), y(0) {};
|
||||
explicit Point() : x(0), y(0) {}
|
||||
|
||||
template <typename T2>
|
||||
Point(const T2 x_, const T2 y_) { Init(x_, y_); }
|
||||
@@ -251,6 +251,20 @@ namespace Clipper2Lib {
|
||||
template <typename T>
|
||||
using Paths = std::vector<Path<T>>;
|
||||
|
||||
template <typename T, typename T2=T>
|
||||
Path<T>& operator<<(Path<T>& poly, const Point<T2>& p)
|
||||
{
|
||||
poly.emplace_back(p);
|
||||
return poly;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Paths<T>& operator<<(Paths<T>& polys, const Path<T>& p)
|
||||
{
|
||||
polys.emplace_back(p);
|
||||
return polys;
|
||||
}
|
||||
|
||||
using Path64 = Path<int64_t>;
|
||||
using PathD = Path<double>;
|
||||
using Paths64 = std::vector< Path64>;
|
||||
@@ -356,13 +370,13 @@ namespace Clipper2Lib {
|
||||
bottom *= scale;
|
||||
}
|
||||
|
||||
bool IsEmpty() const { return bottom <= top || right <= left; };
|
||||
bool IsEmpty() const { return bottom <= top || right <= left; }
|
||||
|
||||
bool Intersects(const Rect<T>& rec) const
|
||||
{
|
||||
return ((std::max)(left, rec.left) <= (std::min)(right, rec.right)) &&
|
||||
((std::max)(top, rec.top) <= (std::min)(bottom, rec.bottom));
|
||||
};
|
||||
}
|
||||
|
||||
bool operator==(const Rect<T>& other) const {
|
||||
return left == other.left && right == other.right &&
|
||||
@@ -688,29 +702,28 @@ namespace Clipper2Lib {
|
||||
return (x > 0) - (x < 0);
|
||||
}
|
||||
|
||||
struct MultiplyUInt64Result
|
||||
struct UInt128Struct
|
||||
{
|
||||
const uint64_t result = 0;
|
||||
const uint64_t carry = 0;
|
||||
const uint64_t lo = 0;
|
||||
const uint64_t hi = 0;
|
||||
|
||||
bool operator==(const MultiplyUInt64Result& other) const
|
||||
bool operator==(const UInt128Struct& other) const
|
||||
{
|
||||
return result == other.result && carry == other.carry;
|
||||
};
|
||||
return lo == other.lo && hi == other.hi;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
inline MultiplyUInt64Result Multiply(uint64_t a, uint64_t b) // #834, #835
|
||||
inline UInt128Struct MultiplyUInt64(uint64_t a, uint64_t b) // #834, #835
|
||||
{
|
||||
// note to self - lamba expressions follow
|
||||
const auto lo = [](uint64_t x) { return x & 0xFFFFFFFF; };
|
||||
const auto hi = [](uint64_t x) { return x >> 32; };
|
||||
|
||||
const uint64_t x1 = lo(a) * lo(b);
|
||||
const uint64_t x2 = hi(a) * lo(b) + hi(x1);
|
||||
const uint64_t x3 = lo(a) * hi(b) + lo(x2);
|
||||
const uint64_t result = lo(x3) << 32 | lo(x1);
|
||||
const uint64_t carry = hi(a) * hi(b) + hi(x2) + hi(x3);
|
||||
|
||||
return { result, carry };
|
||||
return { uint64_t(lo(x3) << 32 | lo(x1)), uint64_t(hi(a) * hi(b) + hi(x2) + hi(x3)) };
|
||||
}
|
||||
|
||||
// returns true if (and only if) a * b == c * d
|
||||
@@ -727,14 +740,50 @@ namespace Clipper2Lib {
|
||||
const auto abs_c = static_cast<uint64_t>(std::abs(c));
|
||||
const auto abs_d = static_cast<uint64_t>(std::abs(d));
|
||||
|
||||
const auto abs_ab = Multiply(abs_a, abs_b);
|
||||
const auto abs_cd = Multiply(abs_c, abs_d);
|
||||
const auto ab = MultiplyUInt64(abs_a, abs_b);
|
||||
const auto cd = MultiplyUInt64(abs_c, abs_d);
|
||||
|
||||
// nb: it's important to differentiate 0 values here from other values
|
||||
const auto sign_ab = TriSign(a) * TriSign(b);
|
||||
const auto sign_cd = TriSign(c) * TriSign(d);
|
||||
|
||||
return abs_ab == abs_cd && sign_ab == sign_cd;
|
||||
return ab == cd && sign_ab == sign_cd;
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline int CrossProductSign(const Point<T>& pt1, const Point<T>& pt2, const Point<T>& pt3)
|
||||
{
|
||||
const auto a = pt2.x - pt1.x;
|
||||
const auto b = pt3.y - pt2.y;
|
||||
const auto c = pt2.y - pt1.y;
|
||||
const auto d = pt3.x - pt2.x;
|
||||
|
||||
#if (defined(__clang__) || defined(__GNUC__)) && UINTPTR_MAX >= UINT64_MAX
|
||||
const auto ab = static_cast<__int128_t>(a) * static_cast<__int128_t>(b);
|
||||
const auto cd = static_cast<__int128_t>(c) * static_cast<__int128_t>(d);
|
||||
if (ab > cd) return 1;
|
||||
else if (ab < cd) return -1;
|
||||
else return 0;
|
||||
#else
|
||||
const auto ab = MultiplyUInt64(std::abs(a), std::abs(b));
|
||||
const auto cd = MultiplyUInt64(std::abs(c), std::abs(d));
|
||||
|
||||
const auto sign_ab = TriSign(a) * TriSign(b);
|
||||
const auto sign_cd = TriSign(c) * TriSign(d);
|
||||
|
||||
if (sign_ab == sign_cd)
|
||||
{
|
||||
int result;
|
||||
if (ab.hi == cd.hi)
|
||||
{
|
||||
if (ab.lo == cd.lo) return 0;
|
||||
result = (ab.lo > cd.lo) ? 1 : -1;
|
||||
}
|
||||
else result = (ab.hi > cd.hi) ? 1 : -1;
|
||||
return (sign_ab > 0) ? result : -result;
|
||||
}
|
||||
return (sign_ab > sign_cd) ? 1 : -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -838,14 +887,18 @@ namespace Clipper2Lib {
|
||||
return Area<T>(poly) >= 0;
|
||||
}
|
||||
|
||||
#if CLIPPER2_HI_PRECISION
|
||||
// GetLineIntersectPt - a 'true' result is non-parallel. The 'ip' will also
|
||||
// be constrained to seg1. However, it's possible that 'ip' won't be inside
|
||||
// seg2, even when 'ip' hasn't been constrained (ie 'ip' is inside seg1).
|
||||
|
||||
#if defined(CLIPPER2_HI_PRECISION) && CLIPPER2_HI_PRECISION
|
||||
// caution: this will compromise performance
|
||||
// https://github.com/AngusJohnson/Clipper2/issues/317#issuecomment-1314023253
|
||||
// See also CPP/BenchMark/GetIntersectPtBenchmark.cpp
|
||||
#define CC_MIN(x,y) ((x)>(y)?(y):(x))
|
||||
#define CC_MAX(x,y) ((x)<(y)?(y):(x))
|
||||
template<typename T>
|
||||
inline bool GetSegmentIntersectPt(const Point<T>& ln1a, const Point<T>& ln1b,
|
||||
inline bool GetLineIntersectPt(const Point<T>& ln1a, const Point<T>& ln1b,
|
||||
const Point<T>& ln2a, const Point<T>& ln2b, Point<T>& ip)
|
||||
{
|
||||
double ln1dy = static_cast<double>(ln1b.y - ln1a.y);
|
||||
@@ -891,11 +944,14 @@ namespace Clipper2Lib {
|
||||
ip.x = originx + static_cast<T>(hitx);
|
||||
ip.y = originy + static_cast<T>(hity);
|
||||
}
|
||||
#ifdef USINGZ
|
||||
ip.z = 0;
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
template<typename T>
|
||||
inline bool GetSegmentIntersectPt(const Point<T>& ln1a, const Point<T>& ln1b,
|
||||
inline bool GetLineIntersectPt(const Point<T>& ln1a, const Point<T>& ln1b,
|
||||
const Point<T>& ln2a, const Point<T>& ln2b, Point<T>& ip)
|
||||
{
|
||||
// https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
|
||||
@@ -913,7 +969,10 @@ namespace Clipper2Lib {
|
||||
{
|
||||
ip.x = static_cast<T>(ln1a.x + t * dx1);
|
||||
ip.y = static_cast<T>(ln1a.y + t * dy1);
|
||||
}
|
||||
#ifdef USINGZ
|
||||
ip.z = 0;
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -949,21 +1008,44 @@ namespace Clipper2Lib {
|
||||
inline bool SegmentsIntersect(const Point64& seg1a, const Point64& seg1b,
|
||||
const Point64& seg2a, const Point64& seg2b, bool inclusive = false)
|
||||
{
|
||||
double dy1 = static_cast<double>(seg1b.y - seg1a.y);
|
||||
double dx1 = static_cast<double>(seg1b.x - seg1a.x);
|
||||
double dy2 = static_cast<double>(seg2b.y - seg2a.y);
|
||||
double dx2 = static_cast<double>(seg2b.x - seg2a.x);
|
||||
double cp = dy1 * dx2 - dy2 * dx1;
|
||||
if (cp == 0) return false; // ie parallel segments
|
||||
|
||||
if (inclusive)
|
||||
{
|
||||
double res1 = CrossProduct(seg1a, seg2a, seg2b);
|
||||
double res2 = CrossProduct(seg1b, seg2a, seg2b);
|
||||
if (res1 * res2 > 0) return false;
|
||||
double res3 = CrossProduct(seg2a, seg1a, seg1b);
|
||||
double res4 = CrossProduct(seg2b, seg1a, seg1b);
|
||||
if (res3 * res4 > 0) return false;
|
||||
return (res1 || res2 || res3 || res4); // ensures not collinear
|
||||
//result **includes** segments that touch at an end point
|
||||
double t = ((seg1a.x - seg2a.x) * dy2 - (seg1a.y - seg2a.y) * dx2);
|
||||
if (t == 0) return true;
|
||||
if (t > 0)
|
||||
{
|
||||
if (cp < 0 || t > cp) return false;
|
||||
}
|
||||
else if (cp > 0 || t < cp) return false; // false when t more neg. than cp
|
||||
|
||||
t = ((seg1a.x - seg2a.x) * dy1 - (seg1a.y - seg2a.y) * dx1);
|
||||
if (t == 0) return true;
|
||||
if (t > 0) return (cp > 0 && t <= cp);
|
||||
else return (cp < 0 && t >= cp); // true when t less neg. than cp
|
||||
}
|
||||
else {
|
||||
return (GetSign(CrossProduct(seg1a, seg2a, seg2b)) *
|
||||
GetSign(CrossProduct(seg1b, seg2a, seg2b)) < 0) &&
|
||||
(GetSign(CrossProduct(seg2a, seg1a, seg1b)) *
|
||||
GetSign(CrossProduct(seg2b, seg1a, seg1b)) < 0);
|
||||
else
|
||||
{
|
||||
//result **excludes** segments that touch at an end point
|
||||
double t = ((seg1a.x - seg2a.x) * dy2 - (seg1a.y - seg2a.y) * dx2);
|
||||
if (t == 0) return false;
|
||||
if (t > 0)
|
||||
{
|
||||
if (cp < 0 || t >= cp) return false;
|
||||
}
|
||||
else if (cp > 0 || t <= cp ) return false; // false when t more neg. than cp
|
||||
|
||||
t = ((seg1a.x - seg2a.x) * dy1 - (seg1a.y - seg2a.y) * dx1);
|
||||
if (t == 0) return false;
|
||||
if (t > 0) return (cp > 0 && t < cp);
|
||||
else return (cp < 0 && t > cp); // true when t less neg. than cp
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1051,7 +1133,7 @@ namespace Clipper2Lib {
|
||||
val = 1 - val; // toggle val
|
||||
else
|
||||
{
|
||||
double d = CrossProduct(*prev, *curr, pt);
|
||||
int d = CrossProductSign(*prev, *curr, pt);
|
||||
if (d == 0) return PointInPolygonResult::IsOn;
|
||||
if ((d < 0) == is_above) val = 1 - val;
|
||||
}
|
||||
@@ -1065,7 +1147,7 @@ namespace Clipper2Lib {
|
||||
if (curr == cend) curr = cbegin;
|
||||
if (curr == cbegin) prev = cend - 1;
|
||||
else prev = curr - 1;
|
||||
double d = CrossProduct(*prev, *curr, pt);
|
||||
int d = CrossProductSign(*prev, *curr, pt);
|
||||
if (d == 0) return PointInPolygonResult::IsOn;
|
||||
if ((d < 0) == is_above) val = 1 - val;
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ namespace Clipper2Lib {
|
||||
if (splits) delete splits;
|
||||
// nb: don't delete the split pointers
|
||||
// as these are owned by ClipperBase's outrec_list_
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
@@ -160,7 +160,7 @@ namespace Clipper2Lib {
|
||||
struct HorzJoin {
|
||||
OutPt* op1 = nullptr;
|
||||
OutPt* op2 = nullptr;
|
||||
HorzJoin() {};
|
||||
HorzJoin() {}
|
||||
explicit HorzJoin(OutPt* ltr, OutPt* rtl) : op1(ltr), op2(rtl) { }
|
||||
};
|
||||
|
||||
@@ -280,11 +280,11 @@ namespace Clipper2Lib {
|
||||
void AddPaths(const Paths64& paths, PathType polytype, bool is_open);
|
||||
public:
|
||||
virtual ~ClipperBase();
|
||||
int ErrorCode() const { return error_code_; };
|
||||
void PreserveCollinear(bool val) { preserve_collinear_ = val; };
|
||||
bool PreserveCollinear() const { return preserve_collinear_;};
|
||||
void ReverseSolution(bool val) { reverse_solution_ = val; };
|
||||
bool ReverseSolution() const { return reverse_solution_; };
|
||||
int ErrorCode() const { return error_code_; }
|
||||
void PreserveCollinear(bool val) { preserve_collinear_ = val; }
|
||||
bool PreserveCollinear() const { return preserve_collinear_;}
|
||||
void ReverseSolution(bool val) { reverse_solution_ = val; }
|
||||
bool ReverseSolution() const { return reverse_solution_; }
|
||||
void Clear();
|
||||
void AddReuseableData(const ReuseableDataContainer64& reuseable_data);
|
||||
#ifdef USINGZ
|
||||
@@ -304,7 +304,7 @@ namespace Clipper2Lib {
|
||||
PolyPath* parent_;
|
||||
public:
|
||||
PolyPath(PolyPath* parent = nullptr): parent_(parent){}
|
||||
virtual ~PolyPath() {};
|
||||
virtual ~PolyPath() {}
|
||||
//https://en.cppreference.com/w/cpp/language/rule_of_three
|
||||
PolyPath(const PolyPath&) = delete;
|
||||
PolyPath& operator=(const PolyPath&) = delete;
|
||||
@@ -352,7 +352,7 @@ namespace Clipper2Lib {
|
||||
explicit PolyPath64(PolyPath64* parent = nullptr) : PolyPath(parent) {}
|
||||
explicit PolyPath64(PolyPath64* parent, const Path64& path) : PolyPath(parent) { polygon_ = path; }
|
||||
|
||||
~PolyPath64() {
|
||||
~PolyPath64() override {
|
||||
childs_.resize(0);
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ namespace Clipper2Lib {
|
||||
return childs_.size();
|
||||
}
|
||||
|
||||
const Path64& Polygon() const { return polygon_; };
|
||||
const Path64& Polygon() const { return polygon_; }
|
||||
|
||||
double Area() const
|
||||
{
|
||||
@@ -418,7 +418,7 @@ namespace Clipper2Lib {
|
||||
polygon_ = path;
|
||||
}
|
||||
|
||||
~PolyPathD() {
|
||||
~PolyPathD() override {
|
||||
childs_.resize(0);
|
||||
}
|
||||
|
||||
@@ -458,7 +458,7 @@ namespace Clipper2Lib {
|
||||
return childs_.size();
|
||||
}
|
||||
|
||||
const PathD& Polygon() const { return polygon_; };
|
||||
const PathD& Polygon() const { return polygon_; }
|
||||
|
||||
double Area() const
|
||||
{
|
||||
@@ -548,7 +548,7 @@ namespace Clipper2Lib {
|
||||
}
|
||||
|
||||
#ifdef USINGZ
|
||||
void SetZCallback(ZCallbackD cb) { zCallbackD_ = cb; };
|
||||
void SetZCallback(ZCallbackD cb) { zCallbackD_ = cb; }
|
||||
|
||||
void ZCB(const Point64& e1bot, const Point64& e1top,
|
||||
const Point64& e2bot, const Point64& e2top, Point64& pt)
|
||||
@@ -564,7 +564,7 @@ namespace Clipper2Lib {
|
||||
PointD e2t = PointD(e2top) * invScale_;
|
||||
zCallbackD_(e1b,e1t, e2b, e2t, tmp);
|
||||
pt.z = tmp.z; // only update 'z'
|
||||
};
|
||||
}
|
||||
|
||||
void CheckCallback()
|
||||
{
|
||||
|
||||
@@ -116,6 +116,7 @@ the four vertices that define the two segments that are intersecting.
|
||||
#include "clipper2/clipper.engine.h"
|
||||
#include "clipper2/clipper.offset.h"
|
||||
#include "clipper2/clipper.rectclip.h"
|
||||
#include "clipper2/clipper.triangulation.h"
|
||||
#include <cstdlib>
|
||||
|
||||
#ifdef USINGZ
|
||||
@@ -816,6 +817,24 @@ EXTERN_DLL_EXPORT CPaths64 MinkowskiDiff64(const CPath64& cpattern, const CPath6
|
||||
return CreateCPathsFromPathsT(solution);
|
||||
}
|
||||
|
||||
EXTERN_DLL_EXPORT CPaths64 Triangulate64(const CPaths64 paths, bool use_delaunay)
|
||||
{
|
||||
Paths64 pp = ConvertCPathsToPathsT(paths);
|
||||
Paths64 sol;
|
||||
if (Triangulate(pp, sol, use_delaunay) != TriangulateResult::success) return nullptr;
|
||||
return CreateCPathsFromPathsT(sol);
|
||||
}
|
||||
|
||||
EXTERN_DLL_EXPORT CPathsD TriangulateD(const CPathsD paths, int decimal_precison, bool use_delaunay)
|
||||
{
|
||||
if (decimal_precison < -8 || decimal_precison > 8) return nullptr;
|
||||
const double scale = std::pow(10, decimal_precison);
|
||||
Paths64 pp = ConvertCPathsDToPaths64(paths, scale);
|
||||
Paths64 sol;
|
||||
if (Triangulate(pp, sol, use_delaunay) != TriangulateResult::success) return nullptr;
|
||||
return CreateCPathsDFromPaths64(sol, 1 / scale);
|
||||
}
|
||||
|
||||
#ifdef USINGZ
|
||||
typedef void (*DLLZCallback64)(const Point64& e1bot, const Point64& e1top, const Point64& e2bot, const Point64& e2top, Point64& pt);
|
||||
typedef void (*DLLZCallbackD)(const PointD& e1bot, const PointD& e1top, const PointD& e2bot, const PointD& e2top, PointD& pt);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 27 April 2024 *
|
||||
* Date : 5 March 2025 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2024 *
|
||||
* Copyright : Angus Johnson 2010-2025 *
|
||||
* Purpose : This module provides a simple interface to the Clipper Library *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
@@ -13,8 +13,9 @@
|
||||
#include "clipper2/clipper.core.h"
|
||||
#include "clipper2/clipper.engine.h"
|
||||
#include "clipper2/clipper.offset.h"
|
||||
#include "clipper2/clipper.minkowski.h"
|
||||
#include "clipper2/clipper.rectclip.h"
|
||||
#include "clipper2/clipper.minkowski.h"
|
||||
#include "clipper2/clipper.triangulation.h"
|
||||
#include <type_traits>
|
||||
|
||||
#ifdef USINGZ
|
||||
@@ -137,7 +138,7 @@
|
||||
JoinType jt, EndType et, double miter_limit = 2.0,
|
||||
double arc_tolerance = 0.0)
|
||||
{
|
||||
if (!delta) return paths;
|
||||
if (delta==0.0) return paths;
|
||||
ClipperOffset clip_offset(miter_limit, arc_tolerance);
|
||||
clip_offset.AddPaths(paths, jt, et);
|
||||
Paths64 solution;
|
||||
@@ -151,10 +152,10 @@
|
||||
{
|
||||
int error_code = 0;
|
||||
CheckPrecisionRange(precision, error_code);
|
||||
if (!delta) return paths;
|
||||
if (delta==0.0) return paths;
|
||||
if (error_code) return PathsD();
|
||||
const double scale = std::pow(10, precision);
|
||||
ClipperOffset clip_offset(miter_limit, arc_tolerance);
|
||||
ClipperOffset clip_offset(miter_limit, arc_tolerance * scale);
|
||||
clip_offset.AddPaths(ScalePaths<int64_t,double>(paths, scale, error_code), jt, et);
|
||||
if (error_code) return PathsD();
|
||||
Paths64 solution;
|
||||
@@ -355,6 +356,29 @@
|
||||
#endif
|
||||
}
|
||||
|
||||
inline size_t GetNext(size_t current, size_t high,
|
||||
const std::vector<bool>& flags)
|
||||
{
|
||||
++current;
|
||||
while (current <= high && flags[current]) ++current;
|
||||
if (current <= high) return current;
|
||||
current = 0;
|
||||
while (flags[current]) ++current;
|
||||
return current;
|
||||
}
|
||||
|
||||
inline size_t GetPrior(size_t current, size_t high,
|
||||
const std::vector<bool>& flags)
|
||||
{
|
||||
if (current == 0) current = high;
|
||||
else --current;
|
||||
while (current > 0 && flags[current]) --current;
|
||||
if (!flags[current]) return current;
|
||||
current = high;
|
||||
while (flags[current]) --current;
|
||||
return current;
|
||||
}
|
||||
|
||||
} // end details namespace
|
||||
|
||||
inline std::ostream& operator<< (std::ostream& os, const PolyTree64& pp)
|
||||
@@ -615,29 +639,6 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
inline size_t GetNext(size_t current, size_t high,
|
||||
const std::vector<bool>& flags)
|
||||
{
|
||||
++current;
|
||||
while (current <= high && flags[current]) ++current;
|
||||
if (current <= high) return current;
|
||||
current = 0;
|
||||
while (flags[current]) ++current;
|
||||
return current;
|
||||
}
|
||||
|
||||
inline size_t GetPrior(size_t current, size_t high,
|
||||
const std::vector<bool>& flags)
|
||||
{
|
||||
if (current == 0) current = high;
|
||||
else --current;
|
||||
while (current > 0 && flags[current]) --current;
|
||||
if (!flags[current]) return current;
|
||||
current = high;
|
||||
while (flags[current]) --current;
|
||||
return current;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline Path<T> SimplifyPath(const Path<T> &path,
|
||||
double epsilon, bool isClosedPath = true)
|
||||
@@ -669,13 +670,13 @@
|
||||
start = curr;
|
||||
do
|
||||
{
|
||||
curr = GetNext(curr, high, flags);
|
||||
curr = details::GetNext(curr, high, flags);
|
||||
} while (curr != start && distSqr[curr] > epsSqr);
|
||||
if (curr == start) break;
|
||||
}
|
||||
|
||||
prior = GetPrior(curr, high, flags);
|
||||
next = GetNext(curr, high, flags);
|
||||
prior = details::GetPrior(curr, high, flags);
|
||||
next = details::GetNext(curr, high, flags);
|
||||
if (next == prior) break;
|
||||
|
||||
// flag for removal the smaller of adjacent 'distances'
|
||||
@@ -684,14 +685,14 @@
|
||||
prior2 = prior;
|
||||
prior = curr;
|
||||
curr = next;
|
||||
next = GetNext(next, high, flags);
|
||||
next = details::GetNext(next, high, flags);
|
||||
}
|
||||
else
|
||||
prior2 = GetPrior(prior, high, flags);
|
||||
prior2 = details::GetPrior(prior, high, flags);
|
||||
|
||||
flags[curr] = true;
|
||||
curr = next;
|
||||
next = GetNext(next, high, flags);
|
||||
next = details::GetNext(next, high, flags);
|
||||
|
||||
if (isClosedPath || ((curr != high) && (curr != 0)))
|
||||
distSqr[curr] = PerpendicDistFromLineSqrd(path[curr], path[prior], path[next]);
|
||||
@@ -716,6 +717,35 @@
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline bool Path2ContainsPath1(const Path<T>& path1, const Path<T>& path2)
|
||||
{
|
||||
// precondition: paths must not intersect, except for
|
||||
// transient (and presumed 'micro') path intersections
|
||||
PointInPolygonResult pip = PointInPolygonResult::IsOn;
|
||||
for (const Point<T>& pt : path1)
|
||||
{
|
||||
switch (PointInPolygon(pt, path2))
|
||||
{
|
||||
case PointInPolygonResult::IsOutside:
|
||||
if (pip == PointInPolygonResult::IsOutside) return false;
|
||||
pip = PointInPolygonResult::IsOutside;
|
||||
break;
|
||||
case PointInPolygonResult::IsInside:
|
||||
if (pip == PointInPolygonResult::IsInside) return true;
|
||||
pip = PointInPolygonResult::IsInside;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pip != PointInPolygonResult::IsInside) return false;
|
||||
// result is likely true but check midpoint
|
||||
Point<T> mp1 = GetBounds(path1).MidPoint();
|
||||
return PointInPolygon(mp1, path2) == PointInPolygonResult::IsInside;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void RDP(const Path<T> path, std::size_t begin,
|
||||
std::size_t end, double epsSqrd, std::vector<bool>& flags)
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Clipper2Lib {
|
||||
quad.emplace_back(tmp[i][h]);
|
||||
quad.emplace_back(tmp[i][j]);
|
||||
quad.emplace_back(tmp[g][j]);
|
||||
};
|
||||
}
|
||||
if (!IsPositive(quad))
|
||||
std::reverse(quad.begin(), quad.end());
|
||||
result.emplace_back(std::move(quad));
|
||||
|
||||
@@ -39,7 +39,7 @@ private:
|
||||
class Group {
|
||||
public:
|
||||
Paths64 paths_in;
|
||||
std::optional<size_t> lowest_path_idx{};
|
||||
std::optional<size_t> lowest_path_idx{};
|
||||
bool is_reversed = false;
|
||||
JoinType join_type;
|
||||
EndType end_type;
|
||||
@@ -92,14 +92,14 @@ public:
|
||||
bool reverse_solution = false) :
|
||||
miter_limit_(miter_limit), arc_tolerance_(arc_tolerance),
|
||||
preserve_collinear_(preserve_collinear),
|
||||
reverse_solution_(reverse_solution) { };
|
||||
reverse_solution_(reverse_solution) { }
|
||||
|
||||
~ClipperOffset() { Clear(); };
|
||||
~ClipperOffset() { Clear(); }
|
||||
|
||||
int ErrorCode() const { return error_code_; };
|
||||
int ErrorCode() const { return error_code_; }
|
||||
void AddPath(const Path64& path, JoinType jt_, EndType et_);
|
||||
void AddPaths(const Paths64& paths, JoinType jt_, EndType et_);
|
||||
void Clear() { groups_.clear(); norms.clear(); };
|
||||
void Clear() { groups_.clear(); norms.clear(); }
|
||||
|
||||
void Execute(double delta, Paths64& sols_64);
|
||||
void Execute(double delta, PolyTree64& polytree);
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace Clipper2Lib {
|
||||
void ExecuteInternal(const Path64& path);
|
||||
Path64 GetPath(OutPt2*& op);
|
||||
public:
|
||||
explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {};
|
||||
explicit RectClipLines64(const Rect64& rect) : RectClip64(rect) {}
|
||||
Paths64 Execute(const Paths64& paths);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 6 December 2025 *
|
||||
* Release : BETA RELEASE *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2025 *
|
||||
* Purpose : Delaunay Triangulation *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef CLIPPER_TRIANGULATION_H
|
||||
#define CLIPPER_TRIANGULATION_H
|
||||
|
||||
#include <stack>
|
||||
#include "clipper2/clipper.core.h"
|
||||
|
||||
#ifdef USINGZ
|
||||
namespace Clipper2Lib_Z {
|
||||
#else
|
||||
namespace Clipper2Lib {
|
||||
#endif
|
||||
|
||||
enum class TriangulateResult { success, fail, no_polygons, paths_intersect };
|
||||
|
||||
// Triangulate - this function will not accept intesecting paths
|
||||
TriangulateResult Triangulate(const Paths64& pp, Paths64& solution, bool useDelaunay = true);
|
||||
TriangulateResult Triangulate(const PathsD& pp, int decPlaces, PathsD& solution, bool useDelaunay = true);
|
||||
|
||||
} // Clipper2Lib namespace
|
||||
#endif // CLIPPER_TRIANGULATION_H
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef CLIPPER_VERSION_H
|
||||
#define CLIPPER_VERSION_H
|
||||
|
||||
constexpr auto CLIPPER2_VERSION = "1.5.2";
|
||||
constexpr auto CLIPPER2_VERSION = "2.0.1";
|
||||
|
||||
#endif // CLIPPER_VERSION_H
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 17 September 2024 *
|
||||
* Date : 21 February 2026 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2024 *
|
||||
* Copyright : Angus Johnson 2010-2026 *
|
||||
* Purpose : This is the main polygon clipping module *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
@@ -482,8 +482,7 @@ namespace Clipper2Lib {
|
||||
inline void SetOwner(OutRec* outrec, OutRec* new_owner)
|
||||
{
|
||||
//precondition1: new_owner is never null
|
||||
while (new_owner->owner && !new_owner->owner->pts)
|
||||
new_owner->owner = new_owner->owner->owner;
|
||||
new_owner->owner = GetRealOutRec(new_owner->owner);
|
||||
OutRec* tmp = new_owner;
|
||||
while (tmp && tmp != outrec) tmp = tmp->owner;
|
||||
if (tmp) new_owner->owner = outrec->owner;
|
||||
@@ -536,9 +535,9 @@ namespace Clipper2Lib {
|
||||
val = 1 - val; // toggle val
|
||||
else
|
||||
{
|
||||
double d = CrossProduct(op2->prev->pt, op2->pt, pt);
|
||||
if (d == 0) return PointInPolygonResult::IsOn;
|
||||
if ((d < 0) == is_above) val = 1 - val;
|
||||
int i = CrossProductSign(op2->prev->pt, op2->pt, pt);
|
||||
if (i == 0) return PointInPolygonResult::IsOn;
|
||||
if ((i < 0) == is_above) val = 1 - val;
|
||||
}
|
||||
is_above = !is_above;
|
||||
op2 = op2->next;
|
||||
@@ -546,9 +545,9 @@ namespace Clipper2Lib {
|
||||
|
||||
if (is_above != starting_above)
|
||||
{
|
||||
double d = CrossProduct(op2->prev->pt, op2->pt, pt);
|
||||
if (d == 0) return PointInPolygonResult::IsOn;
|
||||
if ((d < 0) == is_above) val = 1 - val;
|
||||
int i = CrossProductSign(op2->prev->pt, op2->pt, pt);
|
||||
if (i == 0) return PointInPolygonResult::IsOn;
|
||||
if ((i < 0) == is_above) val = 1 - val;
|
||||
}
|
||||
|
||||
if (val == 0) return PointInPolygonResult::IsOutside;
|
||||
@@ -578,30 +577,31 @@ namespace Clipper2Lib {
|
||||
return result;
|
||||
}
|
||||
|
||||
inline bool Path1InsidePath2(OutPt* op1, OutPt* op2)
|
||||
inline bool Path2ContainsPath1(OutPt* op1, OutPt* op2)
|
||||
{
|
||||
// we need to make some accommodation for rounding errors
|
||||
// so we won't jump if the first vertex is found outside
|
||||
PointInPolygonResult result;
|
||||
int outside_cnt = 0;
|
||||
// this function accommodates rounding errors that
|
||||
// can cause path micro intersections
|
||||
PointInPolygonResult pip = PointInPolygonResult::IsOn;
|
||||
OutPt* op = op1;
|
||||
do
|
||||
{
|
||||
result = PointInOpPolygon(op->pt, op2);
|
||||
if (result == PointInPolygonResult::IsOutside) ++outside_cnt;
|
||||
else if (result == PointInPolygonResult::IsInside) --outside_cnt;
|
||||
do {
|
||||
switch (PointInOpPolygon(op->pt, op2))
|
||||
{
|
||||
case PointInPolygonResult::IsOutside:
|
||||
if (pip == PointInPolygonResult::IsOutside) return false;
|
||||
pip = PointInPolygonResult::IsOutside;
|
||||
break;
|
||||
case PointInPolygonResult::IsInside:
|
||||
if (pip == PointInPolygonResult::IsInside) return true;
|
||||
pip = PointInPolygonResult::IsInside;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
op = op->next;
|
||||
} while (op != op1 && std::abs(outside_cnt) < 2);
|
||||
if (std::abs(outside_cnt) > 1) return (outside_cnt < 0);
|
||||
// since path1's location is still equivocal, check its midpoint
|
||||
Point64 mp = GetBounds(GetCleanPath(op1)).MidPoint();
|
||||
Path64 path2 = GetCleanPath(op2);
|
||||
return PointInPolygon(mp, path2) != PointInPolygonResult::IsOutside;
|
||||
} while (op != op1);
|
||||
// result unclear, so try again using cleaned paths
|
||||
return Path2ContainsPath1(GetCleanPath(op1), GetCleanPath(op2)); // (#973)
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
void AddLocMin(LocalMinimaList& list,
|
||||
Vertex& vert, PathType polytype, bool is_open)
|
||||
{
|
||||
@@ -621,7 +621,7 @@ namespace Clipper2Lib {
|
||||
{return a + path.size(); });
|
||||
if (total_vertex_count == 0) return;
|
||||
|
||||
Vertex* vertices = new Vertex[total_vertex_count], * v = vertices;
|
||||
Vertex* allVertices = new Vertex[total_vertex_count], * v = allVertices;
|
||||
for (const Path64& path : paths)
|
||||
{
|
||||
//for each path create a circular double linked list of vertices
|
||||
@@ -713,7 +713,7 @@ namespace Clipper2Lib {
|
||||
}
|
||||
} // end processing current path
|
||||
|
||||
vertexLists.emplace_back(vertices);
|
||||
vertexLists.emplace_back(allVertices);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@@ -1126,21 +1126,19 @@ namespace Clipper2Lib {
|
||||
return newcomer.curr_x > resident.curr_x;
|
||||
|
||||
//get the turning direction a1.top, a2.bot, a2.top
|
||||
double d = CrossProduct(resident.top, newcomer.bot, newcomer.top);
|
||||
if (d != 0) return d < 0;
|
||||
int i = CrossProductSign(resident.top, newcomer.bot, newcomer.top);
|
||||
if (i != 0) return i < 0;
|
||||
|
||||
//edges must be collinear to get here
|
||||
//for starting open paths, place them according to
|
||||
//the direction they're about to turn
|
||||
if (!IsMaxima(resident) && (resident.top.y > newcomer.top.y))
|
||||
{
|
||||
return CrossProduct(newcomer.bot,
|
||||
resident.top, NextVertex(resident)->pt) <= 0;
|
||||
return (CrossProductSign(newcomer.bot, resident.top, NextVertex(resident)->pt) <= 0);
|
||||
}
|
||||
else if (!IsMaxima(newcomer) && (newcomer.top.y > resident.top.y))
|
||||
{
|
||||
return CrossProduct(newcomer.bot,
|
||||
newcomer.top, NextVertex(newcomer)->pt) >= 0;
|
||||
return (CrossProductSign(newcomer.bot, newcomer.top, NextVertex(newcomer)->pt) >= 0);
|
||||
}
|
||||
|
||||
int64_t y = newcomer.bot.y;
|
||||
@@ -1155,7 +1153,7 @@ namespace Clipper2Lib {
|
||||
resident.bot, resident.top)) return true;
|
||||
else
|
||||
//compare turning direction of the alternate bound
|
||||
return (CrossProduct(PrevPrevVertex(resident)->pt,
|
||||
return (CrossProductSign(PrevPrevVertex(resident)->pt,
|
||||
newcomer.bot, PrevPrevVertex(newcomer)->pt) > 0) == newcomerIsLeft;
|
||||
}
|
||||
|
||||
@@ -1565,7 +1563,7 @@ namespace Clipper2Lib {
|
||||
FixSelfIntersects(outrec);
|
||||
}
|
||||
|
||||
void ClipperBase::DoSplitOp(OutRec* outrec, OutPt* splitOp)
|
||||
void ClipperBase::DoSplitOp (OutRec* outrec, OutPt* splitOp)
|
||||
{
|
||||
// splitOp.prev -> splitOp &&
|
||||
// splitOp.next -> splitOp.next.next are intersecting
|
||||
@@ -1574,7 +1572,7 @@ namespace Clipper2Lib {
|
||||
outrec->pts = prevOp;
|
||||
|
||||
Point64 ip;
|
||||
GetSegmentIntersectPt(prevOp->pt, splitOp->pt,
|
||||
GetLineIntersectPt(prevOp->pt, splitOp->pt,
|
||||
splitOp->next->pt, nextNextOp->pt, ip);
|
||||
|
||||
#ifdef USINGZ
|
||||
@@ -1630,7 +1628,7 @@ namespace Clipper2Lib {
|
||||
|
||||
if (using_polytree_)
|
||||
{
|
||||
if (Path1InsidePath2(prevOp, newOp))
|
||||
if (Path2ContainsPath1(prevOp, newOp))
|
||||
{
|
||||
newOr->splits = new OutRecList();
|
||||
newOr->splits->emplace_back(outrec);
|
||||
@@ -1652,10 +1650,10 @@ namespace Clipper2Lib {
|
||||
void ClipperBase::FixSelfIntersects(OutRec* outrec)
|
||||
{
|
||||
OutPt* op2 = outrec->pts;
|
||||
if (op2->prev == op2->next->next)
|
||||
return; // because triangles can't self-intersect
|
||||
for (; ; )
|
||||
{
|
||||
// triangles can't self-intersect
|
||||
if (op2->prev == op2->next->next) break;
|
||||
if (SegmentsIntersect(op2->prev->pt,
|
||||
op2->pt, op2->next->pt, op2->next->next->pt))
|
||||
{
|
||||
@@ -1664,6 +1662,8 @@ namespace Clipper2Lib {
|
||||
DoSplitOp(outrec, op2);
|
||||
if (!outrec->pts) break;
|
||||
op2 = outrec->pts;
|
||||
if (op2->prev == op2->next->next)
|
||||
break; // again, because triangles can't self-intersect
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@@ -2112,10 +2112,9 @@ namespace Clipper2Lib {
|
||||
e->prev_in_sel = e->prev_in_ael;
|
||||
e->next_in_sel = e->next_in_ael;
|
||||
e->jump = e->next_in_sel;
|
||||
if (e->join_with == JoinWith::Left)
|
||||
e->curr_x = e->prev_in_ael->curr_x; // also avoids complications
|
||||
else
|
||||
e->curr_x = TopX(*e, top_y);
|
||||
// it is safe to ignore 'joined' edges here because
|
||||
// if necessary they will be split in IntersectEdges()
|
||||
e->curr_x = TopX(*e, top_y);
|
||||
e = e->next_in_ael;
|
||||
}
|
||||
}
|
||||
@@ -2262,15 +2261,14 @@ namespace Clipper2Lib {
|
||||
|
||||
void MoveSplits(OutRec* fromOr, OutRec* toOr)
|
||||
{
|
||||
if (!fromOr->splits) return;
|
||||
if (!toOr->splits) toOr->splits = new OutRecList();
|
||||
OutRecList::iterator orIter = fromOr->splits->begin();
|
||||
for (; orIter != fromOr->splits->end(); ++orIter)
|
||||
toOr->splits->emplace_back(*orIter);
|
||||
if (toOr != *orIter) // #987
|
||||
toOr->splits->emplace_back(*orIter);
|
||||
fromOr->splits->clear();
|
||||
}
|
||||
|
||||
|
||||
void ClipperBase::ProcessHorzJoins()
|
||||
{
|
||||
for (const HorzJoin& j : horz_join_list_)
|
||||
@@ -2300,7 +2298,7 @@ namespace Clipper2Lib {
|
||||
|
||||
if (using_polytree_) //#498, #520, #584, D#576, #618
|
||||
{
|
||||
if (Path1InsidePath2(or1->pts, or2->pts))
|
||||
if (Path2ContainsPath1(or1->pts, or2->pts))
|
||||
{
|
||||
//swap or1's & or2's pts
|
||||
OutPt* tmp = or1->pts;
|
||||
@@ -2311,7 +2309,7 @@ namespace Clipper2Lib {
|
||||
//or2 is now inside or1
|
||||
or2->owner = or1;
|
||||
}
|
||||
else if (Path1InsidePath2(or2->pts, or1->pts))
|
||||
else if (Path2ContainsPath1(or2->pts, or1->pts))
|
||||
{
|
||||
or2->owner = or1;
|
||||
}
|
||||
@@ -2324,13 +2322,14 @@ namespace Clipper2Lib {
|
||||
else
|
||||
or2->owner = or1;
|
||||
}
|
||||
else
|
||||
else // joining, not splitting
|
||||
{
|
||||
or2->pts = nullptr;
|
||||
if (using_polytree_)
|
||||
{
|
||||
SetOwner(or2, or1);
|
||||
MoveSplits(or2, or1); //#618
|
||||
if (or2->splits)
|
||||
MoveSplits(or2, or1); //#618
|
||||
}
|
||||
else
|
||||
or2->owner = or1;
|
||||
@@ -2350,7 +2349,7 @@ namespace Clipper2Lib {
|
||||
void ClipperBase::AddNewIntersectNode(Active& e1, Active& e2, int64_t top_y)
|
||||
{
|
||||
Point64 ip;
|
||||
if (!GetSegmentIntersectPt(e1.bot, e1.top, e2.bot, e2.top, ip))
|
||||
if (!GetLineIntersectPt(e1.bot, e1.top, e2.bot, e2.top, ip))
|
||||
ip = Point64(e1.curr_x, top_y); //parallel edges
|
||||
|
||||
//rounding errors can occasionally place the calculated intersection
|
||||
@@ -2934,22 +2933,28 @@ namespace Clipper2Lib {
|
||||
|
||||
bool ClipperBase::CheckSplitOwner(OutRec* outrec, OutRecList* splits)
|
||||
{
|
||||
for (auto split : *splits)
|
||||
// nb: use indexing (not an iterator) in case 'splits' is modified inside this loop (#1029)
|
||||
for (size_t idx = 0; idx < splits->size(); ++idx)
|
||||
{
|
||||
OutRec* split = (*splits)[idx];
|
||||
if (!split->pts && split->splits &&
|
||||
CheckSplitOwner(outrec, split->splits)) return true; //#942
|
||||
split = GetRealOutRec(split);
|
||||
if(!split || split == outrec || split->recursive_split == outrec) continue;
|
||||
if (!split || split == outrec || split->recursive_split == outrec) continue;
|
||||
split->recursive_split = outrec; // prevent infinite loops
|
||||
|
||||
if (split->splits && CheckSplitOwner(outrec, split->splits))
|
||||
return true;
|
||||
else if (CheckBounds(split) &&
|
||||
IsValidOwner(outrec, split) &&
|
||||
split->bounds.Contains(outrec->bounds) &&
|
||||
Path1InsidePath2(outrec->pts, split->pts))
|
||||
{
|
||||
outrec->owner = split; //found in split
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!CheckBounds(split) || !split->bounds.Contains(outrec->bounds) ||
|
||||
!Path2ContainsPath1(outrec->pts, split->pts)) continue;
|
||||
|
||||
if (!IsValidOwner(outrec, split)) // split is owned by outrec! (#957)
|
||||
split->owner = outrec->owner;
|
||||
|
||||
outrec->owner = split;
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -2960,13 +2965,12 @@ namespace Clipper2Lib {
|
||||
// post-condition: if a valid path, outrec will have a polypath
|
||||
|
||||
if (outrec->polypath || outrec->bounds.IsEmpty()) return;
|
||||
|
||||
while (outrec->owner)
|
||||
{
|
||||
if (outrec->owner->splits && CheckSplitOwner(outrec, outrec->owner->splits)) break;
|
||||
if (outrec->owner->pts && CheckBounds(outrec->owner) &&
|
||||
outrec->owner->bounds.Contains(outrec->bounds) &&
|
||||
Path1InsidePath2(outrec->pts, outrec->owner->pts)) break;
|
||||
Path2ContainsPath1(outrec->pts, outrec->owner->pts)) break;
|
||||
outrec->owner = outrec->owner->owner;
|
||||
}
|
||||
|
||||
@@ -3029,6 +3033,7 @@ namespace Clipper2Lib {
|
||||
{
|
||||
OutRec* outrec = outrec_list_[i];
|
||||
if (!outrec || !outrec->pts) continue;
|
||||
|
||||
if (outrec->is_open)
|
||||
{
|
||||
Path64 path;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 22 January 2025 *
|
||||
* Date : 11 October 2025 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2025 *
|
||||
* Purpose : Path Offset (Inflate/Shrink) *
|
||||
@@ -37,22 +37,28 @@ const double arc_const = 0.002; // <-- 1/500
|
||||
// Miscellaneous methods
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
std::optional<size_t> GetLowestClosedPathIdx(const Paths64& paths)
|
||||
void GetLowestClosedPathInfo(const Paths64& paths, std::optional<size_t>& idx, bool& is_neg_area)
|
||||
{
|
||||
std::optional<size_t> result;
|
||||
idx.reset();
|
||||
Point64 botPt = Point64(INT64_MAX, INT64_MIN);
|
||||
for (size_t i = 0; i < paths.size(); ++i)
|
||||
{
|
||||
double a = MAX_DBL;
|
||||
for (const Point64& pt : paths[i])
|
||||
{
|
||||
if ((pt.y < botPt.y) ||
|
||||
((pt.y == botPt.y) && (pt.x >= botPt.x))) continue;
|
||||
result = i;
|
||||
if (a == MAX_DBL)
|
||||
{
|
||||
a = Area(paths[i]);
|
||||
if (a == 0) break; // invalid closed path, so break from inner loop
|
||||
is_neg_area = a < 0;
|
||||
}
|
||||
idx = i;
|
||||
botPt.x = pt.x;
|
||||
botPt.y = pt.y;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
inline double Hypot(double x, double y)
|
||||
@@ -145,15 +151,16 @@ ClipperOffset::Group::Group(const Paths64& _paths, JoinType _join_type, EndType
|
||||
|
||||
if (end_type == EndType::Polygon)
|
||||
{
|
||||
lowest_path_idx = GetLowestClosedPathIdx(paths_in);
|
||||
bool is_neg_area;
|
||||
GetLowestClosedPathInfo(paths_in, lowest_path_idx, is_neg_area);
|
||||
// the lowermost path must be an outer path, so if its orientation is negative,
|
||||
// then flag the whole group is 'reversed' (will negate delta etc.)
|
||||
// as this is much more efficient than reversing every path.
|
||||
is_reversed = (lowest_path_idx.has_value()) && Area(paths_in[lowest_path_idx.value()]) < 0;
|
||||
is_reversed = lowest_path_idx.has_value() && is_neg_area;
|
||||
}
|
||||
else
|
||||
{
|
||||
lowest_path_idx = std::nullopt;
|
||||
lowest_path_idx.reset();
|
||||
is_reversed = false;
|
||||
}
|
||||
}
|
||||
@@ -236,7 +243,7 @@ void ClipperOffset::DoSquare(const Path64& path, size_t j, size_t k)
|
||||
{
|
||||
PointD pt4 = PointD(pt3.x + vec.x * group_delta_, pt3.y + vec.y * group_delta_);
|
||||
PointD pt = ptQ;
|
||||
GetSegmentIntersectPt(pt1, pt2, pt3, pt4, pt);
|
||||
GetLineIntersectPt(pt1, pt2, pt3, pt4, pt);
|
||||
//get the second intersect point through reflecion
|
||||
path_out.emplace_back(ReflectPoint(pt, ptQ));
|
||||
path_out.emplace_back(pt);
|
||||
@@ -245,7 +252,7 @@ void ClipperOffset::DoSquare(const Path64& path, size_t j, size_t k)
|
||||
{
|
||||
PointD pt4 = GetPerpendicD(path[j], norms[k], group_delta_);
|
||||
PointD pt = ptQ;
|
||||
GetSegmentIntersectPt(pt1, pt2, pt3, pt4, pt);
|
||||
GetLineIntersectPt(pt1, pt2, pt3, pt4, pt);
|
||||
path_out.emplace_back(pt);
|
||||
//get the second intersect point through reflecion
|
||||
path_out.emplace_back(ReflectPoint(pt, ptQ));
|
||||
@@ -601,10 +608,10 @@ void ClipperOffset::ExecuteInternal(double delta)
|
||||
|
||||
if (!solution->size()) return;
|
||||
|
||||
bool paths_reversed = CheckReverseOrientation();
|
||||
bool paths_reversed = CheckReverseOrientation();
|
||||
//clean up self-intersections ...
|
||||
Clipper64 c;
|
||||
c.PreserveCollinear(false);
|
||||
c.PreserveCollinear(preserve_collinear_);
|
||||
//the solution should retain the orientation of the input
|
||||
c.ReverseSolution(reverse_solution_ != paths_reversed);
|
||||
#ifdef USINGZ
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/*******************************************************************************
|
||||
* Author : Angus Johnson *
|
||||
* Date : 5 July 2024 *
|
||||
* Date : 11 October 2025 *
|
||||
* Website : https://www.angusj.com *
|
||||
* Copyright : Angus Johnson 2010-2024 *
|
||||
* Copyright : Angus Johnson 2010-2025 *
|
||||
* Purpose : FAST rectangular clipping *
|
||||
* License : https://www.boost.org/LICENSE_1_0.txt *
|
||||
*******************************************************************************/
|
||||
@@ -77,8 +77,8 @@ namespace Clipper2Lib {
|
||||
bool GetSegmentIntersection(const Point64& p1,
|
||||
const Point64& p2, const Point64& p3, const Point64& p4, Point64& ip)
|
||||
{
|
||||
double res1 = CrossProduct(p1, p3, p4);
|
||||
double res2 = CrossProduct(p2, p3, p4);
|
||||
int res1 = CrossProductSign(p1, p3, p4);
|
||||
int res2 = CrossProductSign(p2, p3, p4);
|
||||
if (res1 == 0)
|
||||
{
|
||||
ip = p1;
|
||||
@@ -97,8 +97,8 @@ namespace Clipper2Lib {
|
||||
}
|
||||
if ((res1 > 0) == (res2 > 0)) return false;
|
||||
|
||||
double res3 = CrossProduct(p3, p1, p2);
|
||||
double res4 = CrossProduct(p4, p1, p2);
|
||||
int res3 = CrossProductSign(p3, p1, p2);
|
||||
int res4 = CrossProductSign(p4, p1, p2);
|
||||
if (res3 == 0)
|
||||
{
|
||||
ip = p3;
|
||||
@@ -116,7 +116,7 @@ namespace Clipper2Lib {
|
||||
if ((res3 > 0) == (res4 > 0)) return false;
|
||||
|
||||
// segments must intersect to get here
|
||||
return GetSegmentIntersectPt(p1, p2, p3, p4, ip);
|
||||
return GetLineIntersectPt(p1, p2, p3, p4, ip);
|
||||
}
|
||||
|
||||
inline bool GetIntersection(const Path64& rectPath,
|
||||
@@ -227,7 +227,7 @@ namespace Clipper2Lib {
|
||||
const Point64& prev_pt, const Point64& curr_pt, const Point64& rect_mp)
|
||||
{
|
||||
if (AreOpposites(prev, curr))
|
||||
return CrossProduct(prev_pt, rect_mp, curr_pt) < 0;
|
||||
return CrossProductSign(prev_pt, rect_mp, curr_pt) < 0;
|
||||
else
|
||||
return HeadingClockwise(prev, curr);
|
||||
}
|
||||
|
||||
1224
deps_src/clipper2/Clipper2Lib/src/clipper.triangulation.cpp
Normal file
@@ -6,3 +6,4 @@
|
||||
#include "clipper.engine.cpp"
|
||||
#include "clipper.offset.cpp"
|
||||
#include "clipper.rectclip.cpp"
|
||||
#include "clipper.triangulation.cpp"
|
||||
|
||||
11
deps_src/colorsolver/CMakeLists.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(colorsolver)
|
||||
|
||||
add_library(colorsolver STATIC
|
||||
ColorSolver.cpp
|
||||
ColorSolver.hpp
|
||||
)
|
||||
|
||||
target_include_directories(colorsolver PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_features(colorsolver PUBLIC cxx_std_17)
|
||||
target_link_libraries(colorsolver PUBLIC pigment_painter prusa_fdm_mixer)
|
||||
2024
deps_src/colorsolver/ColorSolver.cpp
Normal file
243
deps_src/colorsolver/ColorSolver.hpp
Normal file
@@ -0,0 +1,243 @@
|
||||
// ColorSolver
|
||||
// Copyright (C) 2026 sentientstardust
|
||||
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#ifndef slic3r_ColorSolver_hpp_
|
||||
#define slic3r_ColorSolver_hpp_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Slic3r {
|
||||
|
||||
enum class ColorSolverMixModel : int
|
||||
{
|
||||
PigmentPainter = 0,
|
||||
PrusaFdmMixer = 1
|
||||
};
|
||||
|
||||
enum class ColorSolverLookupMode : int
|
||||
{
|
||||
ClosestMix = 0,
|
||||
BlendClosestTwo = 1
|
||||
};
|
||||
|
||||
enum class ColorSolverMode : int
|
||||
{
|
||||
RGB = 0,
|
||||
Oklab = 1,
|
||||
OklabSoftCap4Dark4 = 2
|
||||
};
|
||||
|
||||
enum class ColorSolverStackComponentRole : uint8_t
|
||||
{
|
||||
Generic = 0,
|
||||
Cyan = 1,
|
||||
Magenta = 2,
|
||||
Yellow = 3,
|
||||
Black = 4,
|
||||
White = 5
|
||||
};
|
||||
|
||||
enum class ColorSolverCalibratedStackModelKind : uint8_t
|
||||
{
|
||||
None = 0,
|
||||
CurrentLinearAffine = 1,
|
||||
AlphaEffective = 2,
|
||||
DepthKernelLinear = 3,
|
||||
NearestMeasuredSample = 4
|
||||
};
|
||||
|
||||
struct ColorSolverCalibratedStackModel {
|
||||
ColorSolverCalibratedStackModelKind kind { ColorSolverCalibratedStackModelKind::None };
|
||||
size_t component_count { 0 };
|
||||
int measured_stack_depth { 0 };
|
||||
std::vector<float> measured_layer_heights_mm;
|
||||
std::vector<float> alphas;
|
||||
std::vector<float> taus;
|
||||
std::vector<float> coefficients_linear_rgb;
|
||||
std::vector<float> measured_sample_rgbs;
|
||||
std::vector<uint16_t> measured_sample_stacks;
|
||||
mutable std::string cached_key;
|
||||
|
||||
bool valid() const;
|
||||
std::string cache_key() const;
|
||||
};
|
||||
|
||||
struct ColorSolverCandidateSet {
|
||||
struct KdNode {
|
||||
uint32_t candidate_idx { 0 };
|
||||
int left { -1 };
|
||||
int right { -1 };
|
||||
uint8_t axis { 0 };
|
||||
};
|
||||
|
||||
size_t component_count { 0 };
|
||||
std::vector<float> rgbs;
|
||||
std::vector<float> perceptual_coords;
|
||||
std::vector<float> weights;
|
||||
std::vector<KdNode> kd_nodes;
|
||||
std::vector<KdNode> perceptual_kd_nodes;
|
||||
int kd_root { -1 };
|
||||
int perceptual_kd_root { -1 };
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return component_count == 0 || rgbs.empty() || rgbs.size() % 3 != 0 ||
|
||||
weights.size() != (rgbs.size() / 3) * component_count;
|
||||
}
|
||||
};
|
||||
|
||||
using ColorSolverCandidateCache = std::map<std::string, ColorSolverCandidateSet>;
|
||||
|
||||
struct ColorSolverOrderedStackCandidateSet {
|
||||
using KdNode = ColorSolverCandidateSet::KdNode;
|
||||
|
||||
size_t component_count { 0 };
|
||||
int stack_depth { 0 };
|
||||
int simulated_stack_depth { 0 };
|
||||
std::vector<float> rgbs;
|
||||
std::vector<float> perceptual_coords;
|
||||
std::vector<uint16_t> stacks;
|
||||
std::vector<KdNode> kd_nodes;
|
||||
std::vector<KdNode> perceptual_kd_nodes;
|
||||
int kd_root { -1 };
|
||||
int perceptual_kd_root { -1 };
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return component_count == 0 || stack_depth <= 0 || rgbs.empty() || rgbs.size() % 3 != 0 ||
|
||||
stacks.size() != (rgbs.size() / 3) * size_t(stack_depth);
|
||||
}
|
||||
};
|
||||
|
||||
struct ColorSolverOrderedStackResult {
|
||||
std::vector<uint16_t> surface_to_deep;
|
||||
std::array<float, 3> rgb { { 0.f, 0.f, 0.f } };
|
||||
bool has_rgb { false };
|
||||
};
|
||||
|
||||
using ColorSolverOrderedStackCandidateCache = std::map<std::string, ColorSolverOrderedStackCandidateSet>;
|
||||
|
||||
ColorSolverMixModel color_solver_mix_model_from_index(int model);
|
||||
ColorSolverLookupMode color_solver_lookup_mode_from_index(int mode);
|
||||
ColorSolverMode color_solver_mode_from_index(int mode);
|
||||
|
||||
int color_solver_total_units_for_component_count(size_t component_count);
|
||||
size_t color_solver_candidate_count(size_t component_count, int total_units);
|
||||
|
||||
std::array<float, 3> mix_color_solver_components(const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<int> &weights,
|
||||
ColorSolverMixModel mix_model);
|
||||
std::array<float, 3> mix_color_solver_components(const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &weights,
|
||||
ColorSolverMixModel mix_model);
|
||||
std::array<float, 3> mix_color_solver_ordered_stack(const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<uint16_t> &surface_to_deep,
|
||||
const std::vector<float> &layer_opacities,
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
std::array<float, 3> color_solver_oklab_from_srgb(const std::array<float, 3> &rgb);
|
||||
std::array<float, 3> color_solver_srgb_from_oklab(const std::array<float, 3> &oklab);
|
||||
|
||||
std::string color_solver_candidate_cache_key(const std::vector<std::array<float, 3>> &component_colors,
|
||||
ColorSolverMixModel mix_model,
|
||||
int total_units = 0);
|
||||
ColorSolverCandidateSet build_color_solver_candidates(const std::vector<std::array<float, 3>> &component_colors,
|
||||
ColorSolverMixModel mix_model,
|
||||
int total_units = 0);
|
||||
void build_color_solver_candidate_kd_trees(ColorSolverCandidateSet &candidates);
|
||||
const ColorSolverCandidateSet &color_solver_candidates(ColorSolverCandidateCache &cache,
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
ColorSolverMixModel mix_model,
|
||||
int total_units = 0);
|
||||
std::vector<float> solve_color_solver_weights_for_target(const ColorSolverCandidateSet &candidates,
|
||||
const std::array<float, 3> &target_rgb,
|
||||
ColorSolverLookupMode lookup_mode,
|
||||
ColorSolverMode solver_mode);
|
||||
std::string color_solver_ordered_stack_candidate_cache_key(const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &layer_opacities,
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
int stack_depth,
|
||||
int simulated_stack_depth = 0,
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
ColorSolverOrderedStackCandidateSet build_color_solver_ordered_stack_candidates(
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &layer_opacities,
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
int stack_depth,
|
||||
int simulated_stack_depth = 0,
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
const ColorSolverOrderedStackCandidateSet &color_solver_ordered_stack_candidates(
|
||||
ColorSolverOrderedStackCandidateCache &cache,
|
||||
const std::vector<std::array<float, 3>> &component_colors,
|
||||
const std::vector<float> &layer_opacities,
|
||||
const std::array<float, 3> &background_rgb,
|
||||
ColorSolverMixModel mix_model,
|
||||
int stack_depth,
|
||||
int simulated_stack_depth = 0,
|
||||
size_t candidate_limit = 0,
|
||||
size_t stack_item_limit = 0,
|
||||
float surface_scatter = 0.f,
|
||||
bool beer_lambert_rgb_correction = false,
|
||||
bool td_effective_alpha_correction = false,
|
||||
const std::vector<ColorSolverStackComponentRole> &component_roles = {},
|
||||
bool beam_search_stack_expansion = false,
|
||||
const std::vector<float> &layer_opacities_by_depth = {},
|
||||
const ColorSolverCalibratedStackModel *calibrated_stack_model = nullptr,
|
||||
bool adaptive_spectral_correction = false);
|
||||
ColorSolverOrderedStackResult solve_color_solver_ordered_stack_result_for_target(
|
||||
const ColorSolverOrderedStackCandidateSet &candidates,
|
||||
const std::array<float, 3> &target_rgb,
|
||||
ColorSolverMode solver_mode);
|
||||
std::vector<uint16_t> solve_color_solver_ordered_stack_for_target(
|
||||
const ColorSolverOrderedStackCandidateSet &candidates,
|
||||
const std::array<float, 3> &target_rgb,
|
||||
ColorSolverMode solver_mode);
|
||||
|
||||
} // namespace Slic3r
|
||||
|
||||
#endif
|
||||
@@ -267,7 +267,7 @@ void ImGui::Text(const char* fmt, ...)
|
||||
void ImGui::TextCentered(const char* text, ...)
|
||||
{
|
||||
va_list vaList;
|
||||
va_start(vaList,&text);
|
||||
va_start(vaList, text);
|
||||
|
||||
float font_size = ImGui::GetFontSize() * strlen(text) / 2;
|
||||
ImGui::SameLine(ImGui::GetCursorPos().x / 2 - font_size + (font_size / 2));
|
||||
|
||||
14
deps_src/pigment-painter/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(pigment_painter)
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
|
||||
add_library(pigment_painter STATIC
|
||||
lut_wide.png.c
|
||||
pigment_painter_mixer.cpp
|
||||
pigment_painter_mixer.hpp
|
||||
)
|
||||
|
||||
target_include_directories(pigment_painter PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_features(pigment_painter PUBLIC cxx_std_17)
|
||||
target_link_libraries(pigment_painter PRIVATE PNG::PNG)
|
||||
674
deps_src/pigment-painter/COPYING
Normal file
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
480199
deps_src/pigment-painter/lut_wide.png.c
Normal file
334
deps_src/pigment-painter/pigment_painter_mixer.cpp
Normal file
@@ -0,0 +1,334 @@
|
||||
#include "pigment_painter_mixer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
|
||||
#include <png.h>
|
||||
|
||||
extern "C" const char lut_wide_png_data[10295238];
|
||||
|
||||
namespace pigment_painter {
|
||||
namespace {
|
||||
|
||||
constexpr int k_lut_dimen = 256;
|
||||
constexpr size_t k_lut_png_size = sizeof(lut_wide_png_data);
|
||||
|
||||
struct PngMemoryReader
|
||||
{
|
||||
const std::uint8_t *data = nullptr;
|
||||
size_t size = 0;
|
||||
size_t offset = 0;
|
||||
};
|
||||
|
||||
struct LutImage
|
||||
{
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
int row_size = 0;
|
||||
std::vector<std::uint8_t> rgba;
|
||||
bool loaded = false;
|
||||
};
|
||||
|
||||
float clamp01(float value)
|
||||
{
|
||||
return std::max(0.f, std::min(1.f, value));
|
||||
}
|
||||
|
||||
float srgb_to_linear(float value)
|
||||
{
|
||||
const float x = clamp01(value);
|
||||
return x <= 0.04045f ? x / 12.92f : std::pow((x + 0.055f) / 1.055f, 2.4f);
|
||||
}
|
||||
|
||||
float linear_to_srgb(float value)
|
||||
{
|
||||
const float x = clamp01(value);
|
||||
return x <= 0.0031308f ? x * 12.92f : 1.055f * std::pow(x, 1.f / 2.4f) - 0.055f;
|
||||
}
|
||||
|
||||
void png_memory_read(png_structp png_ptr, png_bytep out, png_size_t bytes)
|
||||
{
|
||||
PngMemoryReader *reader = static_cast<PngMemoryReader *>(png_get_io_ptr(png_ptr));
|
||||
if (reader == nullptr || reader->offset + bytes > reader->size)
|
||||
png_error(png_ptr, "pigment painter lut read failed");
|
||||
|
||||
std::memcpy(out, reader->data + reader->offset, bytes);
|
||||
reader->offset += bytes;
|
||||
}
|
||||
|
||||
bool decode_lut_png(LutImage &image)
|
||||
{
|
||||
PngMemoryReader reader {
|
||||
reinterpret_cast<const std::uint8_t *>(lut_wide_png_data),
|
||||
k_lut_png_size,
|
||||
0
|
||||
};
|
||||
|
||||
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
|
||||
if (png == nullptr)
|
||||
return false;
|
||||
|
||||
png_infop info = png_create_info_struct(png);
|
||||
if (info == nullptr) {
|
||||
png_destroy_read_struct(&png, nullptr, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(png))) {
|
||||
png_destroy_read_struct(&png, &info, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
png_set_read_fn(png, &reader, png_memory_read);
|
||||
png_read_info(png, info);
|
||||
|
||||
png_uint_32 width = png_get_image_width(png, info);
|
||||
png_uint_32 height = png_get_image_height(png, info);
|
||||
int bit_depth = png_get_bit_depth(png, info);
|
||||
int color_type = png_get_color_type(png, info);
|
||||
|
||||
if (bit_depth == 16)
|
||||
png_set_strip_16(png);
|
||||
if (color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_palette_to_rgb(png);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
|
||||
png_set_expand_gray_1_2_4_to_8(png);
|
||||
if (png_get_valid(png, info, PNG_INFO_tRNS))
|
||||
png_set_tRNS_to_alpha(png);
|
||||
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
|
||||
png_set_gray_to_rgb(png);
|
||||
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
|
||||
png_set_filler(png, 0xff, PNG_FILLER_AFTER);
|
||||
|
||||
png_read_update_info(png, info);
|
||||
|
||||
if (png_get_channels(png, info) != 4 || width % k_lut_dimen != 0 || height % k_lut_dimen != 0) {
|
||||
png_destroy_read_struct(&png, &info, nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
image.width = int(width);
|
||||
image.height = int(height);
|
||||
image.row_size = image.width / k_lut_dimen;
|
||||
image.rgba.resize(size_t(width) * size_t(height) * 4);
|
||||
|
||||
std::vector<png_bytep> rows(height);
|
||||
for (png_uint_32 row = 0; row < height; ++row)
|
||||
rows[row] = image.rgba.data() + size_t(row) * size_t(width) * 4;
|
||||
|
||||
png_read_image(png, rows.data());
|
||||
png_read_end(png, nullptr);
|
||||
png_destroy_read_struct(&png, &info, nullptr);
|
||||
|
||||
image.loaded = image.width == k_lut_dimen * image.row_size &&
|
||||
image.height >= k_lut_dimen * ((k_lut_dimen * 2 + image.row_size - 1) / image.row_size);
|
||||
return image.loaded;
|
||||
}
|
||||
|
||||
const LutImage *lut_image()
|
||||
{
|
||||
static LutImage image;
|
||||
static std::once_flag once;
|
||||
std::call_once(once, []() { decode_lut_png(image); });
|
||||
return image.loaded ? &image : nullptr;
|
||||
}
|
||||
|
||||
std::array<float, 3> sample_lut_texel(const LutImage &image, int x, int y, int z)
|
||||
{
|
||||
const int col = z % image.row_size;
|
||||
const int row = z / image.row_size;
|
||||
const int ix = x + col * k_lut_dimen;
|
||||
const int iy = y + row * k_lut_dimen;
|
||||
const size_t idx = (size_t(iy) * size_t(image.width) + size_t(ix)) * 4;
|
||||
|
||||
return {
|
||||
float(image.rgba[idx]) / 255.f,
|
||||
float(image.rgba[idx + 2]) / 255.f,
|
||||
float(image.rgba[idx + 1]) / 255.f
|
||||
};
|
||||
}
|
||||
|
||||
std::array<float, 3> lerp_color(const std::array<float, 3> &a, const std::array<float, 3> &b, float t)
|
||||
{
|
||||
return {
|
||||
a[0] + (b[0] - a[0]) * t,
|
||||
a[1] + (b[1] - a[1]) * t,
|
||||
a[2] + (b[2] - a[2]) * t
|
||||
};
|
||||
}
|
||||
|
||||
std::array<float, 3> sample_lut(const LutImage &image, const std::array<float, 3> &color, int z_offset)
|
||||
{
|
||||
const float xf = clamp01(color[0]) * float(k_lut_dimen - 1);
|
||||
const float yf = clamp01(color[1]) * float(k_lut_dimen - 1);
|
||||
const float zf = clamp01(color[2]) * float(k_lut_dimen - 1);
|
||||
|
||||
const int x0 = int(std::floor(xf));
|
||||
const int y0 = int(std::floor(yf));
|
||||
const int z0 = int(std::floor(zf));
|
||||
const int x1 = std::min(x0 + 1, k_lut_dimen - 1);
|
||||
const int y1 = std::min(y0 + 1, k_lut_dimen - 1);
|
||||
const int z1 = std::min(z0 + 1, k_lut_dimen - 1);
|
||||
|
||||
const float tx = xf - float(x0);
|
||||
const float ty = yf - float(y0);
|
||||
const float tz = zf - float(z0);
|
||||
|
||||
const std::array<float, 3> c000 = sample_lut_texel(image, x0, y0, z0 + z_offset);
|
||||
const std::array<float, 3> c100 = sample_lut_texel(image, x1, y0, z0 + z_offset);
|
||||
const std::array<float, 3> c010 = sample_lut_texel(image, x0, y1, z0 + z_offset);
|
||||
const std::array<float, 3> c110 = sample_lut_texel(image, x1, y1, z0 + z_offset);
|
||||
const std::array<float, 3> c001 = sample_lut_texel(image, x0, y0, z1 + z_offset);
|
||||
const std::array<float, 3> c101 = sample_lut_texel(image, x1, y0, z1 + z_offset);
|
||||
const std::array<float, 3> c011 = sample_lut_texel(image, x0, y1, z1 + z_offset);
|
||||
const std::array<float, 3> c111 = sample_lut_texel(image, x1, y1, z1 + z_offset);
|
||||
|
||||
const std::array<float, 3> c00 = lerp_color(c000, c100, tx);
|
||||
const std::array<float, 3> c10 = lerp_color(c010, c110, tx);
|
||||
const std::array<float, 3> c01 = lerp_color(c001, c101, tx);
|
||||
const std::array<float, 3> c11 = lerp_color(c011, c111, tx);
|
||||
const std::array<float, 3> c0 = lerp_color(c00, c10, ty);
|
||||
const std::array<float, 3> c1 = lerp_color(c01, c11, ty);
|
||||
return lerp_color(c0, c1, tz);
|
||||
}
|
||||
|
||||
std::array<float, 4> color_to_pigment(const LutImage &image, const std::array<float, 3> &color)
|
||||
{
|
||||
const std::array<float, 3> sampled = sample_lut(image, color, 0);
|
||||
std::array<float, 4> pigment {
|
||||
sampled[0],
|
||||
sampled[1],
|
||||
sampled[2],
|
||||
1.f - sampled[0] - sampled[1] - sampled[2]
|
||||
};
|
||||
|
||||
const float total = pigment[0] + pigment[1] + pigment[2] + pigment[3];
|
||||
if (total > 0.0001f) {
|
||||
const float inv_total = 1.f / total;
|
||||
for (float &value : pigment)
|
||||
value *= inv_total;
|
||||
}
|
||||
|
||||
return pigment;
|
||||
}
|
||||
|
||||
std::array<float, 3> pigment_to_color(const LutImage &image, const std::array<float, 4> &pigment)
|
||||
{
|
||||
return sample_lut(image, { pigment[0], pigment[1], pigment[2] }, k_lut_dimen);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_with_lut(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<float> &weights,
|
||||
const LutImage &image)
|
||||
{
|
||||
std::array<float, 4> mixed_pigment { 0.f, 0.f, 0.f, 0.f };
|
||||
std::array<float, 3> error { 0.f, 0.f, 0.f };
|
||||
float total_weight = 0.f;
|
||||
|
||||
for (const float weight : weights) {
|
||||
if (std::isfinite(weight) && weight > 0.f)
|
||||
total_weight += weight;
|
||||
}
|
||||
|
||||
if (total_weight <= 0.f)
|
||||
return colors.front();
|
||||
|
||||
const float inv_total_weight = 1.f / total_weight;
|
||||
for (size_t idx = 0; idx < colors.size(); ++idx) {
|
||||
const float raw_weight = weights[idx];
|
||||
if (!std::isfinite(raw_weight) || raw_weight <= 0.f)
|
||||
continue;
|
||||
|
||||
const float weight = raw_weight * inv_total_weight;
|
||||
const std::array<float, 4> pigment = color_to_pigment(image, colors[idx]);
|
||||
const std::array<float, 3> reconstructed = pigment_to_color(image, pigment);
|
||||
|
||||
for (size_t channel = 0; channel < 4; ++channel)
|
||||
mixed_pigment[channel] += pigment[channel] * weight;
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
error[channel] += (clamp01(colors[idx][channel]) - reconstructed[channel]) * weight;
|
||||
}
|
||||
|
||||
const float pigment_total = mixed_pigment[0] + mixed_pigment[1] + mixed_pigment[2] + mixed_pigment[3];
|
||||
if (pigment_total > 0.0001f) {
|
||||
const float inv_pigment_total = 1.f / pigment_total;
|
||||
for (float &value : mixed_pigment)
|
||||
value *= inv_pigment_total;
|
||||
}
|
||||
|
||||
std::array<float, 3> mixed_color = pigment_to_color(image, mixed_pigment);
|
||||
for (size_t channel = 0; channel < 3; ++channel)
|
||||
mixed_color[channel] = clamp01(mixed_color[channel] + error[channel]);
|
||||
|
||||
return mixed_color;
|
||||
}
|
||||
|
||||
float reflectance_to_ks(float reflectance)
|
||||
{
|
||||
constexpr float k_min_reflectance = 0.02f;
|
||||
const float r = std::clamp(reflectance, k_min_reflectance, 1.f);
|
||||
return ((1.f - r) * (1.f - r)) / (2.f * r);
|
||||
}
|
||||
|
||||
float ks_to_reflectance(float ks)
|
||||
{
|
||||
const float ratio = std::max(0.f, ks);
|
||||
return clamp01(1.f + ratio - std::sqrt(std::max(0.f, ratio * ratio + 2.f * ratio)));
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_linear_reflectance(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<float> &weights)
|
||||
{
|
||||
if (colors.empty() || colors.size() != weights.size())
|
||||
return { 0.f, 0.f, 0.f };
|
||||
|
||||
if (const LutImage *image = lut_image(); image != nullptr)
|
||||
return mix_with_lut(colors, weights, *image);
|
||||
|
||||
std::array<float, 3> accumulated_ks { 0.f, 0.f, 0.f };
|
||||
float total_weight = 0.f;
|
||||
for (size_t idx = 0; idx < colors.size(); ++idx) {
|
||||
const float weight = std::max(0.f, weights[idx]);
|
||||
if (!std::isfinite(weight) || weight <= 0.f)
|
||||
continue;
|
||||
|
||||
accumulated_ks[0] += reflectance_to_ks(srgb_to_linear(colors[idx][0])) * weight;
|
||||
accumulated_ks[1] += reflectance_to_ks(srgb_to_linear(colors[idx][1])) * weight;
|
||||
accumulated_ks[2] += reflectance_to_ks(srgb_to_linear(colors[idx][2])) * weight;
|
||||
total_weight += weight;
|
||||
}
|
||||
|
||||
if (total_weight <= 0.f)
|
||||
return colors.front();
|
||||
|
||||
const float inv_total = 1.f / total_weight;
|
||||
return {
|
||||
linear_to_srgb(ks_to_reflectance(accumulated_ks[0] * inv_total)),
|
||||
linear_to_srgb(ks_to_reflectance(accumulated_ks[1] * inv_total)),
|
||||
linear_to_srgb(ks_to_reflectance(accumulated_ks[2] * inv_total))
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::array<float, 3> mix_srgb(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<float> &weights)
|
||||
{
|
||||
return mix_linear_reflectance(colors, weights);
|
||||
}
|
||||
|
||||
std::array<float, 3> mix_srgb(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<int> &weights)
|
||||
{
|
||||
std::vector<float> float_weights;
|
||||
float_weights.reserve(weights.size());
|
||||
for (const int weight : weights)
|
||||
float_weights.emplace_back(float(std::max(0, weight)));
|
||||
return mix_linear_reflectance(colors, float_weights);
|
||||
}
|
||||
|
||||
} // namespace pigment_painter
|
||||
17
deps_src/pigment-painter/pigment_painter_mixer.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef PIGMENT_PAINTER_MIXER_HPP
|
||||
#define PIGMENT_PAINTER_MIXER_HPP
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
namespace pigment_painter {
|
||||
|
||||
std::array<float, 3> mix_srgb(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<float> &weights);
|
||||
|
||||
std::array<float, 3> mix_srgb(const std::vector<std::array<float, 3>> &colors,
|
||||
const std::vector<int> &weights);
|
||||
|
||||
} // namespace pigment_painter
|
||||
|
||||
#endif
|
||||
10
deps_src/prusa-fdm-mixer/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(prusa_fdm_mixer)
|
||||
|
||||
add_library(prusa_fdm_mixer STATIC
|
||||
prusa_fdm_mixer.cpp
|
||||
prusa_fdm_mixer.hpp
|
||||
)
|
||||
|
||||
target_include_directories(prusa_fdm_mixer PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_compile_features(prusa_fdm_mixer PUBLIC cxx_std_17)
|
||||
21
deps_src/prusa-fdm-mixer/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Ondrej Bartas (Prusa Research s.r.o.) and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
351
deps_src/prusa-fdm-mixer/prusa_fdm_mixer.cpp
Normal file
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* prusa_fdm_mixer.cpp — Implementation of the prusa-fdm-mixer color mixing model.
|
||||
*
|
||||
* Copyright (c) Prusa Research s.r.o.
|
||||
* MIT License — see LICENSE.
|
||||
*/
|
||||
|
||||
#include "prusa_fdm_mixer.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace prusa_fdm_mixer {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr double PI = 3.14159265358979323846;
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* sRGB <-> linear RGB
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
inline double srgb_to_linear(double c) {
|
||||
c = c / 255.0;
|
||||
if (c <= 0.04045) return c / 12.92;
|
||||
return std::pow((c + 0.055) / 1.055, 2.4);
|
||||
}
|
||||
|
||||
inline double linear_to_srgb(double c) {
|
||||
c = std::clamp(c, 0.0, 1.0);
|
||||
double v;
|
||||
if (c <= 0.0031308) v = 12.92 * c;
|
||||
else v = 1.055 * std::pow(c, 1.0 / 2.4) - 0.055;
|
||||
return v * 255.0;
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* sRGB <-> XYZ (D65)
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
struct XYZ { double x, y, z; };
|
||||
|
||||
inline XYZ rgb_to_xyz(const RGB& rgb) {
|
||||
const double r = srgb_to_linear(rgb.r);
|
||||
const double g = srgb_to_linear(rgb.g);
|
||||
const double b = srgb_to_linear(rgb.b);
|
||||
return XYZ{
|
||||
(r * 0.4124564 + g * 0.3575761 + b * 0.1804375) * 100.0,
|
||||
(r * 0.2126729 + g * 0.7151522 + b * 0.0721750) * 100.0,
|
||||
(r * 0.0193339 + g * 0.1191920 + b * 0.9503041) * 100.0,
|
||||
};
|
||||
}
|
||||
|
||||
inline RGB xyz_to_rgb(const XYZ& xyz) {
|
||||
const double x = xyz.x / 100.0;
|
||||
const double y = xyz.y / 100.0;
|
||||
const double z = xyz.z / 100.0;
|
||||
const double r = linear_to_srgb(x * 3.2404542 + y * -1.5371385 + z * -0.4985314);
|
||||
const double g = linear_to_srgb(x * -0.9692660 + y * 1.8760108 + z * 0.0415560);
|
||||
const double b = linear_to_srgb(x * 0.0556434 + y * -0.2040259 + z * 1.0572252);
|
||||
auto clamp_round = [](double v) -> std::uint8_t {
|
||||
const long iv = std::lround(v);
|
||||
return static_cast<std::uint8_t>(std::clamp<long>(iv, 0, 255));
|
||||
};
|
||||
return RGB{ clamp_round(r), clamp_round(g), clamp_round(b) };
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
* XYZ <-> CIELAB (D65)
|
||||
* -------------------------------------------------------------------------- */
|
||||
|
||||
constexpr double XN = 95.047;
|
||||
constexpr double YN = 100.0;
|
||||
constexpr double ZN = 108.883;
|
||||
|
||||
inline double lab_f(double t) {
|
||||
return (t > 0.008856) ? std::cbrt(t) : (7.787 * t + 16.0 / 116.0);
|
||||
}
|
||||
|
||||
inline double lab_f_inv(double t) {
|
||||
return (t > 0.206893) ? (t * t * t) : ((t - 16.0 / 116.0) / 7.787);
|
||||
}
|
||||
|
||||
inline LAB xyz_to_lab(const XYZ& xyz) {
|
||||
const double fx = lab_f(xyz.x / XN);
|
||||
const double fy = lab_f(xyz.y / YN);
|
||||
const double fz = lab_f(xyz.z / ZN);
|
||||
return LAB{ 116.0 * fy - 16.0, 500.0 * (fx - fy), 200.0 * (fy - fz) };
|
||||
}
|
||||
|
||||
inline XYZ lab_to_xyz(const LAB& lab) {
|
||||
const double fy = (lab.L + 16.0) / 116.0;
|
||||
const double fx = lab.a / 500.0 + fy;
|
||||
const double fz = fy - lab.b / 200.0;
|
||||
return XYZ{ XN * lab_f_inv(fx), YN * lab_f_inv(fy), ZN * lab_f_inv(fz) };
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
/* ============================================================================
|
||||
* Public color-space helpers
|
||||
* ============================================================================ */
|
||||
|
||||
RGB hex_to_rgb(const std::string& hex) {
|
||||
std::string s = hex;
|
||||
if (!s.empty() && s[0] == '#') s.erase(0, 1);
|
||||
if (s.size() != 6) {
|
||||
throw std::invalid_argument("prusa_fdm_mixer::hex_to_rgb: expected 6 hex digits, got: " + hex);
|
||||
}
|
||||
auto parse_byte = [&](size_t off) -> std::uint8_t {
|
||||
unsigned int v = 0;
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
char c = s[off + i];
|
||||
unsigned int d;
|
||||
if (c >= '0' && c <= '9') d = static_cast<unsigned int>(c - '0');
|
||||
else if (c >= 'a' && c <= 'f') d = 10u + static_cast<unsigned int>(c - 'a');
|
||||
else if (c >= 'A' && c <= 'F') d = 10u + static_cast<unsigned int>(c - 'A');
|
||||
else throw std::invalid_argument("prusa_fdm_mixer::hex_to_rgb: invalid hex char in: " + hex);
|
||||
v = (v << 4) | d;
|
||||
}
|
||||
return static_cast<std::uint8_t>(v);
|
||||
};
|
||||
return RGB{ parse_byte(0), parse_byte(2), parse_byte(4) };
|
||||
}
|
||||
|
||||
std::string rgb_to_hex(const RGB& rgb) {
|
||||
char buf[8];
|
||||
std::snprintf(buf, sizeof(buf), "#%02x%02x%02x",
|
||||
static_cast<unsigned int>(rgb.r),
|
||||
static_cast<unsigned int>(rgb.g),
|
||||
static_cast<unsigned int>(rgb.b));
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
LAB rgb_to_lab(const RGB& rgb) {
|
||||
return xyz_to_lab(rgb_to_xyz(rgb));
|
||||
}
|
||||
|
||||
RGB lab_to_rgb(const LAB& lab) {
|
||||
return xyz_to_rgb(lab_to_xyz(lab));
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* prusa-fdm-mixer model
|
||||
* ============================================================================ */
|
||||
|
||||
namespace {
|
||||
|
||||
// Empirically fit constants — see companion repo for derivation.
|
||||
constexpr double YN_EXPONENT = 3.0;
|
||||
constexpr double L_SLOPE = -0.0477;
|
||||
constexpr double L_INTERCEPT = -2.112;
|
||||
constexpr double L_KINK_THRESHOLD = 15.0;
|
||||
constexpr double L_KINK_SLOPE = -0.060;
|
||||
constexpr double C_SLOPE = 0.2780;
|
||||
constexpr double C_INTERCEPT = -15.580;
|
||||
constexpr double PEAK_STRENGTH = 1.375;
|
||||
constexpr double HUE_PEAK_DEG = 10.38;
|
||||
constexpr double HUE_CENTER_DEG = 210.0;
|
||||
constexpr double HUE_HALF_WIDTH_DEG = 30.0;
|
||||
|
||||
LAB predict_lab(const std::vector<Part>& parts) {
|
||||
if (parts.empty()) {
|
||||
throw std::invalid_argument("prusa_fdm_mixer::mix: empty parts list");
|
||||
}
|
||||
|
||||
// ---- Gradient safety: if any single part has ratio >= ~1, return it directly. ----
|
||||
// Without this guard, the constant lightness correction (-2.112 * cs) would
|
||||
// perturb the predicted color even at the endpoints of a gradient.
|
||||
for (const Part& p : parts) {
|
||||
if (p.ratio >= 0.9999) {
|
||||
return rgb_to_lab(hex_to_rgb(p.hex));
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Step 1: Yule-Nielsen base prediction ----
|
||||
double r_acc = 0.0, g_acc = 0.0, b_acc = 0.0;
|
||||
std::vector<double> component_Ls;
|
||||
component_Ls.reserve(parts.size());
|
||||
|
||||
const double inv_n = 1.0 / YN_EXPONENT;
|
||||
for (const Part& p : parts) {
|
||||
const RGB rgb = hex_to_rgb(p.hex);
|
||||
const double r_lin = srgb_to_linear(rgb.r);
|
||||
const double g_lin = srgb_to_linear(rgb.g);
|
||||
const double b_lin = srgb_to_linear(rgb.b);
|
||||
r_acc += std::pow(r_lin, inv_n) * p.ratio;
|
||||
g_acc += std::pow(g_lin, inv_n) * p.ratio;
|
||||
b_acc += std::pow(b_lin, inv_n) * p.ratio;
|
||||
component_Ls.push_back(rgb_to_lab(rgb).L);
|
||||
}
|
||||
|
||||
auto pow_clamped = [](double v, double exp) {
|
||||
return std::pow(std::max(0.0, v), exp);
|
||||
};
|
||||
const double yn_r = linear_to_srgb(pow_clamped(r_acc, YN_EXPONENT));
|
||||
const double yn_g = linear_to_srgb(pow_clamped(g_acc, YN_EXPONENT));
|
||||
const double yn_b = linear_to_srgb(pow_clamped(b_acc, YN_EXPONENT));
|
||||
|
||||
auto clamp_round = [](double v) -> std::uint8_t {
|
||||
const long iv = std::lround(v);
|
||||
return static_cast<std::uint8_t>(std::clamp<long>(iv, 0, 255));
|
||||
};
|
||||
const RGB yn_rgb{ clamp_round(yn_r), clamp_round(yn_g), clamp_round(yn_b) };
|
||||
const LAB base = rgb_to_lab(yn_rgb);
|
||||
|
||||
// ---- Bell-curve weight ----
|
||||
// For N components: w = N^N * prod(ratios)
|
||||
// = 1 when ratios are equal (peak correction zone)
|
||||
// = 0 at any endpoint (single-component, no correction needed)
|
||||
double w = 1.0;
|
||||
for (const Part& p : parts) w *= p.ratio;
|
||||
w *= std::pow(static_cast<double>(parts.size()),
|
||||
static_cast<double>(parts.size()));
|
||||
w = std::clamp(w, 0.0, 1.0);
|
||||
const double cs = w * PEAK_STRENGTH;
|
||||
|
||||
// ---- Step 2: piecewise lightness correction ----
|
||||
const double L_min = *std::min_element(component_Ls.begin(), component_Ls.end());
|
||||
const double L_max = *std::max_element(component_Ls.begin(), component_Ls.end());
|
||||
const double L_gap = L_max - L_min;
|
||||
|
||||
double L_corr = L_SLOPE * L_gap + L_INTERCEPT;
|
||||
if (L_gap > L_KINK_THRESHOLD) {
|
||||
L_corr += L_KINK_SLOPE * (L_gap - L_KINK_THRESHOLD);
|
||||
}
|
||||
L_corr *= cs;
|
||||
const double L_new = base.L + L_corr;
|
||||
|
||||
// ---- Step 3: chroma correction ----
|
||||
double a_out = base.a;
|
||||
double b_out = base.b;
|
||||
const double pred_C = std::hypot(base.a, base.b);
|
||||
if (pred_C >= 0.01) {
|
||||
const double target_dC = (C_SLOPE * L_new + C_INTERCEPT) * cs;
|
||||
const double new_C = std::max(0.0, pred_C + target_dC);
|
||||
const double scale = new_C / pred_C;
|
||||
a_out = base.a * scale;
|
||||
b_out = base.b * scale;
|
||||
}
|
||||
|
||||
// ---- Step 4: cyan-band hue rotation ----
|
||||
const double new_C_final = std::hypot(a_out, b_out);
|
||||
if (new_C_final >= 1.0) {
|
||||
double pred_h = std::atan2(b_out, a_out) * 180.0 / PI;
|
||||
if (pred_h < 0.0) pred_h += 360.0;
|
||||
|
||||
double h_corr = 0.0;
|
||||
if (pred_h >= HUE_CENTER_DEG - HUE_HALF_WIDTH_DEG &&
|
||||
pred_h < HUE_CENTER_DEG + HUE_HALF_WIDTH_DEG) {
|
||||
const double dist = std::abs(pred_h - HUE_CENTER_DEG);
|
||||
const double falloff = std::max(0.0, 1.0 - dist / HUE_HALF_WIDTH_DEG);
|
||||
h_corr = HUE_PEAK_DEG * falloff * w;
|
||||
}
|
||||
if (h_corr != 0.0) {
|
||||
double new_h = std::fmod(pred_h + h_corr, 360.0);
|
||||
if (new_h < 0.0) new_h += 360.0;
|
||||
const double new_h_rad = new_h * PI / 180.0;
|
||||
a_out = new_C_final * std::cos(new_h_rad);
|
||||
b_out = new_C_final * std::sin(new_h_rad);
|
||||
}
|
||||
}
|
||||
|
||||
return LAB{ L_new, a_out, b_out };
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
RGB mix_rgb(const std::vector<Part>& parts) {
|
||||
return lab_to_rgb(predict_lab(parts));
|
||||
}
|
||||
|
||||
std::string mix(const std::vector<Part>& parts) {
|
||||
return rgb_to_hex(mix_rgb(parts));
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
* ΔE2000
|
||||
* ============================================================================ */
|
||||
|
||||
double delta_e_2000(const LAB& lab1, const LAB& lab2) {
|
||||
const double L1 = lab1.L, a1 = lab1.a, b1 = lab1.b;
|
||||
const double L2 = lab2.L, a2 = lab2.a, b2 = lab2.b;
|
||||
|
||||
const double avg_L = (L1 + L2) / 2.0;
|
||||
const double C1 = std::hypot(a1, b1);
|
||||
const double C2 = std::hypot(a2, b2);
|
||||
const double avg_C = (C1 + C2) / 2.0;
|
||||
const double avg_C7 = std::pow(avg_C, 7.0);
|
||||
const double pow25_7 = std::pow(25.0, 7.0);
|
||||
const double G = 0.5 * (1.0 - std::sqrt(avg_C7 / (avg_C7 + pow25_7)));
|
||||
|
||||
const double a1p = a1 * (1.0 + G);
|
||||
const double a2p = a2 * (1.0 + G);
|
||||
const double C1p = std::hypot(a1p, b1);
|
||||
const double C2p = std::hypot(a2p, b2);
|
||||
const double avg_Cp = (C1p + C2p) / 2.0;
|
||||
|
||||
auto deg = [](double x) {
|
||||
double d = x * 180.0 / PI;
|
||||
if (d < 0.0) d += 360.0;
|
||||
return d;
|
||||
};
|
||||
const double h1p = deg(std::atan2(b1, a1p));
|
||||
const double h2p = deg(std::atan2(b2, a2p));
|
||||
|
||||
double dHp_diff = h2p - h1p;
|
||||
double dhp = 0.0;
|
||||
if (C1p * C2p != 0.0) {
|
||||
if (std::abs(dHp_diff) <= 180.0) dhp = dHp_diff;
|
||||
else if (dHp_diff > 180.0) dhp = dHp_diff - 360.0;
|
||||
else dhp = dHp_diff + 360.0;
|
||||
}
|
||||
|
||||
double avg_Hp;
|
||||
if (C1p * C2p == 0.0) avg_Hp = h1p + h2p;
|
||||
else if (std::abs(h1p - h2p) <= 180.0) avg_Hp = (h1p + h2p) / 2.0;
|
||||
else if (h1p + h2p < 360.0) avg_Hp = (h1p + h2p + 360.0) / 2.0;
|
||||
else avg_Hp = (h1p + h2p - 360.0) / 2.0;
|
||||
|
||||
const double T = 1.0
|
||||
- 0.17 * std::cos((avg_Hp - 30.0) * PI / 180.0)
|
||||
+ 0.24 * std::cos((2.0 * avg_Hp) * PI / 180.0)
|
||||
+ 0.32 * std::cos((3.0 * avg_Hp + 6.0) * PI / 180.0)
|
||||
- 0.20 * std::cos((4.0 * avg_Hp - 63.0) * PI / 180.0);
|
||||
|
||||
const double dLp = L2 - L1;
|
||||
const double dCp = C2p - C1p;
|
||||
const double dHpFinal = 2.0 * std::sqrt(C1p * C2p) * std::sin(dhp * PI / 360.0);
|
||||
|
||||
const double SL = 1.0 + (0.015 * std::pow(avg_L - 50.0, 2.0))
|
||||
/ std::sqrt(20.0 + std::pow(avg_L - 50.0, 2.0));
|
||||
const double SC = 1.0 + 0.045 * avg_Cp;
|
||||
const double SH = 1.0 + 0.015 * avg_Cp * T;
|
||||
|
||||
const double dTheta = 30.0 * std::exp(-std::pow((avg_Hp - 275.0) / 25.0, 2.0));
|
||||
const double avg_Cp7 = std::pow(avg_Cp, 7.0);
|
||||
const double RC = 2.0 * std::sqrt(avg_Cp7 / (avg_Cp7 + pow25_7));
|
||||
const double RT = -RC * std::sin(2.0 * dTheta * PI / 180.0);
|
||||
|
||||
return std::sqrt(
|
||||
std::pow(dLp / SL, 2.0) +
|
||||
std::pow(dCp / SC, 2.0) +
|
||||
std::pow(dHpFinal / SH, 2.0) +
|
||||
RT * (dCp / SC) * (dHpFinal / SH)
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace prusa_fdm_mixer
|
||||
99
deps_src/prusa-fdm-mixer/prusa_fdm_mixer.hpp
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* prusa_fdm_mixer.hpp — Predicts the apparent color of FDM filament mixes.
|
||||
*
|
||||
* The prusa-fdm-mixer model, calibrated against measured prints. Produces
|
||||
* predictions with a median ΔE2000 of ~5.7 against real samples
|
||||
* (Linear RGB ~14.5 for comparison).
|
||||
*
|
||||
* Drop-in usage in PrusaSlicer / OrcaSlicer / any C++17 project:
|
||||
*
|
||||
* #include "prusa_fdm_mixer.hpp"
|
||||
*
|
||||
* std::vector<prusa_fdm_mixer::Part> parts = {
|
||||
* { "#007a9d", 0.75 }, // 75% azure blue
|
||||
* { "#f6b921", 0.25 }, // 25% yellow
|
||||
* };
|
||||
* std::string mixed_hex = prusa_fdm_mixer::mix(parts);
|
||||
* // mixed_hex == "#XXXXXX" — predicted apparent color
|
||||
*
|
||||
* Properties:
|
||||
* - Gradient-safe: a part with ratio 1.0 returns that part's hex exactly.
|
||||
* - Smooth: small ratio changes produce small color changes.
|
||||
* - Works for 2 or 3+ components; ratios should sum to 1.
|
||||
*
|
||||
* No external dependencies beyond the C++ standard library.
|
||||
*
|
||||
* Copyright (c) Prusa Research s.r.o.
|
||||
* MIT License — see LICENSE.
|
||||
*/
|
||||
|
||||
#ifndef PRUSA_FDM_MIXER_HPP
|
||||
#define PRUSA_FDM_MIXER_HPP
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace prusa_fdm_mixer {
|
||||
|
||||
/** A single filament component in a mix. */
|
||||
struct Part {
|
||||
/** 6-digit hex color including leading '#', e.g. "#aabbcc". */
|
||||
std::string hex;
|
||||
/** Mixing ratio in [0, 1]. Ratios across all parts should sum to 1. */
|
||||
double ratio;
|
||||
};
|
||||
|
||||
/** RGB triple, channel values in [0, 255]. */
|
||||
struct RGB {
|
||||
std::uint8_t r;
|
||||
std::uint8_t g;
|
||||
std::uint8_t b;
|
||||
};
|
||||
|
||||
/** CIELAB triple — L in [0, 100], a/b unbounded but typically [-128, 127]. */
|
||||
struct LAB {
|
||||
double L;
|
||||
double a;
|
||||
double b;
|
||||
};
|
||||
|
||||
/* ============================================================================
|
||||
* Public API
|
||||
* ============================================================================ */
|
||||
|
||||
/**
|
||||
* Predict the apparent color when filaments are mixed in the given ratios.
|
||||
* @param parts Two or more parts; ratios should sum to ~1.
|
||||
* @return Predicted hex color, e.g. "#aabbcc".
|
||||
*/
|
||||
std::string mix(const std::vector<Part>& parts);
|
||||
|
||||
/**
|
||||
* Same as mix() but returns an RGB struct.
|
||||
*/
|
||||
RGB mix_rgb(const std::vector<Part>& parts);
|
||||
|
||||
/* ============================================================================
|
||||
* Color-space conversions (exposed for callers who want them)
|
||||
* ============================================================================ */
|
||||
|
||||
/** Parse a "#rrggbb" hex string. Throws std::invalid_argument on bad input. */
|
||||
RGB hex_to_rgb(const std::string& hex);
|
||||
|
||||
/** Format an RGB as "#rrggbb" lowercase. */
|
||||
std::string rgb_to_hex(const RGB& rgb);
|
||||
|
||||
/** Convert sRGB (0-255 channels) to CIELAB (D65 white point). */
|
||||
LAB rgb_to_lab(const RGB& rgb);
|
||||
|
||||
/** Convert CIELAB (D65 white point) back to sRGB (0-255 channels, clamped). */
|
||||
RGB lab_to_rgb(const LAB& lab);
|
||||
|
||||
/** ΔE2000 perceptual color difference between two LAB colors. */
|
||||
double delta_e_2000(const LAB& lab1, const LAB& lab2);
|
||||
|
||||
} // namespace prusa_fdm_mixer
|
||||
|
||||
#endif // PRUSA_FDM_MIXER_HPP
|
||||
8
deps_src/tinygltf/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
add_library(tinygltf_v3 STATIC tiny_gltf_v3.c)
|
||||
|
||||
target_include_directories(tinygltf_v3 PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
set_target_properties(tinygltf_v3 PROPERTIES
|
||||
C_STANDARD 11
|
||||
C_STANDARD_REQUIRED ON
|
||||
)
|
||||
21
deps_src/tinygltf/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
3278
deps_src/tinygltf/tiny_gltf_v3.c
Normal file
4477
deps_src/tinygltf/tiny_gltf_v3.h
Normal file
1024
deps_src/tinygltf/tinygltf_json_c.h
Normal file
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\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"
|
||||
@@ -1708,6 +1708,25 @@ msgstr ""
|
||||
msgid "Untitled"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1736,6 +1755,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, possible-c-format, possible-boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr ""
|
||||
@@ -5611,7 +5638,7 @@ msgstr ""
|
||||
msgid "Save current project as"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr ""
|
||||
|
||||
msgid "Load a model"
|
||||
@@ -8259,6 +8286,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -11468,6 +11505,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-03-15 10:55+0100\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -1786,6 +1786,35 @@ msgstr "OrcaSlicer ha tingut una excepció no gestionada: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Sense títol"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Des de la versió 2.4.0, OrcaSlicer sincronitza els perfils d'usuari a través "
|
||||
"d'Orca Cloud en lloc de Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Per migrar els teus perfils existents, inicia la sessió a Orca Cloud i es "
|
||||
"transferiran automàticament. Per obtenir més informació sobre com OrcaSlicer "
|
||||
"emmagatzema i sincronitza els teus perfils, o per migrar els teus perfils "
|
||||
"manualment, consulta la nostra wiki.\n"
|
||||
"\n"
|
||||
"Si no feies servir Bambu Cloud per sincronitzar perfils, aquest canvi no "
|
||||
"t'afecta i pots ignorar aquest missatge amb tranquil·litat."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Recarregant el connector de xarxa..."
|
||||
|
||||
@@ -1819,6 +1848,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "El camí de recursos no existeix o no és un directori: %s"
|
||||
@@ -6089,8 +6126,8 @@ msgstr "Desa el projecte com a"
|
||||
msgid "Save current project as"
|
||||
msgstr "Desar el projecte actual com"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importar 3MF STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importar 3MF STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Carregar un model"
|
||||
@@ -9031,6 +9068,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12745,6 +12792,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generant Faldilla i Vora d'Adherència"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportant el Codi-G"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Jakub Hencl\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1753,6 +1753,35 @@ msgstr "OrcaSlicer narazil na neošetřenou výjimku: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Bez názvu"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Od verze 2.4.0 OrcaSlicer synchronizuje uživatelské profily prostřednictvím "
|
||||
"Orca Cloud namísto Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Chcete-li migrovat své stávající profily, přihlaste se k Orca Cloud a budou "
|
||||
"automaticky přeneseny. Další informace o tom, jak OrcaSlicer ukládá a "
|
||||
"synchronizuje vaše profily, nebo o ruční migraci vašich předvoleb najdete na "
|
||||
"naší wiki.\n"
|
||||
"\n"
|
||||
"Pokud jste k synchronizaci profilů nepoužívali Bambu Cloud, tato změna se "
|
||||
"vás netýká a můžete tuto zprávu klidně ignorovat."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Znovunačítání síťového plug-inu..."
|
||||
|
||||
@@ -1784,6 +1813,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Cesta ke zdrojům neexistuje nebo není adresář: %s"
|
||||
@@ -6011,8 +6048,8 @@ msgstr "Uložit projekt jako"
|
||||
msgid "Save current project as"
|
||||
msgstr "Uložit aktuální projekt jako"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importovat 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importovat 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Načíst model"
|
||||
@@ -8905,6 +8942,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12521,6 +12568,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generování sukně a lemu"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportuji G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Heiko Liebscher <hliebschergmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1787,6 +1787,36 @@ msgstr "OrcaSlicer hat eine unbehandelte Ausnahme erzeugt: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Unbenannt"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Seit Version 2.4.0 synchronisiert OrcaSlicer Benutzerprofile über Orca Cloud "
|
||||
"anstelle der Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Um Ihre vorhandenen Profile zu migrieren, melden Sie sich bei Orca Cloud an, "
|
||||
"dann werden sie automatisch übertragen. Weitere Informationen darüber, wie "
|
||||
"OrcaSlicer Ihre Profile speichert und synchronisiert, oder wie Sie Ihre "
|
||||
"Profile manuell migrieren, finden Sie in unserem Wiki.\n"
|
||||
"\n"
|
||||
"Wenn Sie die Bambu Cloud nicht zum Synchronisieren von Profilen verwendet "
|
||||
"haben, betrifft Sie diese Änderung nicht und Sie können diese Meldung "
|
||||
"ignorieren."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr "Mehr erfahren"
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Netzwerk-Plugin wird neu geladen..."
|
||||
|
||||
@@ -1818,6 +1848,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2-Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Ressourcenpfad existiert nicht oder ist kein Verzeichnis: %s"
|
||||
@@ -6181,8 +6219,8 @@ msgstr "Projekt speichern als"
|
||||
msgid "Save current project as"
|
||||
msgstr "Aktuelles Projekt speichern als"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importiere 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importiere 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Lade ein Modell"
|
||||
@@ -9168,6 +9206,16 @@ msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
"Zeigt geworfene Schatten auf der Platte in der realistischen Ansicht an."
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "Kantenglättung"
|
||||
|
||||
@@ -13006,6 +13054,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generieren von Schürze und Rand (skirt & brim)"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportiere G-Code"
|
||||
|
||||
@@ -25799,9 +25855,6 @@ msgstr ""
|
||||
#~ "Die automatische Kalibrierung unterstützt nur Fälle, in denen die linken "
|
||||
#~ "und rechten Düsendurchmesser identisch sind."
|
||||
|
||||
#~ msgid "Learn more"
|
||||
#~ msgstr "Mehr erfahren"
|
||||
|
||||
#~ msgid "✖ Skipped %1%: %2%, same file\n"
|
||||
#~ msgstr "✖ %1% übersprungen: %2%, gleiche Datei\n"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-05-18 09:32-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1706,6 +1706,25 @@ msgstr ""
|
||||
msgid "Untitled"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1734,6 +1753,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr ""
|
||||
@@ -5668,7 +5695,7 @@ msgstr ""
|
||||
msgid "Save current project as"
|
||||
msgstr ""
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr ""
|
||||
|
||||
msgid "Load a model"
|
||||
@@ -8351,6 +8378,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -11624,6 +11661,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Ian A. Bassi <>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1788,6 +1788,35 @@ msgstr "OrcaSlicer recibió una notificación de excepción no controlada: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Sin título"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Desde la versión 2.4.0, OrcaSlicer sincroniza los perfiles de usuario a "
|
||||
"través de Orca Cloud en lugar de Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Para migrar tus perfiles existentes, inicia sesión en Orca Cloud y se "
|
||||
"transferirán automáticamente. Para obtener más información sobre cómo "
|
||||
"OrcaSlicer almacena y sincroniza tus perfiles, o para migrar tus perfiles "
|
||||
"manualmente, consulta nuestra wiki.\n"
|
||||
"\n"
|
||||
"Si no usabas Bambu Cloud para sincronizar perfiles, este cambio no te afecta "
|
||||
"y puedes ignorar este mensaje con seguridad."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Recargando el complemento de red..."
|
||||
|
||||
@@ -1821,6 +1850,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "La ruta de recursos no existe o no es un directorio: %s"
|
||||
@@ -6169,8 +6206,8 @@ msgstr "Guardar proyecto como"
|
||||
msgid "Save current project as"
|
||||
msgstr "Guardar el proyecto actual como"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importar 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importar 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Cargar un modelo"
|
||||
@@ -9154,6 +9191,16 @@ msgstr ""
|
||||
"Los objetos renderizados proyectan sombras sobre la cama en la vista "
|
||||
"realista."
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "Anti-aliasing"
|
||||
|
||||
@@ -12972,6 +13019,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generando falda y borde de adherencia"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportando G-Code"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Guislain Cyril, Thomas Lété\n"
|
||||
@@ -1807,6 +1807,35 @@ msgstr "Orca Slicer a reçu une exception non gérée : %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Sans titre"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Depuis la version 2.4.0, OrcaSlicer synchronise les profils utilisateur via "
|
||||
"Orca Cloud au lieu de Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Pour migrer vos profils existants, connectez-vous à Orca Cloud et ils seront "
|
||||
"transférés automatiquement. Pour en savoir plus sur la façon dont OrcaSlicer "
|
||||
"stocke et synchronise vos profils, ou pour migrer vos préréglages "
|
||||
"manuellement, consultez notre wiki.\n"
|
||||
"\n"
|
||||
"Si vous n'utilisiez pas Bambu Cloud pour synchroniser vos profils, ce "
|
||||
"changement ne vous concerne pas et vous pouvez ignorer ce message."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Rechargement du plug-in réseau…"
|
||||
|
||||
@@ -1838,6 +1867,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Le chemin des ressources n'existe pas ou n'est pas un répertoire : %s"
|
||||
@@ -6190,8 +6227,8 @@ msgstr "Enregistrer le projet sous"
|
||||
msgid "Save current project as"
|
||||
msgstr "Enregistrer le projet actuel sous"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importer des fichiers 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importer des fichiers 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Charger un modèle"
|
||||
@@ -9188,6 +9225,16 @@ msgstr "Ombres"
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr "Affiche les ombres portées sur la plaque dans la vue réaliste."
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "Anticrénelage"
|
||||
|
||||
@@ -13073,6 +13120,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Génération jupe et bord"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportation du G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"Language: hu\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -1770,6 +1770,36 @@ msgstr "Az OrcaSlicer kezeletlen kivételt kapott: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Névtelen"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"A 2.4.0-s verziótól kezdve az OrcaSlicer a felhasználói profilokat a Bambu "
|
||||
"Cloud helyett az Orca Cloudon keresztül szinkronizálja.\n"
|
||||
"\n"
|
||||
"Meglévő profiljai átviteléhez jelentkezzen be az Orca Cloudba, és azok "
|
||||
"automatikusan átkerülnek. Ha többet szeretne megtudni arról, hogyan tárolja "
|
||||
"és szinkronizálja az OrcaSlicer a profiljait, vagy ha kézzel szeretné "
|
||||
"átvinni a beállításait, tekintse meg a wikinket.\n"
|
||||
"\n"
|
||||
"Ha nem használta a Bambu Cloudot a profilok szinkronizálásához, ez a "
|
||||
"változás nem érinti Önt, és nyugodtan figyelmen kívül hagyhatja ezt az "
|
||||
"üzenetet."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Hálózati bővítmény újratöltése..."
|
||||
|
||||
@@ -1801,6 +1831,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Az erőforrások elérési útja nem létezik vagy nem könyvtár: %s"
|
||||
@@ -6086,8 +6124,8 @@ msgstr "Projekt mentése másként"
|
||||
msgid "Save current project as"
|
||||
msgstr "Jelenlegi projekt mentése másként"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importálás 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importálás 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Modell betöltése"
|
||||
@@ -9003,6 +9041,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "Élsimítás"
|
||||
|
||||
@@ -12776,6 +12824,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Szoknya & perem generálása"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "G-kód exportálása"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -1794,6 +1794,35 @@ msgstr "OrcaSlicer ha ricevuto un'eccezione non gestita: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Senza titolo"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Dalla versione 2.4.0, OrcaSlicer sincronizza i profili utente tramite Orca "
|
||||
"Cloud anziché Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Per migrare i tuoi profili esistenti, accedi a Orca Cloud e verranno "
|
||||
"trasferiti automaticamente. Per saperne di più su come OrcaSlicer memorizza "
|
||||
"e sincronizza i tuoi profili, o per migrare i tuoi profili manualmente, "
|
||||
"consulta la nostra wiki.\n"
|
||||
"\n"
|
||||
"Se non utilizzavi Bambu Cloud per sincronizzare i profili, questa modifica "
|
||||
"non ti riguarda e puoi ignorare questo messaggio."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Ricaricamento modulo di rete..."
|
||||
|
||||
@@ -1826,6 +1855,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Il percorso delle risorse non esiste o non è una directory: %s"
|
||||
@@ -6142,8 +6179,8 @@ msgstr "Salva progetto con nome"
|
||||
msgid "Save current project as"
|
||||
msgstr "Salva progetto corrente con nome"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importa 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importa 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Carica modello"
|
||||
@@ -9091,6 +9128,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12878,6 +12925,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generazione gonna e tesa"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Esportazione G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -1758,6 +1758,34 @@ msgstr "OrcaSlicerで未処理の例外が発生しました: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "名称未設定"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"バージョン 2.4.0 以降、OrcaSlicer はユーザープロファイルを Bambu Cloud ではな"
|
||||
"く Orca Cloud を通じて同期します。\n"
|
||||
"\n"
|
||||
"既存のプロファイルを移行するには、Orca Cloud にログインしてください。自動的に"
|
||||
"転送されます。OrcaSlicer がプロファイルを保存・同期する仕組みの詳細や、プリ"
|
||||
"セットを手動で移行する方法については、Wiki をご覧ください。\n"
|
||||
"\n"
|
||||
"プロファイルの同期に Bambu Cloud を使用していなかった場合、この変更の影響はあ"
|
||||
"りません。このメッセージは無視して問題ありません。"
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "ネットワークプラグインを再読み込み中..."
|
||||
|
||||
@@ -1788,6 +1816,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "リソースパスが存在しないかディレクトリではありません: %s"
|
||||
@@ -5945,8 +5981,8 @@ msgstr "プロジェクトを名前を付けて保存"
|
||||
msgid "Save current project as"
|
||||
msgstr "プロジェクトを名前を付けて保存"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/AMFをインポート"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMFをインポート"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "モデルを読み込む"
|
||||
@@ -8788,6 +8824,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12314,6 +12360,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "スカートとブリムを生成"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "G-codeをエクスポート中"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-06-02 17:12+0900\n"
|
||||
"Last-Translator: crwusiz <crwusiz@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1753,6 +1753,34 @@ msgstr "Orca Slicer에 처리되지 않은 예외가 발생했습니다: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "제목 없음"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"버전 2.4.0부터 OrcaSlicer는 사용자 프로파일을 Bambu Cloud 대신 Orca Cloud를 "
|
||||
"통해 동기화합니다.\n"
|
||||
"\n"
|
||||
"기존 프로파일을 이전하려면 Orca Cloud에 로그인하세요. 자동으로 전송됩니다. "
|
||||
"OrcaSlicer가 프로파일을 저장하고 동기화하는 방식에 대해 자세히 알아보거나 사"
|
||||
"전 설정을 수동으로 이전하려면 위키를 참조하세요.\n"
|
||||
"\n"
|
||||
"프로파일 동기화에 Bambu Cloud를 사용하지 않았다면 이 변경 사항은 영향을 주지 "
|
||||
"않으므로 이 메시지를 무시해도 됩니다."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "네트워크 플러그인 재로드 중..."
|
||||
|
||||
@@ -1784,6 +1812,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 런타임"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "리소스 경로가 존재하지 않거나 디렉토리가 아닙니다: %s"
|
||||
@@ -5923,8 +5959,8 @@ msgstr "프로젝트 다른 이름으로 저장"
|
||||
msgid "Save current project as"
|
||||
msgstr "현재 프로젝트 다른 이름으로 저장"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/AMF 가져오기"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF 가져오기"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "모델 불러오기"
|
||||
@@ -8715,6 +8751,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12207,6 +12253,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "스커트 & 브림 생성 중"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Gcode 내보내는 중"
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-10-25 23:01+0300\n"
|
||||
"Last-Translator: Gintaras Kučinskas <sharanchius@gmail.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1767,6 +1767,35 @@ msgstr "OrcaSlicer susidūrė su neapdorota klaida: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Be pavadinimo"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Nuo 2.4.0 versijos OrcaSlicer sinchronizuoja naudotojo profilius per Orca "
|
||||
"Cloud, o ne Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Norėdami perkelti esamus profilius, prisijunkite prie Orca Cloud ir jie bus "
|
||||
"perkelti automatiškai. Norėdami sužinoti daugiau apie tai, kaip OrcaSlicer "
|
||||
"saugo ir sinchronizuoja jūsų profilius, arba norėdami perkelti profilius "
|
||||
"rankiniu būdu, apsilankykite mūsų wiki.\n"
|
||||
"\n"
|
||||
"Jei profiliams sinchronizuoti nenaudojote Bambu Cloud, šis pakeitimas jums "
|
||||
"neaktualus ir šį pranešimą galite ignoruoti."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Reloading network plug-in..."
|
||||
|
||||
@@ -1798,6 +1827,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "\"WebView2\" paleidimo terpė"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Išteklių kelias neegzistuoja arba nėra katalogas: %s"
|
||||
@@ -6048,8 +6085,8 @@ msgstr "Išsaugoti projektą kaip"
|
||||
msgid "Save current project as"
|
||||
msgstr "Išsaugoti dabartinį projektą kaip"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importuoti 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importuoti 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Įkelti modelį"
|
||||
@@ -8946,6 +8983,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12625,6 +12672,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generuojamas apvadas ir kraštas"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Eksportuojamas G-kodas"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
@@ -1759,6 +1759,35 @@ msgstr "OrcaSlicer kreeg een onbehandelde uitzondering: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Naamloos"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Sinds versie 2.4.0 synchroniseert OrcaSlicer gebruikersprofielen via Orca "
|
||||
"Cloud in plaats van Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Om je bestaande profielen te migreren, log je in bij Orca Cloud en worden ze "
|
||||
"automatisch overgezet. Raadpleeg onze wiki voor meer informatie over hoe "
|
||||
"OrcaSlicer je profielen opslaat en synchroniseert, of om je voorinstellingen "
|
||||
"handmatig te migreren.\n"
|
||||
"\n"
|
||||
"Als je Bambu Cloud niet gebruikte om profielen te synchroniseren, heeft deze "
|
||||
"wijziging geen invloed op jou en kun je dit bericht veilig negeren."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Reloading network plug-in..."
|
||||
|
||||
@@ -1790,6 +1819,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Resources path does not exist or is not a directory: %s"
|
||||
@@ -6035,8 +6072,8 @@ msgstr "Bewaar project als"
|
||||
msgid "Save current project as"
|
||||
msgstr "Bewaar huidig project als"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/AMF importeren"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF importeren"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Laad een model"
|
||||
@@ -8953,6 +8990,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12631,6 +12678,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Skirt en brim worden gegenereerd"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "G-code exporteren"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer 2.3.0-rc\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: \n"
|
||||
"Last-Translator: Krzysztof Morga <<tlumaczeniebs@gmail.com>>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1775,6 +1775,35 @@ msgstr "OrcaSlicer napotkał nieobsługiwany wyjątek: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Bez tytułu"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Od wersji 2.4.0 OrcaSlicer synchronizuje profile użytkownika za "
|
||||
"pośrednictwem Orca Cloud zamiast Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Aby przenieść istniejące profile, zaloguj się do Orca Cloud, a zostaną one "
|
||||
"przeniesione automatycznie. Aby dowiedzieć się więcej o tym, jak OrcaSlicer "
|
||||
"przechowuje i synchronizuje Twoje profile, lub aby ręcznie przenieść swoje "
|
||||
"profile, zajrzyj do naszej wiki.\n"
|
||||
"\n"
|
||||
"Jeśli nie korzystano z Bambu Cloud do synchronizacji profili, ta zmiana Cię "
|
||||
"nie dotyczy i możesz zignorować tę wiadomość."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1806,6 +1835,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr ""
|
||||
@@ -6006,8 +6043,8 @@ msgstr "Zapisz projekt jako"
|
||||
msgid "Save current project as"
|
||||
msgstr "Zapisz bieżący projekt jako"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importuj 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importuj 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Wczytaj model"
|
||||
@@ -8888,6 +8925,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12504,6 +12551,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Generowanie skirtu i brimu"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Eksportowanie G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2026-06-17 10:29-0300\n"
|
||||
"Last-Translator: Alexandre Folle de Menezes\n"
|
||||
"Language-Team: Portuguese, Brazilian\n"
|
||||
@@ -1782,6 +1782,35 @@ msgstr "OrcaSlicer encontrou uma exceção não tratada: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Sem título"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Desde a versão 2.4.0, o OrcaSlicer sincroniza os perfis de usuário através "
|
||||
"do Orca Cloud em vez do Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Para migrar seus perfis existentes, faça login no Orca Cloud e eles serão "
|
||||
"transferidos automaticamente. Para saber mais sobre como o OrcaSlicer "
|
||||
"armazena e sincroniza seus perfis, ou para migrar suas predefinições "
|
||||
"manualmente, consulte nossa wiki.\n"
|
||||
"\n"
|
||||
"Se você não usava o Bambu Cloud para sincronizar perfis, esta mudança não "
|
||||
"afeta você e você pode ignorar esta mensagem com segurança."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr "Saber mais"
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Recarregando o plug-in de rede…"
|
||||
|
||||
@@ -1813,6 +1842,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "Tempo de execução WebView2"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "O caminho dos recursos não existe ou não é um diretório: %s"
|
||||
@@ -6106,8 +6143,8 @@ msgstr "Salvar projeto como"
|
||||
msgid "Save current project as"
|
||||
msgstr "Salvar o projeto atual como"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importar 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importar 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Carregar um modelo"
|
||||
@@ -9053,6 +9090,16 @@ msgstr "Sombras"
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr "Renderiza sombras na placa em uma visualização realista."
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "Antisserrilhamento"
|
||||
|
||||
@@ -12031,8 +12078,7 @@ msgstr "Pular esta versão"
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"New version available: %s. Please update OrcaSlicer from the Microsoft Store."
|
||||
msgstr ""
|
||||
"Nova versão disponível: %s. Atualize o OrcaSlicer da Microsoft Store."
|
||||
msgstr "Nova versão disponível: %s. Atualize o OrcaSlicer da Microsoft Store."
|
||||
|
||||
msgid "Confirm and Update Nozzle"
|
||||
msgstr "Confirmar e Atualizar Bico"
|
||||
@@ -12828,6 +12874,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Gerando saia e borda"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exportando G-code"
|
||||
|
||||
@@ -23431,8 +23485,8 @@ msgstr "Não foi possível conectar via serial à Flashforge"
|
||||
|
||||
msgid "Flashforge local API requires both serial number and access code."
|
||||
msgstr ""
|
||||
"A API local Flashforge exige o número de série da impressora e o código "
|
||||
"de acesso."
|
||||
"A API local Flashforge exige o número de série da impressora e o código de "
|
||||
"acesso."
|
||||
|
||||
msgid "Printer returned an error"
|
||||
msgstr "A impressora retornou um erro"
|
||||
@@ -25109,9 +25163,6 @@ msgstr ""
|
||||
#~ msgid "Wiki Guide: Input Shaping Calibration"
|
||||
#~ msgstr "Wiki Guide: Calibração da Modelagem de Entrada"
|
||||
|
||||
#~ msgid "Learn more"
|
||||
#~ msgstr "Saber mais"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Tips: You can drag the filaments to reassign them to different nozzles."
|
||||
#~ msgstr ""
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: OrcaSlicer V2.3.2 beta2\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\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), "
|
||||
@@ -1819,6 +1819,36 @@ msgstr "Неизвестная ошибка OrcaSlicer : %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Без названия"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Начиная с версии 2.4.0, OrcaSlicer синхронизирует пользовательские профили "
|
||||
"через Orca Cloud вместо Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Чтобы перенести существующие профили, войдите в Orca Cloud, и они будут "
|
||||
"перенесены автоматически. Чтобы узнать больше о том, как OrcaSlicer хранит и "
|
||||
"синхронизирует ваши профили, или перенести профили вручную, посетите нашу "
|
||||
"вики.\n"
|
||||
"\n"
|
||||
"Если вы не использовали Bambu Cloud для синхронизации профилей, это "
|
||||
"изменение вас не затрагивает, и вы можете спокойно проигнорировать это "
|
||||
"сообщение."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Перезагрузка сетевого плагина..."
|
||||
|
||||
@@ -1850,6 +1880,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Путь не существует или не является каталогом: %s"
|
||||
@@ -6227,8 +6265,8 @@ msgstr "Сохранить проект как"
|
||||
msgid "Save current project as"
|
||||
msgstr "Сохранить текущий проект как"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Импорт 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Импорт 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Загрузка модели"
|
||||
@@ -9193,6 +9231,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12917,6 +12965,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Генерация юбки и каймы"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Экспорт в G-код"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"Language: sv\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
@@ -1747,6 +1747,35 @@ msgstr "OrcaSlicer got an unhandled exception: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Ej namngiven"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Från och med version 2.4.0 synkroniserar OrcaSlicer användarprofiler via "
|
||||
"Orca Cloud i stället för Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Logga in på Orca Cloud för att migrera dina befintliga profiler, så överförs "
|
||||
"de automatiskt. Läs mer om hur OrcaSlicer lagrar och synkroniserar dina "
|
||||
"profiler, eller om hur du migrerar dina förinställningar manuellt, i vår "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"Om du inte använde Bambu Cloud för att synkronisera profiler påverkar den "
|
||||
"här ändringen dig inte och du kan ignorera det här meddelandet."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Reloading network plug-in..."
|
||||
|
||||
@@ -1778,6 +1807,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Resources path does not exist or is not a directory: %s"
|
||||
@@ -6004,8 +6041,8 @@ msgstr "Spara Projekt som"
|
||||
msgid "Save current project as"
|
||||
msgstr "Spara nuvarande projekt som"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Importera 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Importera 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Ladda modell"
|
||||
@@ -8877,6 +8914,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12501,6 +12548,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Skapar Skirt & Brim"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Exporterar G-kod"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2026-06-04 12:39+0700\n"
|
||||
"Last-Translator: Icezaza\n"
|
||||
"Language-Team: Thai\n"
|
||||
@@ -1743,6 +1743,34 @@ msgstr "OrcaSlicer พบข้อยกเว้นที่ไม่ได้
|
||||
msgid "Untitled"
|
||||
msgstr "ไม่มีชื่อ"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"ตั้งแต่เวอร์ชัน 2.4.0 เป็นต้นไป OrcaSlicer จะซิงค์โปรไฟล์ผู้ใช้ผ่าน Orca Cloud แทน Bambu "
|
||||
"Cloud\n"
|
||||
"\n"
|
||||
"หากต้องการย้ายโปรไฟล์ที่มีอยู่ของคุณ ให้เข้าสู่ระบบ Orca Cloud แล้วระบบจะถ่ายโอนให้โดยอัตโนมัติ "
|
||||
"หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับวิธีที่ OrcaSlicer จัดเก็บและซิงค์โปรไฟล์ของคุณ "
|
||||
"หรือต้องการย้ายพรีเซ็ตด้วยตนเอง โปรดดูที่วิกิของเรา\n"
|
||||
"\n"
|
||||
"หากคุณไม่ได้ใช้ Bambu Cloud ในการซิงค์โปรไฟล์ การเปลี่ยนแปลงนี้จะไม่ส่งผลต่อคุณ "
|
||||
"และคุณสามารถเพิกเฉยต่อข้อความนี้ได้"
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "กำลังโหลดปลั๊กอินเครือข่ายใหม่..."
|
||||
|
||||
@@ -1773,6 +1801,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "รันไทม์ WebView2"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "ไม่มีเส้นทางทรัพยากรหรือไม่ใช่ไดเรกทอรี: %s"
|
||||
@@ -8676,6 +8712,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "ต่อต้านนามแฝง"
|
||||
|
||||
@@ -12185,6 +12231,14 @@ msgstr "การหดตัวของเส้นพลาสติกจะ
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "กำลังสร้าง เส้นล้อมชิ้นงาน และ ขอบยึดชิ้นงาน"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "กำลังส่งออก G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2026-04-08 23:59+0300\n"
|
||||
"Last-Translator: GlauTech\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1768,6 +1768,35 @@ msgstr "OrcaSlicer'da işlenmeyen bir istisna oluştu: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "İsimsiz"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"OrcaSlicer, 2.4.0 sürümünden itibaren kullanıcı profillerini Bambu Cloud "
|
||||
"yerine Orca Cloud üzerinden senkronize eder.\n"
|
||||
"\n"
|
||||
"Mevcut profillerinizi taşımak için Orca Cloud'da oturum açın; profilleriniz "
|
||||
"otomatik olarak aktarılacaktır. OrcaSlicer'ın profillerinizi nasıl depolayıp "
|
||||
"senkronize ettiği hakkında daha fazla bilgi edinmek veya ön ayarlarınızı "
|
||||
"elle taşımak için wiki'mize göz atın.\n"
|
||||
"\n"
|
||||
"Profilleri senkronize etmek için Bambu Cloud kullanmadıysanız bu değişiklik "
|
||||
"sizi etkilemez ve bu mesajı güvenle yoksayabilirsiniz."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Ağ eklentisi yeniden yükleniyor..."
|
||||
|
||||
@@ -1799,6 +1828,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Çalışma Zamanı"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Kaynak yolu mevcut değil veya bir dizin değil: %s"
|
||||
@@ -6025,8 +6062,8 @@ msgstr "Projeyi farklı kaydet"
|
||||
msgid "Save current project as"
|
||||
msgstr "Mevcut projeyi farklı kaydet"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/AMF'yi içe aktar"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF'yi içe aktar"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Model yükle"
|
||||
@@ -8917,6 +8954,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12576,6 +12623,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Etek ve kenar oluşturma"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "G kodu dışa aktarılıyor"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: orcaslicerua\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-03-07 09:30+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: Ukrainian\n"
|
||||
@@ -1773,6 +1773,35 @@ msgstr "Невідома помилка OrcaSlicer : %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Без назви"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Починаючи з версії 2.4.0, OrcaSlicer синхронізує профілі користувача через "
|
||||
"Orca Cloud замість Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Щоб перенести наявні профілі, увійдіть до Orca Cloud, і вони будуть "
|
||||
"перенесені автоматично. Щоб дізнатися більше про те, як OrcaSlicer зберігає "
|
||||
"та синхронізує ваші профілі, або щоб перенести свої шаблони вручну, "
|
||||
"перегляньте нашу вікі.\n"
|
||||
"\n"
|
||||
"Якщо ви не використовували Bambu Cloud для синхронізації профілів, ця зміна "
|
||||
"вас не стосується, і ви можете сміливо проігнорувати це повідомлення."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr ""
|
||||
|
||||
@@ -1803,6 +1832,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "Виконання WebView2"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr ""
|
||||
@@ -5913,8 +5950,8 @@ msgstr "Зберегти проєкт як"
|
||||
msgid "Save current project as"
|
||||
msgstr "Зберегти поточний проєкт як"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Імпорт 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Імпорт 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Завантажте модель"
|
||||
@@ -8754,6 +8791,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12256,6 +12303,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Генерація спідниці та кайми"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Експорт G-code"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-10-02 17:43+0700\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: hainguyen.ts13@gmail.com\n"
|
||||
@@ -1746,6 +1746,35 @@ msgstr "OrcaSlicer gặp ngoại lệ không xử lý được: %1%"
|
||||
msgid "Untitled"
|
||||
msgstr "Không tiêu đề"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"Kể từ phiên bản 2.4.0, OrcaSlicer đồng bộ hồ sơ người dùng thông qua Orca "
|
||||
"Cloud thay vì Bambu Cloud.\n"
|
||||
"\n"
|
||||
"Để di chuyển các hồ sơ hiện có của bạn, hãy đăng nhập vào Orca Cloud và "
|
||||
"chúng sẽ được chuyển tự động. Để tìm hiểu thêm về cách OrcaSlicer lưu trữ và "
|
||||
"đồng bộ hồ sơ của bạn, hoặc để di chuyển các cài đặt sẵn theo cách thủ công, "
|
||||
"hãy xem wiki của chúng tôi.\n"
|
||||
"\n"
|
||||
"Nếu bạn không sử dụng Bambu Cloud để đồng bộ hồ sơ, thay đổi này không ảnh "
|
||||
"hưởng đến bạn và bạn có thể bỏ qua thông báo này."
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr ""
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr ""
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "Reloading network plug-in..."
|
||||
|
||||
@@ -1777,6 +1806,14 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "Đường dẫn tài nguyên không tồn tại hoặc không phải thư mục: %s"
|
||||
@@ -5966,8 +6003,8 @@ msgstr "Lưu dự án thành"
|
||||
msgid "Save current project as"
|
||||
msgstr "Lưu dự án hiện tại thành"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "Nhập 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "Nhập 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "Tải model"
|
||||
@@ -8824,6 +8861,16 @@ msgstr ""
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr ""
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr ""
|
||||
|
||||
@@ -12406,6 +12453,14 @@ msgstr ""
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "Đang tạo viền & brim"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "Đang xuất G-code"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Slic3rPE\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2026-06-11 12:37-0300\n"
|
||||
"Last-Translator: Handle <mail@bysb.net>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1599,7 +1599,10 @@ msgid ""
|
||||
"It is recommended to assemble objects first,\n"
|
||||
"because they are restricted to the bed \n"
|
||||
"and only parts can be lifted."
|
||||
msgstr "建议先组合对象,\n因为对象被固定在打印床上,\n只有零件可以被抬起。"
|
||||
msgstr ""
|
||||
"建议先组合对象,\n"
|
||||
"因为对象被固定在打印床上,\n"
|
||||
"只有零件可以被抬起。"
|
||||
|
||||
msgid "Face and face assembly"
|
||||
msgstr "面对面装配"
|
||||
@@ -1727,6 +1730,34 @@ msgstr "OrcaSlicer 捕捉到一个未处理的异常:%1%"
|
||||
msgid "Untitled"
|
||||
msgstr "未命名"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"自 2.4.0 版本起,OrcaSlicer 通过 Orca Cloud(而非 Bambu Cloud)同步用户配置文"
|
||||
"件。\n"
|
||||
"\n"
|
||||
"要迁移您现有的配置文件,请登录 Orca Cloud,配置文件将被自动转移。若要进一步了"
|
||||
"解 OrcaSlicer 如何存储和同步您的配置文件,或手动迁移您的预设,请查看我们的 "
|
||||
"Wiki。\n"
|
||||
"\n"
|
||||
"如果您此前未使用 Bambu Cloud 同步配置文件,则此变更不会影响您,您可以放心忽略"
|
||||
"此消息。"
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr "配置文件同步方式变更"
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr "了解更多"
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "正在重新加载网络插件..."
|
||||
|
||||
@@ -1757,6 +1788,18 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 运行库"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
"无法安装 Microsoft WebView2 运行库。\n"
|
||||
"在安装之前,包括设置向导在内的部分功能可能显示为空白。\n"
|
||||
"请从 https://developer.microsoft.com/microsoft-edge/webview2/ 手动安装,然后"
|
||||
"重启 Orca Slicer。"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "资源路径不存在或不是目录:%s"
|
||||
@@ -1886,14 +1929,18 @@ msgid ""
|
||||
"the cloud.\n"
|
||||
"Delete will delete your local preset. Force push overwrites it with your "
|
||||
"local preset."
|
||||
msgstr "云同步冲突:之前已从云端删除了同名预设。\n“删除”将删除您的本地预设。“强制推送”将用您的本地预设覆盖它。"
|
||||
msgstr ""
|
||||
"云同步冲突:之前已从云端删除了同名预设。\n"
|
||||
"“删除”将删除您的本地预设。“强制推送”将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"Cloud sync conflict: there was an unexpected or unidentified preset "
|
||||
"conflict.\n"
|
||||
"Pull downloads the cloud copy. Force push overwrites it with your local "
|
||||
"preset."
|
||||
msgstr "云同步冲突:发生了意外或无法识别的预设冲突。\n“拉取”将下载云端副本。“强制推送”将用您的本地预设覆盖它。"
|
||||
msgstr ""
|
||||
"云同步冲突:发生了意外或无法识别的预设冲突。\n"
|
||||
"“拉取”将下载云端副本。“强制推送”将用您的本地预设覆盖它。"
|
||||
|
||||
msgid ""
|
||||
"Force push will overwrite the cloud copy with your local preset changes.\n"
|
||||
@@ -5801,8 +5848,8 @@ msgstr "项目另存为"
|
||||
msgid "Save current project as"
|
||||
msgstr "项目另存为"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "导入 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "导入 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "加载模型"
|
||||
@@ -8519,6 +8566,19 @@ msgstr "阴影"
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr "在写实渲染中渲染投射到打印板上的阴影。"
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr "平滑法线"
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
"在写实渲染中应用平滑法线。\n"
|
||||
"\n"
|
||||
"需要手动重新加载场景才能生效(在 3D 视图中右键单击 →“重新加载全部”)。"
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "抗锯齿"
|
||||
|
||||
@@ -11958,6 +12018,18 @@ msgstr "不会使用耗材收缩率,因为所用耗材的耗材收缩率不匹
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "正在生成裙边和brim"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
"在“逐件”打印顺序下,物体之间无法容纳逐物体裙边。\n"
|
||||
"\n"
|
||||
"请增大物体之间的距离、减小 brim/裙边尺寸、将裙边类型切换为“组合”,或将打印顺"
|
||||
"序切换为“逐层”。"
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "正在导出G-code"
|
||||
|
||||
@@ -12094,7 +12166,9 @@ msgid ""
|
||||
"Enable this if the printer accepts a 3MF file as the print job. When "
|
||||
"enabled, Orca Slicer sends the sliced file as a .gcode.3mf, instead of a "
|
||||
"plain .gcode file."
|
||||
msgstr "如果打印机接受 3MF 文件作为打印任务,请启用此选项。启用后,Orca Slicer 将以 .gcode.3mf 格式发送切片文件,而不是普通的 .gcode 文件。"
|
||||
msgstr ""
|
||||
"如果打印机接受 3MF 文件作为打印任务,请启用此选项。启用后,Orca Slicer 将"
|
||||
"以 .gcode.3mf 格式发送切片文件,而不是普通的 .gcode 文件。"
|
||||
|
||||
msgid "Printer Agent"
|
||||
msgstr "打印机代理"
|
||||
@@ -14363,7 +14437,6 @@ msgstr "如果填充图案支持,使用多线进行填充。"
|
||||
msgid "Z-buckling bias optimization (experimental)"
|
||||
msgstr "Z 轴屈曲偏置优化(实验性)"
|
||||
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
"Tightens the gyroid wave along the Z (vertical) axis at low infill density "
|
||||
"to shorten the effective vertical column length and improve Z-axis "
|
||||
@@ -21519,7 +21592,9 @@ msgstr "上传失败"
|
||||
msgid ""
|
||||
"The file has been transferred, but some unknown errors occurred. Please "
|
||||
"check the device page for the file and try to start printing again."
|
||||
msgstr "文件已传输,但发生了一些未知错误。请在设备页面查看该文件,然后重新尝试开始打印。"
|
||||
msgstr ""
|
||||
"文件已传输,但发生了一些未知错误。请在设备页面查看该文件,然后重新尝试开始打"
|
||||
"印。"
|
||||
|
||||
msgid "Failed to open file for upload."
|
||||
msgstr "无法打开要上传的文件。"
|
||||
@@ -21571,7 +21646,8 @@ msgstr "无法连接到 CrealityPrint。"
|
||||
msgid ""
|
||||
"Connection timed out. Please check if the printer and computer network are "
|
||||
"functioning properly, and confirm that they are on the same network."
|
||||
msgstr "连接超时。请检查打印机和计算机网络是否正常工作,并确认它们处于同一网络中。"
|
||||
msgstr ""
|
||||
"连接超时。请检查打印机和计算机网络是否正常工作,并确认它们处于同一网络中。"
|
||||
|
||||
msgid "The Hostname/IP/URL could not be parsed, please check it and try again."
|
||||
msgstr "无法解析主机名/IP/URL,请检查后重试。"
|
||||
@@ -21849,12 +21925,15 @@ msgstr "执行桌面集成失败,因为未找到应用程序目录。"
|
||||
msgid ""
|
||||
"Performing desktop integration failed - could not create Gcodeviewer desktop "
|
||||
"file. OrcaSlicer desktop file was probably created successfully."
|
||||
msgstr "执行桌面集成失败 - 无法创建 Gcodeviewer 桌面文件。OrcaSlicer 桌面文件可能已成功创建。"
|
||||
msgstr ""
|
||||
"执行桌面集成失败 - 无法创建 Gcodeviewer 桌面文件。OrcaSlicer 桌面文件可能已成"
|
||||
"功创建。"
|
||||
|
||||
msgid ""
|
||||
"Performing downloader desktop integration failed - "
|
||||
"boost::filesystem::canonical did not return appimage path."
|
||||
msgstr "执行下载器桌面集成失败 - boost::filesystem::canonical 未返回 AppImage 路径。"
|
||||
msgstr ""
|
||||
"执行下载器桌面集成失败 - boost::filesystem::canonical 未返回 AppImage 路径。"
|
||||
|
||||
msgid ""
|
||||
"Performing downloader desktop integration failed - Could not find executable."
|
||||
@@ -21872,7 +21951,10 @@ msgid ""
|
||||
"Desktop Integration sets this binary to be searchable by the system.\n"
|
||||
"\n"
|
||||
"Press \"Perform\" to proceed."
|
||||
msgstr "桌面集成会将此二进制文件设置为可被系统搜索到。\n\n按“执行”以继续。"
|
||||
msgstr ""
|
||||
"桌面集成会将此二进制文件设置为可被系统搜索到。\n"
|
||||
"\n"
|
||||
"按“执行”以继续。"
|
||||
|
||||
msgid "The download has failed"
|
||||
msgstr "下载失败"
|
||||
@@ -22264,665 +22346,3 @@ msgid ""
|
||||
msgstr ""
|
||||
"避免翘曲\n"
|
||||
"您知道吗?打印ABS这类易翘曲材料时,适当提高热床温度可以降低翘曲的概率。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "It is recommended to assemble objects first,\n"
|
||||
#~ "because the objects is restriced to bed \n"
|
||||
#~ "and only parts can be lifted."
|
||||
#~ msgstr ""
|
||||
#~ "建议先装配物体,\n"
|
||||
#~ "因为物体被限制在打印平台上,\n"
|
||||
#~ "只有零件可以被抬起。"
|
||||
|
||||
#~ msgid "part selection"
|
||||
#~ msgstr "零件选择"
|
||||
|
||||
#~ msgid "°"
|
||||
#~ msgstr "°"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Controls the density (spacing) of external bridge lines. Default is "
|
||||
#~ "100%.\n"
|
||||
#~ "Theoretically, 100% means a solid bridge, but due to the tendency of "
|
||||
#~ "bridge extrusions to sag, 100% may not be sufficient.\n"
|
||||
#~ "\n"
|
||||
#~ "- Higher than 100% density (Recommended Max 125%):\n"
|
||||
#~ " - Pros: Produces smoother bridge surfaces, as overlapping lines provide "
|
||||
#~ "additional support during printing.\n"
|
||||
#~ " - Cons: Can cause overextrusion, which may reduce lower and upper "
|
||||
#~ "surface quality and increase the risk of warping.\n"
|
||||
#~ "\n"
|
||||
#~ "- Lower than 100% density (Min 10%):\n"
|
||||
#~ " - Pros: Can create a string-like first layer. Faster and with better "
|
||||
#~ "cooling because there is more space for air to circulate around the "
|
||||
#~ "extruded bridge.\n"
|
||||
#~ " - Cons: May lead to sagging and poorer surface finish.\n"
|
||||
#~ "\n"
|
||||
#~ "Recommended range: Minimum 10% - Maximum 125%."
|
||||
#~ msgstr ""
|
||||
#~ "控制外部桥接线的密度(间距)。默认值为 100%。\n"
|
||||
#~ "理论上 100% 意味着实心桥接,但由于桥接挤出物容易下垂,100% 可能并不足"
|
||||
#~ "够。\n"
|
||||
#~ "\n"
|
||||
#~ "- 高于 100% 的密度(推荐最大 125%):\n"
|
||||
#~ " - 优点:产生更平滑的桥接表面,因为重叠的线在打印过程中提供额外支撑。\n"
|
||||
#~ " - 缺点:可能导致过度挤出,从而降低上下表面质量并增加翘曲风险。\n"
|
||||
#~ "\n"
|
||||
#~ "- 低于 100% 的密度(最小 10%):\n"
|
||||
#~ " - 优点:可形成类似拉丝的第一层。速度更快、冷却更好,因为挤出桥接周围有更"
|
||||
#~ "多空气流通的空间。\n"
|
||||
#~ " - 缺点:可能导致下垂和较差的表面光洁度。\n"
|
||||
#~ "\n"
|
||||
#~ "推荐范围:最小 10% - 最大 125%。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Controls the density (spacing) of internal bridge lines. Default is 100%. "
|
||||
#~ "100% means a solid internal bridge.\n"
|
||||
#~ "\n"
|
||||
#~ "Internal bridges act as intermediate support between sparse infill and "
|
||||
#~ "top solid infill and can strongly affect top surface quality.\n"
|
||||
#~ "\n"
|
||||
#~ "- Higher than 100% density (Recommended Max 125%):\n"
|
||||
#~ " - Pros: Improves internal bridge strength and support under top layers, "
|
||||
#~ "reducing sagging and improving top-surface finish.\n"
|
||||
#~ " - Cons: Increases material use and print time; excessive density may "
|
||||
#~ "cause overextrusion and internal stresses.\n"
|
||||
#~ "\n"
|
||||
#~ "- Lower than 100% density (Min 10%):\n"
|
||||
#~ " - Pros: Can reduce pillowing and improve cooling (more airflow through "
|
||||
#~ "the bridge), and may speed up printing.\n"
|
||||
#~ " - Cons: May reduce internal support, increasing the risk of sagging and "
|
||||
#~ "top surface defects.\n"
|
||||
#~ "\n"
|
||||
#~ "This option works particularly well when combined with the second "
|
||||
#~ "internal bridge over infill option to improve bridging further before "
|
||||
#~ "solid infill is extruded."
|
||||
#~ msgstr ""
|
||||
#~ "控制内部桥接线的密度(间距)。默认值为 100%。100% 表示实心内部桥接。\n"
|
||||
#~ "\n"
|
||||
#~ "内部桥接作为稀疏填充与顶部实心填充之间的过渡支撑,会强烈影响顶面质量。\n"
|
||||
#~ "\n"
|
||||
#~ "- 高于 100% 的密度(推荐最大 125%):\n"
|
||||
#~ " - 优点:提升内部桥接强度以及对顶层的支撑,减少下垂并改善顶面光洁度。\n"
|
||||
#~ " - 缺点:增加材料用量和打印时间;密度过高可能导致过度挤出和内部应力。\n"
|
||||
#~ "\n"
|
||||
#~ "- 低于 100% 的密度(最小 10%):\n"
|
||||
#~ " - 优点:可减少表面起鼓并改善冷却(更多气流通过桥接),还可能加快打印速"
|
||||
#~ "度。\n"
|
||||
#~ " - 缺点:可能降低内部支撑,增加下垂和顶面缺陷的风险。\n"
|
||||
#~ "\n"
|
||||
#~ "此选项与“在填充上方增加第二层内部桥接”选项结合使用时效果尤佳,可在挤出实心"
|
||||
#~ "填充之前进一步改善桥接。"
|
||||
|
||||
#, fuzzy, c-format, boost-format
|
||||
#~ msgid ""
|
||||
#~ "Bridge line width is expressed either as an absolute value or as a "
|
||||
#~ "percentage of the active nozzle diameter (percentages are computed from "
|
||||
#~ "the nozzle diameter).\n"
|
||||
#~ "Recommended to use with a higher Bridge density or Bridge flow ratio.\n"
|
||||
#~ "\n"
|
||||
#~ "The maximum value is 100% or the nozzle diameter.\n"
|
||||
#~ "If set to 0, the line width will match the Internal solid infill width."
|
||||
#~ msgstr ""
|
||||
#~ "桥接线宽可以表示为绝对值,或当前喷嘴直径的百分比(百分比根据喷嘴直径计"
|
||||
#~ "算)。\n"
|
||||
#~ "建议与较高的桥接密度或桥接流量比配合使用。\n"
|
||||
#~ "\n"
|
||||
#~ "最大值为 100% 或喷嘴直径。\n"
|
||||
#~ "如果设置为 0,线宽将与内部实心填充宽度一致。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The Wipe option is not available when using the Firmware Retraction "
|
||||
#~ "mode.\n"
|
||||
#~ "\n"
|
||||
#~ "Shall I disable it in order to enable Firmware Retraction?"
|
||||
#~ msgstr ""
|
||||
#~ "使用固件回抽模式时,擦拭选项不可用。\n"
|
||||
#~ "我应该禁用它以启用固件回抽吗?"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"G92 E0\" was found in before_layer_gcode, which is incompatible with "
|
||||
#~ "absolute extruder addressing."
|
||||
#~ msgstr "\"G92E0\" 出现在 before_layer_gcode 中,与绝对挤出机寻址不兼容。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"G92 E0\" was found in layer_gcode, which is incompatible with absolute "
|
||||
#~ "extruder addressing."
|
||||
#~ msgstr "\"G92E0\" 出现在 layer_gcode 中,这与绝对挤出机寻址不兼容。"
|
||||
|
||||
#, no-c-format, no-boost-format
|
||||
#~ msgid ""
|
||||
#~ "Bridging angle override. If left to zero, the bridging angle will be "
|
||||
#~ "calculated automatically. Otherwise the provided angle will be used for "
|
||||
#~ "external bridges. Use 180° for zero angle."
|
||||
#~ msgstr ""
|
||||
#~ "搭桥角度覆盖。如果设置为零,该角度将自动计算。否则外部的桥接将用提供的值。"
|
||||
#~ "180°表示0度。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Internal bridging angle override. If left to zero, the bridging angle "
|
||||
#~ "will be calculated automatically. Otherwise the provided angle will be "
|
||||
#~ "used for internal bridges. Use 180° for zero angle.\n"
|
||||
#~ "\n"
|
||||
#~ "It is recommended to leave it at 0 unless there is a specific model need "
|
||||
#~ "not to."
|
||||
#~ msgstr ""
|
||||
#~ "内部桥接角度覆盖。如果设置为0,则桥接角度将自动计算;否则将采用所提供的角"
|
||||
#~ "度用于内部桥接。使用180°表示0角度。\n"
|
||||
#~ "\n"
|
||||
#~ "建议保持此值为0,除非有特殊模型要求。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Controls the density (spacing) of external bridge lines. Default is "
|
||||
#~ "100%.\n"
|
||||
#~ "\n"
|
||||
#~ "Lower density external bridges can help improve reliability as there is "
|
||||
#~ "more space for air to circulate around the extruded bridge, improving its "
|
||||
#~ "cooling speed. Minimum is 10%.\n"
|
||||
#~ "\n"
|
||||
#~ "Higher densities can produce smoother bridge surfaces, as overlapping "
|
||||
#~ "lines provide additional support during printing. Maximum is 120%.\n"
|
||||
#~ "Note: Bridge density that is too high can cause warping or overextrusion."
|
||||
#~ msgstr ""
|
||||
#~ "控制外部桥线的密度(间距)。默认值为 100%。 较低密度的外部桥有助于提高可靠"
|
||||
#~ "性,因为挤压桥周围有更多的空气流通空间,从而提高其冷却速度。最低为 10%。 "
|
||||
#~ "更高的密度可以产生更平滑的桥接表面,因为重叠的线在打印过程中提供了额外的支"
|
||||
#~ "撑。最大值为 120%。\n"
|
||||
#~ "注意:桥接密度过高可能会导致翘曲或过度挤压。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Controls the density (spacing) of internal bridge lines. 100% means solid "
|
||||
#~ "bridge. Default is 100%.\n"
|
||||
#~ "\n"
|
||||
#~ "Lower density internal bridges can help reduce top surface pillowing and "
|
||||
#~ "improve internal bridge reliability as there is more space for air to "
|
||||
#~ "circulate around the extruded bridge, improving its cooling speed.\n"
|
||||
#~ "\n"
|
||||
#~ "This option works particularly well when combined with the second "
|
||||
#~ "internal bridge over infill option, further improving internal bridging "
|
||||
#~ "structure before solid infill is extruded."
|
||||
#~ msgstr ""
|
||||
#~ "控制内部桥接线的密度(间距)。100% 表示实心桥接,默认值为 100%。\n"
|
||||
#~ "\n"
|
||||
#~ "较低密度的内部桥接有助于减少顶面起鼓现象,并提高内部桥接的可靠性,因为挤出"
|
||||
#~ "桥梁周围有更多空间供空气循环,加快冷却速度。\n"
|
||||
#~ "\n"
|
||||
#~ "此选项与第二层内部桥接覆盖填充功能结合使用时尤为有效,可在挤出实心填充前进"
|
||||
#~ "一步改善内部桥接结构。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Decrease this value slightly (for example 0.9) to reduce the amount of "
|
||||
#~ "material for bridge, to improve sag.\n"
|
||||
#~ "\n"
|
||||
#~ "The actual bridge flow used is calculated by multiplying this value with "
|
||||
#~ "the filament flow ratio, and if set, the object's flow ratio."
|
||||
#~ msgstr ""
|
||||
#~ "稍微减小该值(例如 0.9)以减少桥梁材料的用量,从而改善下垂。 实际使用的桥"
|
||||
#~ "流量是通过将该值乘以耗材流量比以及对象的流量比(如果已设置)来计算的。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This value governs the thickness of the internal bridge layer. This is "
|
||||
#~ "the first layer over sparse infill. Decrease this value slightly (for "
|
||||
#~ "example 0.9) to improve surface quality over sparse infill.\n"
|
||||
#~ "\n"
|
||||
#~ "The actual internal bridge flow used is calculated by multiplying this "
|
||||
#~ "value with the bridge flow ratio, the filament flow ratio, and if set, "
|
||||
#~ "the object's flow ratio."
|
||||
#~ msgstr ""
|
||||
#~ "该值控制内部桥接层的厚度。这是稀疏填充的第一层。稍微减小该值(例如 0.9)可"
|
||||
#~ "改善稀疏填充的表面质量。 实际使用的内部桥流量是通过将该值乘以桥流量比、耗"
|
||||
#~ "材流量比以及对象的流量比(如果已设置)来计算的。"
|
||||
|
||||
#, no-c-format, no-boost-format
|
||||
#~ msgid ""
|
||||
#~ "Enable this option to slow down printing in areas where perimeters may "
|
||||
#~ "have curled upwards. For example, additional slowdown will be applied "
|
||||
#~ "when printing overhangs on sharp corners like the front of the Benchy "
|
||||
#~ "hull, reducing curling which compounds over multiple layers.\n"
|
||||
#~ "\n"
|
||||
#~ "It is generally recommended to have this option switched on unless your "
|
||||
#~ "printer cooling is powerful enough or the print speed slow enough that "
|
||||
#~ "perimeter curling does not happen. If printing with a high external "
|
||||
#~ "perimeter speed, this parameter may introduce slight artifacts when "
|
||||
#~ "slowing down due to the large variance in print speeds. If you notice "
|
||||
#~ "artifacts, ensure your pressure advance is tuned correctly.\n"
|
||||
#~ "\n"
|
||||
#~ "Note: When this option is enabled, overhang perimeters are treated like "
|
||||
#~ "overhangs, meaning the overhang speed is applied even if the overhanging "
|
||||
#~ "perimeter is part of a bridge. For example, when the perimeters are 100% "
|
||||
#~ "overhanging, with no wall supporting them from underneath, the 100% "
|
||||
#~ "overhang speed will be applied."
|
||||
#~ msgstr ""
|
||||
#~ "启用此选项以降低可能向上翘曲的周长区域的打印速度。例如,在打印Benchy船体前"
|
||||
#~ "部等尖锐角落的悬垂时,将应用额外的减速,减少在多层中复合的翘曲。\n"
|
||||
#~ "\n"
|
||||
#~ "通常建议启用此选项,除非您的打印机冷却足够强大或打印速度足够慢,以至于周长"
|
||||
#~ "翘曲不会发生。如果以较高的外部周长速度打印,由于打印速度的巨大差异,此参数"
|
||||
#~ "在减速时可能会引入轻微的伪影。如果您注意到伪影,请确保您的压力提前已正确调"
|
||||
#~ "整。\n"
|
||||
#~ "\n"
|
||||
#~ "注意:启用此选项时,悬垂周长将被视为悬垂,这意味着即使悬垂周长是桥接的一部"
|
||||
#~ "分,也会应用悬垂速度。例如,当周长100%悬垂,没有墙壁从下方支撑时,将应用"
|
||||
#~ "100%悬垂速度。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If enabled, bridges are more reliable, can bridge longer distances, but "
|
||||
#~ "may look worse. If disabled, bridges look better but are reliable just "
|
||||
#~ "for shorter bridged distances."
|
||||
#~ msgstr ""
|
||||
#~ "如果启用,桥接会更可靠,可以桥接更长的距离,但可能看起来更糟。如果关闭,桥"
|
||||
#~ "梁看起来更好,但只适用于较短的桥接距离。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If enabled, thick internal bridges will be used. It's usually recommended "
|
||||
#~ "to have this feature turned on. However, consider turning it off if you "
|
||||
#~ "are using large nozzles."
|
||||
#~ msgstr ""
|
||||
#~ "如果启用,将使用厚内部桥接。通常建议打开此功能。但是,如果您使用大喷嘴,请"
|
||||
#~ "考虑关闭它。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Aligns infill and surface fill directions to follow the model's "
|
||||
#~ "orientation on the build plate. When enabled, fill directions rotate with "
|
||||
#~ "the model to maintain optimal strength characteristics."
|
||||
#~ msgstr ""
|
||||
#~ "使填充和表面填充方向遵循模型在打印板上的方向。启用时,填充方向随模型旋转以"
|
||||
#~ "保持最佳强度特性。"
|
||||
|
||||
#~ msgid "Filament to print internal sparse infill."
|
||||
#~ msgstr "打印内部稀疏填充的耗材丝"
|
||||
|
||||
#~ msgid "Filament to print walls."
|
||||
#~ msgstr "打印外墙的耗材丝"
|
||||
|
||||
#~ msgid "Solid infill"
|
||||
#~ msgstr "实心填充"
|
||||
|
||||
#~ msgid "Filament to print solid infill."
|
||||
#~ msgstr "打印实心填充的耗材丝。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Filament to print support base and raft. \"Default\" means no specific "
|
||||
#~ "filament for support and current filament is used."
|
||||
#~ msgstr ""
|
||||
#~ "打印支撑主体和筏层的耗材丝。\"默认\"代表不指定特定的耗材丝,并使用当前耗材"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Filament to print support interface. \"Default\" means no specific "
|
||||
#~ "filament for support interface and current filament is used."
|
||||
#~ msgstr ""
|
||||
#~ "打印支撑接触面的耗材丝。\"默认\"代表不指定特定的耗材丝,并使用当前耗材"
|
||||
|
||||
#~ msgid "Erase all painting"
|
||||
#~ msgstr "擦除所有绘制"
|
||||
|
||||
#~ msgid "Reset cut"
|
||||
#~ msgstr "重置"
|
||||
|
||||
#~ msgid "Swap pan and rotate mouse buttons"
|
||||
#~ msgstr "交换鼠标按钮的平移与旋转功能"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "If enabled, swaps the left and right mouse buttons pan and rotate "
|
||||
#~ "functions."
|
||||
#~ msgstr "启用后,将左键和右键的平移与旋转功能对调"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "nozzle size in preset: %d"
|
||||
#~ msgstr "预设喷嘴尺寸:%d"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "nozzle size memorized: %d"
|
||||
#~ msgstr "已记住喷嘴尺寸:%d"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The size of nozzle type in preset is not consistent with memorized "
|
||||
#~ "nozzle. Did you change your nozzle lately?"
|
||||
#~ msgstr "预设中的喷嘴类型与已记住的喷嘴尺寸不一致。您最近有更换喷嘴吗?"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "nozzle[%d] in preset: %.1f"
|
||||
#~ msgstr "预设中的 [%d] 喷嘴:%.1f"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "nozzle[%d] memorized: %.1f"
|
||||
#~ msgstr "[%d] 喷嘴已记住:%.1f"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Your nozzle type in preset is not consistent with memorized nozzle. Did "
|
||||
#~ "you change your nozzle lately?"
|
||||
#~ msgstr "您预设中的喷嘴类型与已记住的喷嘴不一致。您最近有更换喷嘴吗?"
|
||||
|
||||
#~ msgid "Remove selected points"
|
||||
#~ msgstr "删除已选择的点"
|
||||
|
||||
#~ msgid "Remove all"
|
||||
#~ msgstr "删除所有点"
|
||||
|
||||
#~ msgid "Auto-generate points"
|
||||
#~ msgstr "自动生成点"
|
||||
|
||||
#~ msgid "Add a brim ear"
|
||||
#~ msgstr "加入一个耳状Brim"
|
||||
|
||||
#~ msgid "Delete a brim ear"
|
||||
#~ msgstr "删除一个耳状Brim"
|
||||
|
||||
#~ msgid "Adjust head diameter"
|
||||
#~ msgstr "调整喷头直径"
|
||||
|
||||
#~ msgid "Adjust section view"
|
||||
#~ msgstr "调整剖面视图"
|
||||
|
||||
#~ msgid " invalid brim ears"
|
||||
#~ msgstr " 个无效耳状Brim"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Reverse on odd\n"
|
||||
#~ "Did you know that <b>Reverse on odd</b> feature can significantly improve "
|
||||
#~ "the surface quality of your overhangs?"
|
||||
#~ msgstr ""
|
||||
#~ "奇数层反转\n"
|
||||
#~ "您知道吗?<b>奇数层反转</b>功能可以显著提高您悬垂的表面质量。"
|
||||
|
||||
#~ msgid "Pen size"
|
||||
#~ msgstr "画笔尺寸"
|
||||
|
||||
#~ msgid "Pen shape"
|
||||
#~ msgstr "画笔形状"
|
||||
|
||||
#~ msgid "Key 1~9"
|
||||
#~ msgstr "按键 1~9"
|
||||
|
||||
#~ msgid "Left click"
|
||||
#~ msgstr "左击"
|
||||
|
||||
#~ msgid "Right click"
|
||||
#~ msgstr "右击"
|
||||
|
||||
#~ msgid "Select feature"
|
||||
#~ msgstr "选择特征"
|
||||
|
||||
#~ msgid "Based on PrusaSlicer and BambuStudio"
|
||||
#~ msgstr "基于PrusaSlicer和BambuStudio"
|
||||
|
||||
#~ msgid "Object/Part Setting"
|
||||
#~ msgstr "对象/零件设置"
|
||||
|
||||
#~ msgid "OrcaSlicer is based on BambuStudio, PrusaSlicer, and SuperSlicer."
|
||||
#~ msgstr "OrcaSlicer 基于 BambuStudio、PrusaSlicer 以及 SuperSlicer 开发。"
|
||||
|
||||
#~ msgid "BambuStudio is originally based on PrusaSlicer by PrusaResearch."
|
||||
#~ msgstr "BambuStudio 基于 PrusaResearch 的 PrusaSlicer 开发而来。"
|
||||
|
||||
#~ msgid "PrusaSlicer is originally based on Slic3r by Alessandro Ranellucci."
|
||||
#~ msgstr "PrusaSlicer 最初是基于 Alessandro Ranellucci 的 Slic3r。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Slic3r was created by Alessandro Ranellucci with the help of many other "
|
||||
#~ "contributors."
|
||||
#~ msgstr "Slic3r 由 Alessandro Ranellucci 在其他众多贡献者的帮助下创建。"
|
||||
|
||||
#~ msgid "Actual Speed: "
|
||||
#~ msgstr "实际速度:"
|
||||
|
||||
#~ msgid "Mouse wheel:"
|
||||
#~ msgstr "鼠标滚轮:"
|
||||
|
||||
#~ msgid "Pass 1"
|
||||
#~ msgstr "粗调"
|
||||
|
||||
#~ msgid "Flow ratio test - Pass 1"
|
||||
#~ msgstr "流量比例测试 - 粗调"
|
||||
|
||||
#~ msgid "Pass 2"
|
||||
#~ msgstr "微调"
|
||||
|
||||
#~ msgid "Flow ratio test - Pass 2"
|
||||
#~ msgstr "流量比例测试 - 微调"
|
||||
|
||||
#~ msgid "Orca YOLO flowratio calibration, 0.01 step"
|
||||
#~ msgstr "Orca YOLO流量比例校准,0.01步长"
|
||||
|
||||
#~ msgid "YOLO (perfectionist version)"
|
||||
#~ msgstr "YOLO(完美主义者版本)"
|
||||
|
||||
#~ msgid "Orca YOLO flowratio calibration, 0.005 step"
|
||||
#~ msgstr "Orca YOLO流量比例校准,0.005步长"
|
||||
|
||||
#~ msgid "Retraction test"
|
||||
#~ msgstr "回抽测试"
|
||||
|
||||
#~ msgid "Tutorial"
|
||||
#~ msgstr "教程"
|
||||
|
||||
#~ msgid "Calibration help"
|
||||
#~ msgstr "校准帮助"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Do you want to synchronize your personal data from Bambu Cloud?\n"
|
||||
#~ "It contains the following information:\n"
|
||||
#~ "1. The Process presets\n"
|
||||
#~ "2. The Filament presets\n"
|
||||
#~ "3. The Printer presets"
|
||||
#~ msgstr ""
|
||||
#~ "想从 Bambu 云同步你的个人数据吗?\n"
|
||||
#~ "包含如下信息:\n"
|
||||
#~ "1. 工艺预设\n"
|
||||
#~ "2. 打印丝预设\n"
|
||||
#~ "3. 打印机预设"
|
||||
|
||||
#~ msgid "Show/Hide advanced parameters"
|
||||
#~ msgstr "显示/隐藏高级参数"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "Left nozzle: %smm"
|
||||
#~ msgstr "左喷嘴:%smm"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "Right nozzle: %smm"
|
||||
#~ msgstr "右喷嘴:%smm"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "\"Fix Model\" feature is currently only on Windows. Please repair the "
|
||||
#~ "model on Orca Slicer(windows) or CAD softwares."
|
||||
#~ msgstr ""
|
||||
#~ "\"修复模型\"功能目前仅适用于Windows。请在逆戟鲸切片器(windows)或CAD软件上"
|
||||
#~ "修复模型。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "This stops the transmission of data to Bambu's cloud services. Users who "
|
||||
#~ "don't use BBL machines or use LAN mode only can safely turn on this "
|
||||
#~ "function."
|
||||
#~ msgstr ""
|
||||
#~ "停止向拓竹科技服务器发送数据。如果您不使用Bambu Lab的打印机或仅使用局域网"
|
||||
#~ "模式,则可以安全地启用此功能。"
|
||||
|
||||
#~ msgid "Resonance Avoidance"
|
||||
#~ msgstr "共振规避"
|
||||
|
||||
#~ msgid "Saving objects into the 3MF failed."
|
||||
#~ msgstr "保存对象到3mf失败。"
|
||||
|
||||
#~ msgid "Only Windows 10 is supported."
|
||||
#~ msgstr "仅支持Windows 10。"
|
||||
|
||||
#~ msgid "Failed to initialize the WinRT library."
|
||||
#~ msgstr "初始化WinRT库失败。"
|
||||
|
||||
#~ msgid "Exporting objects"
|
||||
#~ msgstr "正在导出对象"
|
||||
|
||||
#~ msgid "Failed loading objects."
|
||||
#~ msgstr "加载对象失败。"
|
||||
|
||||
#~ msgid "Repairing object by Windows service"
|
||||
#~ msgstr "通过Windows服务修复对象"
|
||||
|
||||
#~ msgid "Repair failed."
|
||||
#~ msgstr "修复失败。"
|
||||
|
||||
#~ msgid "Loading repaired objects"
|
||||
#~ msgstr "正在加载修复的对象。"
|
||||
|
||||
#~ msgid "Exporting 3MF file failed"
|
||||
#~ msgstr "导出3mf失败"
|
||||
|
||||
#~ msgid "Import 3MF file failed"
|
||||
#~ msgstr "导入3mf失败"
|
||||
|
||||
#~ msgid "Repaired 3MF file does not contain any object"
|
||||
#~ msgstr "已修复的3mf文件不包含任何对象"
|
||||
|
||||
#~ msgid "Repaired 3MF file contains more than one object"
|
||||
#~ msgstr "已修复的3mf文件包含了不止一个对象"
|
||||
|
||||
#~ msgid "Repaired 3MF file does not contain any volume"
|
||||
#~ msgstr "修复的3mf文件不包含任何零件"
|
||||
|
||||
#~ msgid "Repaired 3MF file contains more than one volume"
|
||||
#~ msgstr "已修复的3mf文件包含多个零件"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Printing high-temp and low-temp filaments together may cause nozzle "
|
||||
#~ "clogging or printer damage."
|
||||
#~ msgstr "同时打印高温和低温耗材可能会导致喷嘴堵塞或打印机损坏。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Printing high-temp and low-temp filaments together may cause nozzle "
|
||||
#~ "clogging or printer damage. If you still want to print, you can enable "
|
||||
#~ "the option in Preferences."
|
||||
#~ msgstr ""
|
||||
#~ "同时打印高温和低温耗材可能会导致喷嘴堵塞或打印机损坏。如果您仍想打印,可以"
|
||||
#~ "在“首选项”中启用该选项。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Printing different-temp filaments together may cause nozzle clogging or "
|
||||
#~ "printer damage."
|
||||
#~ msgstr "将不同温度的耗材一起打印可能会导致喷嘴堵塞或打印机损坏。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Printing high-temp and mid-temp filaments together may cause nozzle "
|
||||
#~ "clogging or printer damage."
|
||||
#~ msgstr "同时打印高温和中温耗材可能会导致喷嘴堵塞或打印机损坏。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Printing mid-temp and low-temp filaments together may cause nozzle "
|
||||
#~ "clogging or printer damage."
|
||||
#~ msgstr "同时打印中温和低温耗材可能会导致喷嘴堵塞或打印机损坏。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "The direction which the wall loops are extruded when looking down from "
|
||||
#~ "the top.\n"
|
||||
#~ "\n"
|
||||
#~ "By default all walls are extruded in counter-clockwise, unless Reverse on "
|
||||
#~ "even is enabled. Set this to any option other than Auto will force the "
|
||||
#~ "wall direction regardless of the Reverse on even.\n"
|
||||
#~ "\n"
|
||||
#~ "This option will be disabled if spiral vase mode is enabled."
|
||||
#~ msgstr ""
|
||||
#~ "从上往下看时墙循环挤出的方向。\n"
|
||||
#~ "\n"
|
||||
#~ "默认情况下,所有墙都以逆时针方向挤出,除非启用了偶数层反转。将此设置为自动"
|
||||
#~ "以外的任何选项将强制墙方向,而不管偶数层反转如何。\n"
|
||||
#~ "\n"
|
||||
#~ "如果启用螺旋花瓶模式,此选项将被禁用。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Noise type to use for fuzzy skin generation:\n"
|
||||
#~ "Classic: Classic uniform random noise.\n"
|
||||
#~ "Perlin: Perlin noise, which gives a more consistent texture.\n"
|
||||
#~ "Billow: Similar to perlin noise, but clumpier.\n"
|
||||
#~ "Ridged Multifractal: Ridged noise with sharp, jagged features. Creates "
|
||||
#~ "marble-like textures.\n"
|
||||
#~ "Voronoi: Divides the surface into voronoi cells, and displaces each one "
|
||||
#~ "by a random amount. Creates a patchwork texture."
|
||||
#~ msgstr ""
|
||||
#~ "用于生成绒毛效果的噪波类型。\n"
|
||||
#~ "经典: 经典的均匀随机噪波。\n"
|
||||
#~ "柏林噪波: 能产生更均匀纹理的柏林噪波。\n"
|
||||
#~ "云状噪波: 类似柏林噪波,但更聚集。\n"
|
||||
#~ "脊状多重分形: 具有锋利锯齿特性的脊状噪波,呈现大理石般纹理。\n"
|
||||
#~ "维诺图: 将表面划分为维诺单元,每个单元依随机量位移,形成拼贴纹理。"
|
||||
|
||||
#~ msgid "Flow Rate"
|
||||
#~ msgstr "流量比例"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Cannot print multiple filaments which have large difference of "
|
||||
#~ "temperature together. Otherwise, the extruder and nozzle may be blocked "
|
||||
#~ "or damaged during printing"
|
||||
#~ msgstr ""
|
||||
#~ "无法同时打印多个温差较大的耗材。否则挤出机和喷嘴在打印过程中可能会堵塞或损"
|
||||
#~ "坏"
|
||||
|
||||
#~ msgid "BambuStudio warning"
|
||||
#~ msgstr "BambuStudio 警告"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Zero first layer height is invalid.\n"
|
||||
#~ "\n"
|
||||
#~ "The first layer height will be reset to 0.2."
|
||||
#~ msgstr ""
|
||||
#~ "首层层高为无效的0值。\n"
|
||||
#~ "将被重置为0.2。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Prime tower position exceeded build plate boundaries and was repositioned "
|
||||
#~ "to the nearest valid edge."
|
||||
#~ msgstr "Prime 塔位置超出了打印板边界,并重新定位到最近的有效边缘。"
|
||||
|
||||
#~ msgid "Check for Update"
|
||||
#~ msgstr "检查新版本"
|
||||
|
||||
#~ msgid "Detect spaghetti failure(scattered lose filament)."
|
||||
#~ msgstr "检测炒面故障(散落的耗材丝)。"
|
||||
|
||||
#~ msgid "Rotate of view"
|
||||
#~ msgstr "旋转视图"
|
||||
|
||||
#~ msgid "Move of view"
|
||||
#~ msgstr "移动视图"
|
||||
|
||||
#~ msgid "Zoom of view"
|
||||
#~ msgstr "缩放视图"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Enabling both precise Z height and the prime tower may cause the size of "
|
||||
#~ "prime tower to increase. Do you still want to enable?"
|
||||
#~ msgstr "同时启用精确Z高度和擦拭塔可能会导致擦拭塔尺寸增大。您仍然要启用吗?"
|
||||
|
||||
#~ msgid "Extruders count"
|
||||
#~ msgstr "挤出机数量"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Missing BambuSource component registered for media playing! Please re-"
|
||||
#~ "install BambuStudio or seek after-sales help."
|
||||
#~ msgstr ""
|
||||
#~ "缺少用于媒体播放的已注册 BambuSource 组件!请重新安装 BambuStudio 或寻求售"
|
||||
#~ "后帮助。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "When enabled, the extrusion flow is limited by the smaller of the fitted "
|
||||
#~ "value (calculated from line width and layer height) and the user-defined "
|
||||
#~ "maximum flow. When disabled, only the user-defined maximum flow is "
|
||||
#~ "applied."
|
||||
#~ msgstr ""
|
||||
#~ "启用后,挤出流量受到拟合值(根据线宽和层高计算)和用户定义的最大流量中较小"
|
||||
#~ "者的限制。禁用时,仅应用用户定义的最大流量。"
|
||||
|
||||
#~ msgid "Auto-refill"
|
||||
#~ msgstr "自动补充"
|
||||
|
||||
#~ msgid "Network Plug-in"
|
||||
#~ msgstr "网络插件"
|
||||
|
||||
#~ msgid "Packing data to 3mf"
|
||||
#~ msgstr "将数据打包至 3MF"
|
||||
|
||||
#~ msgid "Cool Plate (Supertack)"
|
||||
#~ msgstr "冷却板(Supertack)"
|
||||
|
||||
#, c-format, boost-format
|
||||
#~ msgid "The selected preset: %s is not found."
|
||||
#~ msgstr "未找到所选预设:%s。"
|
||||
|
||||
@@ -9,7 +9,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Orca Slicer\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2026-06-17 18:00+0800\n"
|
||||
"POT-Creation-Date: 2026-06-26 11:35+0800\n"
|
||||
"PO-Revision-Date: 2025-11-28 13:48-0600\n"
|
||||
"Last-Translator: tntchn <15895303+tntchn@users.noreply.github.com>\n"
|
||||
"Language-Team: \n"
|
||||
@@ -1733,6 +1733,34 @@ msgstr "Orca Slicer 遭遇到一個未處理的例外:%1%"
|
||||
msgid "Untitled"
|
||||
msgstr "未命名"
|
||||
|
||||
msgid ""
|
||||
"Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
"instead of Bambu Cloud.\n"
|
||||
"\n"
|
||||
"To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
"transferred automatically. To learn more about how OrcaSlicer stores and "
|
||||
"syncs your profiles, or to migrate your presets manually, check out our "
|
||||
"wiki.\n"
|
||||
"\n"
|
||||
"If you did not use Bambu Cloud to sync profiles, this change does not affect "
|
||||
"you and you can safely ignore this message."
|
||||
msgstr ""
|
||||
"自 2.4.0 版本起,OrcaSlicer 透過 Orca Cloud(而非 Bambu Cloud)同步使用者設定"
|
||||
"檔。\n"
|
||||
"\n"
|
||||
"若要移轉您現有的設定檔,請登入 Orca Cloud,設定檔將會自動轉移。若要進一步了"
|
||||
"解 OrcaSlicer 如何儲存與同步您的設定檔,或手動移轉您的預設,請參閱我們的 "
|
||||
"wiki。\n"
|
||||
"\n"
|
||||
"若您先前並未使用 Bambu Cloud 同步設定檔,則此變更不會影響您,您可以放心忽略此"
|
||||
"訊息。"
|
||||
|
||||
msgid "Profile syncing change"
|
||||
msgstr "設定檔同步方式變更"
|
||||
|
||||
msgid "Learn more"
|
||||
msgstr "了解更多"
|
||||
|
||||
msgid "Reloading network plug-in..."
|
||||
msgstr "正在重新載入網路外掛程式..."
|
||||
|
||||
@@ -1763,6 +1791,18 @@ msgstr ""
|
||||
msgid "WebView2 Runtime"
|
||||
msgstr "WebView2 Runtime"
|
||||
|
||||
msgid ""
|
||||
"The Microsoft WebView2 Runtime could not be installed.\n"
|
||||
"Some features, including the setup wizard, may appear blank until it is "
|
||||
"installed.\n"
|
||||
"Please install it manually from https://developer.microsoft.com/microsoft-"
|
||||
"edge/webview2/ and restart Orca Slicer."
|
||||
msgstr ""
|
||||
"無法安裝 Microsoft WebView2 Runtime。\n"
|
||||
"在安裝完成前,包括設定精靈在內的部分功能可能顯示為空白。\n"
|
||||
"請從 https://developer.microsoft.com/microsoft-edge/webview2/ 手動安裝,然後"
|
||||
"重新啟動 Orca Slicer。"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "Resources path does not exist or is not a directory: %s"
|
||||
msgstr "資源路徑不存在或並非目錄:%s"
|
||||
@@ -2010,7 +2050,9 @@ msgid ""
|
||||
"The preset content is too large to sync to the cloud (exceeds 1MB). Please "
|
||||
"reduce the preset size by removing custom configurations or use it locally "
|
||||
"only."
|
||||
msgstr "預設內容過大,無法同步至雲端(超過 1MB)。請移除自訂設定以減少預設大小,或僅在本機使用。"
|
||||
msgstr ""
|
||||
"預設內容過大,無法同步至雲端(超過 1MB)。請移除自訂設定以減少預設大小,或僅"
|
||||
"在本機使用。"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid "%s updated from %s to %s"
|
||||
@@ -3559,20 +3601,29 @@ msgid ""
|
||||
"forked from PrusaSlicer, and SuperSlicer extended it with community-driven "
|
||||
"enhancements. Each project carried the work of its predecessors forward, "
|
||||
"crediting those who came before."
|
||||
msgstr "開源切片建立在協作與署名的傳統之上。由 Alessandro Ranellucci 與 RepRap 社群打造的 Slic3r 奠定了基礎。Prusa Research 的 PrusaSlicer 在此基礎上持續發展,Bambu Studio 由 PrusaSlicer 分支而來,SuperSlicer 則以社群驅動的增強功能加以擴充。每個專案都延續了前人的成果,並向先行者致謝。"
|
||||
msgstr ""
|
||||
"開源切片建立在協作與署名的傳統之上。由 Alessandro Ranellucci 與 RepRap 社群打"
|
||||
"造的 Slic3r 奠定了基礎。Prusa Research 的 PrusaSlicer 在此基礎上持續發展,"
|
||||
"Bambu Studio 由 PrusaSlicer 分支而來,SuperSlicer 則以社群驅動的增強功能加以"
|
||||
"擴充。每個專案都延續了前人的成果,並向先行者致謝。"
|
||||
|
||||
msgid ""
|
||||
"OrcaSlicer began in that same spirit, drawing from PrusaSlicer, BambuStudio, "
|
||||
"SuperSlicer, and CuraSlicer. But it has since grown far beyond its origins — "
|
||||
"introducing advanced calibration tools, precise wall and seam control and "
|
||||
"hundreds of other features."
|
||||
msgstr "OrcaSlicer 也源於同樣的精神,汲取了 PrusaSlicer、BambuStudio、SuperSlicer 與 CuraSlicer 的長處。但如今它已遠遠超越最初的根源——引入了先進的校正工具、精確的牆與接縫控制,以及數百項其他功能。"
|
||||
msgstr ""
|
||||
"OrcaSlicer 也源於同樣的精神,汲取了 PrusaSlicer、BambuStudio、SuperSlicer 與 "
|
||||
"CuraSlicer 的長處。但如今它已遠遠超越最初的根源——引入了先進的校正工具、精確的"
|
||||
"牆與接縫控制,以及數百項其他功能。"
|
||||
|
||||
msgid ""
|
||||
"Today, OrcaSlicer is the most widely used and actively developed open-source "
|
||||
"slicer in the 3D printing community. Many of its innovations have been "
|
||||
"adopted by other slicers, making it a driving force for the entire industry."
|
||||
msgstr "如今,OrcaSlicer 是 3D 列印社群中使用最廣泛、開發最活躍的開源切片軟體。它的許多創新已被其他切片軟體採用,使其成為推動整個產業的動力。"
|
||||
msgstr ""
|
||||
"如今,OrcaSlicer 是 3D 列印社群中使用最廣泛、開發最活躍的開源切片軟體。它的許"
|
||||
"多創新已被其他切片軟體採用,使其成為推動整個產業的動力。"
|
||||
|
||||
msgid "Version"
|
||||
msgstr "版本"
|
||||
@@ -5865,8 +5916,8 @@ msgstr "另存專案為"
|
||||
msgid "Save current project as"
|
||||
msgstr "將目前專案另存為"
|
||||
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgstr "匯入 3MF/STL/STEP/SVG/OBJ/AMF"
|
||||
msgid "Import 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
msgstr "匯入 3MF/STL/STEP/SVG/OBJ/GLTF/GLB/AMF"
|
||||
|
||||
msgid "Load a model"
|
||||
msgstr "載入模型"
|
||||
@@ -7610,13 +7661,17 @@ msgstr "該 3MF 檔案版本 %s 比 %s 的版本 %s 新,建議升級您的軟
|
||||
msgid ""
|
||||
"The 3MF was created by BambuStudio (version %s), which is newer than the "
|
||||
"compatible version %s. Found unrecognized settings:"
|
||||
msgstr "此 3MF 由 BambuStudio(版本 %s)建立,其版本比相容版本 %s 更新。發現無法辨識的設定:"
|
||||
msgstr ""
|
||||
"此 3MF 由 BambuStudio(版本 %s)建立,其版本比相容版本 %s 更新。發現無法辨識"
|
||||
"的設定:"
|
||||
|
||||
#, c-format, boost-format
|
||||
msgid ""
|
||||
"The 3MF was created by BambuStudio (version %s), which is newer than the "
|
||||
"compatible version %s. Some settings may not be fully compatible."
|
||||
msgstr "此 3MF 由 BambuStudio(版本 %s)建立,該版本新於相容版本 %s。部分設定可能無法完全相容。"
|
||||
msgstr ""
|
||||
"此 3MF 由 BambuStudio(版本 %s)建立,該版本新於相容版本 %s。部分設定可能無法"
|
||||
"完全相容。"
|
||||
|
||||
msgid ""
|
||||
"The 3MF was created by BambuStudio. Some settings may differ from OrcaSlicer."
|
||||
@@ -7767,8 +7822,7 @@ msgid "The selected object couldn't be split."
|
||||
msgstr "選中的模型不可分割。"
|
||||
|
||||
msgid "Disable Auto-Drop to preserve Z positioning?\n"
|
||||
msgstr ""
|
||||
"停用自動落板以保留 Z 定位?\n"
|
||||
msgstr "停用自動落板以保留 Z 定位?\n"
|
||||
|
||||
msgid "Object with floating parts was detected"
|
||||
msgstr "偵測到含有懸空零件的物件"
|
||||
@@ -8595,6 +8649,20 @@ msgstr "陰影"
|
||||
msgid "Renders cast shadows on the plate in realistic view."
|
||||
msgstr "在擬真檢視中於列印板上算繪投射陰影。"
|
||||
|
||||
msgid "Smooth normals"
|
||||
msgstr "平滑法線"
|
||||
|
||||
msgid ""
|
||||
"Applies smooth normals to the realistic view.\n"
|
||||
"\n"
|
||||
"Requires manual scene reload to take effect (right-click on 3D view → "
|
||||
"\"Reload All\")."
|
||||
msgstr ""
|
||||
"將平滑法線套用至擬真檢視。\n"
|
||||
"\n"
|
||||
"需要手動重新載入場景才能生效(在 3D 檢視中按一下滑鼠右鍵 →「重新載入所有物"
|
||||
"件」)。"
|
||||
|
||||
msgid "Anti-aliasing"
|
||||
msgstr "抗鋸齒"
|
||||
|
||||
@@ -8669,7 +8737,8 @@ msgid ""
|
||||
"Note: When Stealth Mode is enabled, your user profiles will not be backed up "
|
||||
"to Orca Cloud."
|
||||
msgstr ""
|
||||
"這會停用所有雲端功能,包括 Orca Cloud 設定檔同步。偏好完全離線工作的使用者可以啟用此選項。\n"
|
||||
"這會停用所有雲端功能,包括 Orca Cloud 設定檔同步。偏好完全離線工作的使用者可"
|
||||
"以啟用此選項。\n"
|
||||
"注意:啟用隱身模式時,您的使用者設定檔將不會備份到 Orca Cloud。"
|
||||
|
||||
msgid "Hide login side panel"
|
||||
@@ -8693,7 +8762,9 @@ msgstr "啟用 Bambu Cloud"
|
||||
msgid ""
|
||||
"Allow logging into Bambu Cloud alongside Orca Cloud. When enabled, a Bambu "
|
||||
"login section appears on the homepage."
|
||||
msgstr "允許在登入 Orca Cloud 的同時登入 Bambu Cloud。啟用後,首頁會顯示 Bambu 登入區塊。"
|
||||
msgstr ""
|
||||
"允許在登入 Orca Cloud 的同時登入 Bambu Cloud。啟用後,首頁會顯示 Bambu 登入區"
|
||||
"塊。"
|
||||
|
||||
msgid "Update & sync"
|
||||
msgstr "更新與同步"
|
||||
@@ -8824,7 +8895,8 @@ msgid ""
|
||||
"changing the object mesh (such as cut/reload from disk/simplify/fix etc.)\n"
|
||||
"Highly experimental! Slow and may create artifact."
|
||||
msgstr ""
|
||||
"嘗試在變更物件網格(例如切割/從磁碟重新載入/簡化/修復等)後,保留已繪製的特徵(顏色/Z 縫/支撐/絨毛等)。\n"
|
||||
"嘗試在變更物件網格(例如切割/從磁碟重新載入/簡化/修復等)後,保留已繪製的特徵"
|
||||
"(顏色/Z 縫/支撐/絨毛等)。\n"
|
||||
"高度實驗性!速度緩慢且可能產生瑕疵。"
|
||||
|
||||
msgid "Show unsupported presets"
|
||||
@@ -9521,7 +9593,9 @@ msgid ""
|
||||
"The type of external filament is unknown or does not match with the filament "
|
||||
"type in the slicing file. Please make sure you have installed the correct "
|
||||
"filament in the external spool."
|
||||
msgstr "外部線材的類型未知,或與切片檔案中的線材類型不符。請確認您已在外部料盤中安裝正確的線材。"
|
||||
msgstr ""
|
||||
"外部線材的類型未知,或與切片檔案中的線材類型不符。請確認您已在外部料盤中安裝"
|
||||
"正確的線材。"
|
||||
|
||||
msgid "Please refer to Wiki before use->"
|
||||
msgstr "使用前請參考 Wiki ->"
|
||||
@@ -10410,8 +10484,7 @@ msgstr ""
|
||||
|
||||
msgid ""
|
||||
"Some first-layer and other-layer temperature pairs exceed safety limits.\n"
|
||||
msgstr ""
|
||||
"部分首層與其他層的溫度組合超出安全限制。\n"
|
||||
msgstr "部分首層與其他層的溫度組合超出安全限制。\n"
|
||||
|
||||
msgid ""
|
||||
"\n"
|
||||
@@ -11014,12 +11087,16 @@ msgstr "請選擇線材顏色"
|
||||
msgid ""
|
||||
"Native Wayland liveview requires the GStreamer GTK video sink. Please "
|
||||
"install the gtksink plugin for GStreamer, then restart OrcaSlicer."
|
||||
msgstr "原生 Wayland 即時檢視需要 GStreamer GTK 視訊接收器。請為 GStreamer 安裝 gtksink 外掛程式,然後重新啟動 OrcaSlicer。"
|
||||
msgstr ""
|
||||
"原生 Wayland 即時檢視需要 GStreamer GTK 視訊接收器。請為 GStreamer 安裝 "
|
||||
"gtksink 外掛程式,然後重新啟動 OrcaSlicer。"
|
||||
|
||||
msgid ""
|
||||
"Failed to initialize the native Wayland GStreamer video sink. Please check "
|
||||
"your GStreamer GTK plugin installation."
|
||||
msgstr "無法初始化原生 Wayland GStreamer 視訊接收器。請檢查您的 GStreamer GTK 外掛程式安裝。"
|
||||
msgstr ""
|
||||
"無法初始化原生 Wayland GStreamer 視訊接收器。請檢查您的 GStreamer GTK 外掛程"
|
||||
"式安裝。"
|
||||
|
||||
msgid ""
|
||||
"Windows Media Player is required for this task! Do you want to enable "
|
||||
@@ -11738,7 +11815,9 @@ msgid ""
|
||||
"Selected nozzle temperatures are incompatible. Each filament's nozzle "
|
||||
"temperature must fall within the recommended nozzle temperature range of the "
|
||||
"other filaments. Otherwise, nozzle clogging or printer damage may occur."
|
||||
msgstr "所選的噴嘴溫度不相容。每種線材的噴嘴溫度都必須落在其他線材的建議噴嘴溫度範圍內。否則可能會發生噴嘴堵塞或列印設備損壞。"
|
||||
msgstr ""
|
||||
"所選的噴嘴溫度不相容。每種線材的噴嘴溫度都必須落在其他線材的建議噴嘴溫度範圍"
|
||||
"內。否則可能會發生噴嘴堵塞或列印設備損壞。"
|
||||
|
||||
msgid ""
|
||||
"Invalid recommended nozzle temperature range. The lower bound must be lower "
|
||||
@@ -11748,7 +11827,9 @@ msgstr "建議的噴嘴溫度範圍無效。下限必須低於上限。"
|
||||
msgid ""
|
||||
"If you still want to print, you can enable the option in Preferences / "
|
||||
"Control / Slicing / Remove mixed temperature restriction."
|
||||
msgstr "如果您仍想列印,可以在「偏好設定 / 控制 / 切片 / 移除混合溫度限制」中啟用該選項。"
|
||||
msgstr ""
|
||||
"如果您仍想列印,可以在「偏好設定 / 控制 / 切片 / 移除混合溫度限制」中啟用該選"
|
||||
"項。"
|
||||
|
||||
msgid "No extrusions under current settings."
|
||||
msgstr "根據目前設定,不會進行任何列印。"
|
||||
@@ -11937,12 +12018,16 @@ msgstr "橋接線寬不得超過噴嘴直徑"
|
||||
msgid ""
|
||||
"\"G92 E0\" was found in before_layer_change_gcode, but the G or E are not "
|
||||
"uppercase. Please change them to the exact uppercase \"G92 E0\"."
|
||||
msgstr "在 before_layer_change_gcode 中找到 \"G92 E0\",但 G 或 E 不是大寫。請將它們改為完全大寫的 \"G92 E0\"。"
|
||||
msgstr ""
|
||||
"在 before_layer_change_gcode 中找到 \"G92 E0\",但 G 或 E 不是大寫。請將它們"
|
||||
"改為完全大寫的 \"G92 E0\"。"
|
||||
|
||||
msgid ""
|
||||
"\"G92 E0\" was found in layer_change_gcode, but the G or E are not "
|
||||
"uppercase. Please change them to the exact uppercase \"G92 E0\"."
|
||||
msgstr "在 layer_change_gcode 中找到 \"G92 E0\",但 G 或 E 並非大寫。請將其改為完全大寫的 \"G92 E0\"。"
|
||||
msgstr ""
|
||||
"在 layer_change_gcode 中找到 \"G92 E0\",但 G 或 E 並非大寫。請將其改為完全大"
|
||||
"寫的 \"G92 E0\"。"
|
||||
|
||||
msgid ""
|
||||
"Relative extruder addressing requires resetting the extruder position at "
|
||||
@@ -11955,7 +12040,8 @@ msgstr ""
|
||||
msgid ""
|
||||
"\"G92 E0\" was found in before_layer_change_gcode, which is incompatible "
|
||||
"with absolute extruder addressing."
|
||||
msgstr "在 before_layer_change_gcode 中發現 \"G92 E0\",這與絕對擠出機定址不相容。"
|
||||
msgstr ""
|
||||
"在 before_layer_change_gcode 中發現 \"G92 E0\",這與絕對擠出機定址不相容。"
|
||||
|
||||
msgid ""
|
||||
"\"G92 E0\" was found in layer_change_gcode, which is incompatible with "
|
||||
@@ -12035,6 +12121,18 @@ msgstr "線材收縮補償將被停用,因為所使用的線材之間的收縮
|
||||
msgid "Generating skirt & brim"
|
||||
msgstr "正在產生 Skirt 和 Brim"
|
||||
|
||||
msgid ""
|
||||
"Per-object skirts cannot fit between the objects in By object print "
|
||||
"sequence.\n"
|
||||
"\n"
|
||||
"Move the objects farther apart, reduce brim/skirt size, switch Skirt type to "
|
||||
"Combined, or switch Print sequence to By layer."
|
||||
msgstr ""
|
||||
"在「逐件」列印順序下,物件之間無法容納各別物件的 Skirt。\n"
|
||||
"\n"
|
||||
"請加大物件之間的距離、縮小 Brim/Skirt 尺寸、將 Skirt 類型切換為「合併」,或將"
|
||||
"列印順序切換為「逐層」。"
|
||||
|
||||
msgid "Exporting G-code"
|
||||
msgstr "正在匯出 G-code"
|
||||
|
||||
@@ -12076,7 +12174,9 @@ msgid ""
|
||||
"Ordered list of bed exclude areas by parallel printhead count. Item 1 "
|
||||
"applies to one printhead, item 2 to two printheads, and so on. Leave an item "
|
||||
"empty for no excluded area."
|
||||
msgstr "依平行列印頭數量排序的熱床淨空區域列表。第 1 項適用於一個列印頭,第 2 項適用於兩個列印頭,依此類推。將項目留空表示無淨空區域。"
|
||||
msgstr ""
|
||||
"依平行列印頭數量排序的熱床淨空區域列表。第 1 項適用於一個列印頭,第 2 項適用"
|
||||
"於兩個列印頭,依此類推。將項目留空表示無淨空區域。"
|
||||
|
||||
msgid "Bed exclude area"
|
||||
msgstr "熱床淨空區域"
|
||||
@@ -12169,7 +12269,9 @@ msgid ""
|
||||
"Enable this if the printer accepts a 3MF file as the print job. When "
|
||||
"enabled, Orca Slicer sends the sliced file as a .gcode.3mf, instead of a "
|
||||
"plain .gcode file."
|
||||
msgstr "若列印設備接受 3MF 檔案作為列印作業,請啟用此選項。啟用後,Orca Slicer 會將切片後的檔案以 .gcode.3mf 形式傳送,而非單純的 .gcode 檔案。"
|
||||
msgstr ""
|
||||
"若列印設備接受 3MF 檔案作為列印作業,請啟用此選項。啟用後,Orca Slicer 會將切"
|
||||
"片後的檔案以 .gcode.3mf 形式傳送,而非單純的 .gcode 檔案。"
|
||||
|
||||
msgid "Printer Agent"
|
||||
msgstr "列印設備代理"
|
||||
@@ -12591,7 +12693,8 @@ msgstr ""
|
||||
" - 缺點:可能造成過度擠出,進而降低上下表面的品質並增加翹曲風險。\n"
|
||||
"\n"
|
||||
"- 低於 100% 的密度(最小 10%):\n"
|
||||
" - 優點:能產生線狀的首層。速度更快且冷卻效果更好,因為擠出的橋接周圍有更多空間讓空氣流通。\n"
|
||||
" - 優點:能產生線狀的首層。速度更快且冷卻效果更好,因為擠出的橋接周圍有更多"
|
||||
"空間讓空氣流通。\n"
|
||||
" - 缺點:可能導致下垂及較差的表面光潔度。"
|
||||
|
||||
msgid "Internal bridge density"
|
||||
@@ -12626,10 +12729,12 @@ msgstr ""
|
||||
" - 缺點:增加材料用量與列印時間;密度過高可能導致過度擠出與內部應力。\n"
|
||||
"\n"
|
||||
"- 密度低於 100%(最小 10%):\n"
|
||||
" - 優點:可減少表面凸起並改善冷卻(更多氣流通過橋接),還可能加快列印速度。\n"
|
||||
" - 優點:可減少表面凸起並改善冷卻(更多氣流通過橋接),還可能加快列印速"
|
||||
"度。\n"
|
||||
" - 缺點:可能降低內部支撐,增加下垂與頂面缺陷的風險。\n"
|
||||
"\n"
|
||||
"此選項與「在填充上方增加第二層內部橋接」選項搭配使用時效果尤佳,可在擠出實心填充前進一步改善橋接。"
|
||||
"此選項與「在填充上方增加第二層內部橋接」選項搭配使用時效果尤佳,可在擠出實心"
|
||||
"填充前進一步改善橋接。"
|
||||
|
||||
msgid "Bridge flow ratio"
|
||||
msgstr "橋接流量"
|
||||
@@ -12648,7 +12753,8 @@ msgstr ""
|
||||
"大於 1.0 的值:在維持線距的同時增加材料量。這可以改善線條接觸與強度。\n"
|
||||
"小於 1.0 的值:減少材料量並調整線距以維持接觸。這可以改善下垂。\n"
|
||||
"\n"
|
||||
"實際使用的橋接流量是將此數值乘以線材流量比例計算得出,若有設定,還會乘以物件的流量比例。"
|
||||
"實際使用的橋接流量是將此數值乘以線材流量比例計算得出,若有設定,還會乘以物件"
|
||||
"的流量比例。"
|
||||
|
||||
msgid ""
|
||||
"Line width of the Bridge. If expressed as a %, it will be computed over the "
|
||||
@@ -12679,11 +12785,13 @@ msgid ""
|
||||
"The actual bridge flow used is calculated by multiplying this value with the "
|
||||
"filament flow ratio, and if set, the object's flow ratio."
|
||||
msgstr ""
|
||||
"此數值控制內部橋接層的厚度。這是稀疏填充上方的第一層,因此增加它可能會提升強度與上層品質。\n"
|
||||
"此數值控制內部橋接層的厚度。這是稀疏填充上方的第一層,因此增加它可能會提升強"
|
||||
"度與上層品質。\n"
|
||||
"大於 1.0 的數值:在維持線距的同時增加材料用量。這可以改善線條接觸與強度。\n"
|
||||
"小於 1.0 的數值:減少材料用量並調整線距以維持接觸。這可以改善下垂。\n"
|
||||
"\n"
|
||||
"實際使用的橋接流量是將此數值乘以線材流量比例計算得出;若有設定物件的流量比例,則會再乘上該值。"
|
||||
"實際使用的橋接流量是將此數值乘以線材流量比例計算得出;若有設定物件的流量比"
|
||||
"例,則會再乘上該值。"
|
||||
|
||||
msgid "Top surface flow ratio"
|
||||
msgstr "頂部表面流量比例"
|
||||
@@ -13011,18 +13119,23 @@ msgid ""
|
||||
"supporting them from underneath, the 100% overhang speed will be applied."
|
||||
msgstr ""
|
||||
"啟用此選項可在牆可能向上捲曲的區域降低列印速度。\n"
|
||||
"例如,在列印像 Benchy 船體前端這類尖角上的懸空時,會套用額外的減速,以減少在多個層上不斷累積的捲曲。\n"
|
||||
"例如,在列印像 Benchy 船體前端這類尖角上的懸空時,會套用額外的減速,以減少在"
|
||||
"多個層上不斷累積的捲曲。\n"
|
||||
"\n"
|
||||
"一般建議開啟此選項,除非您的列印設備冷卻能力夠強,或列印速度夠慢,使得牆不會發生捲曲。 \n"
|
||||
"若以較高的外牆速度列印,此參數在減速時可能會產生牆面瑕疵,這是因為列印速度的差異可能過大,導致擠出機無法跟上所要求的流量變化。\n"
|
||||
"這些瑕疵的根本原因很可能是 PA 調校略有偏差,尤其是搭配較高的 PA 平滑時間時。\n"
|
||||
"一般建議開啟此選項,除非您的列印設備冷卻能力夠強,或列印速度夠慢,使得牆不會"
|
||||
"發生捲曲。 \n"
|
||||
"若以較高的外牆速度列印,此參數在減速時可能會產生牆面瑕疵,這是因為列印速度的"
|
||||
"差異可能過大,導致擠出機無法跟上所要求的流量變化。\n"
|
||||
"這些瑕疵的根本原因很可能是 PA 調校略有偏差,尤其是搭配較高的 PA 平滑時間"
|
||||
"時。\n"
|
||||
"\n"
|
||||
"啟用此選項時的建議:\n"
|
||||
"1. 將壓力補償平滑時間降低至 0.015 - 0.02,讓擠出機能快速回應速度變化。\n"
|
||||
"2. 提高最小列印速度,以限制減速的幅度,並減少快慢區段之間的差異。\n"
|
||||
"3. 若仍出現瑕疵,請啟用平滑擠出率 (ERS) 以進一步平滑流量轉換。\n"
|
||||
"\n"
|
||||
"注意:啟用此選項時,懸空牆會被視為懸空,這表示即使懸空牆屬於橋接的一部分,仍會套用懸空列印速度。\n"
|
||||
"注意:啟用此選項時,懸空牆會被視為懸空,這表示即使懸空牆屬於橋接的一部分,仍"
|
||||
"會套用懸空列印速度。\n"
|
||||
"例如,當牆 100% 懸空、下方沒有牆支撐時,將會套用 100% 懸空列印速度。"
|
||||
|
||||
msgid "mm/s or %"
|
||||
@@ -13087,7 +13200,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"此係數會影響邊緣所使用的材料量。\n"
|
||||
"\n"
|
||||
"實際使用的邊緣流量是將此值乘以線材流量比例計算而得;若有設定,還會再乘以物件的流量比例。\n"
|
||||
"實際使用的邊緣流量是將此值乘以線材流量比例計算而得;若有設定,還會再乘以物件"
|
||||
"的流量比例。\n"
|
||||
"\n"
|
||||
"注意:計算結果不會受首層流量比例影響。"
|
||||
|
||||
@@ -13615,7 +13729,8 @@ msgid ""
|
||||
"This option will be disabled if spiral vase mode is enabled."
|
||||
msgstr ""
|
||||
"從上方往下看時輪廓牆環擠出的方向。\n"
|
||||
"孔洞會以與輪廓相反的方向列印,以與輪廓多邊形不完整且改變方向的層保持對齊,同時部分形成孔洞的輪廓。\n"
|
||||
"孔洞會以與輪廓相反的方向列印,以與輪廓多邊形不完整且改變方向的層保持對齊,同"
|
||||
"時部分形成孔洞的輪廓。\n"
|
||||
"\n"
|
||||
"若啟用螺旋花瓶模式,此選項將被停用。"
|
||||
|
||||
@@ -14426,7 +14541,10 @@ msgid ""
|
||||
"compression buckling resistance. Filament use is preserved. No effect at "
|
||||
"~30% sparse infill density and above. Only applies when Sparse infill "
|
||||
"pattern is set to Gyroid."
|
||||
msgstr "在低填充密度時,沿 Z(垂直)軸收緊螺旋體波形,以縮短有效垂直柱長度並提升 Z 軸抗壓挫曲能力。線材用量維持不變。在約 30% 稀疏填充密度及以上時無效果。僅在稀疏填充圖案設為螺旋體時適用。"
|
||||
msgstr ""
|
||||
"在低填充密度時,沿 Z(垂直)軸收緊螺旋體波形,以縮短有效垂直柱長度並提升 Z 軸"
|
||||
"抗壓挫曲能力。線材用量維持不變。在約 30% 稀疏填充密度及以上時無效果。僅在稀疏"
|
||||
"填充圖案設為螺旋體時適用。"
|
||||
|
||||
msgid "Sparse infill pattern"
|
||||
msgstr "稀疏填充圖案"
|
||||
@@ -14941,8 +15059,10 @@ msgstr ""
|
||||
"Perlin:Perlin 雜訊,能產生更一致的紋理。\n"
|
||||
"Billow:類似 Perlin 雜訊,但更為團塊狀。\n"
|
||||
"Ridged Multifractal:具有銳利、鋸齒狀特徵的脊狀雜訊,可產生大理石般的紋理。\n"
|
||||
"Voronoi:將表面分割為 voronoi 單元,並將每個單元隨機位移一定量,可產生拼布般的紋理。\n"
|
||||
"Ripple:均勻的漣漪圖案,在原始路徑的左右兩側形成漣漪。重複的圖案,呈現編織般的外觀。"
|
||||
"Voronoi:將表面分割為 voronoi 單元,並將每個單元隨機位移一定量,可產生拼布般"
|
||||
"的紋理。\n"
|
||||
"Ripple:均勻的漣漪圖案,在原始路徑的左右兩側形成漣漪。重複的圖案,呈現編織般"
|
||||
"的外觀。"
|
||||
|
||||
msgid "Classic"
|
||||
msgstr "經典"
|
||||
@@ -15014,7 +15134,8 @@ msgstr ""
|
||||
"- 50% 會將圖案位移半個波長,等於反轉相位。\n"
|
||||
"- 100% 會將圖案位移一個完整波長,回到原始相位。\n"
|
||||
"\n"
|
||||
"此位移會依「漣漪偏移間隔層數」設定每隔指定層數套用一次,因此同一組內的各層會以相同方式列印。"
|
||||
"此位移會依「漣漪偏移間隔層數」設定每隔指定層數套用一次,因此同一組內的各層會"
|
||||
"以相同方式列印。"
|
||||
|
||||
msgid "Layers between ripple offset"
|
||||
msgstr "漣漪偏移間隔層數"
|
||||
@@ -15032,8 +15153,10 @@ msgid ""
|
||||
msgstr ""
|
||||
"指定在套用偏移之前,有多少個連續層共用相同的漣漪相位。\n"
|
||||
"例如:\n"
|
||||
"- 1 = 第 1 層以基礎漣漪圖案列印,接著第 2 層以設定的偏移移位,然後第 3 層回到基礎圖案,依此類推。\n"
|
||||
"- 3 = 第 1 至 3 層以基礎漣漪圖案列印,接著第 4 至 6 層以設定的偏移移位,然後第 7 至 9 層回到基礎圖案,依此類推。"
|
||||
"- 1 = 第 1 層以基礎漣漪圖案列印,接著第 2 層以設定的偏移移位,然後第 3 層回到"
|
||||
"基礎圖案,依此類推。\n"
|
||||
"- 3 = 第 1 至 3 層以基礎漣漪圖案列印,接著第 4 至 6 層以設定的偏移移位,然後"
|
||||
"第 7 至 9 層回到基礎圖案,依此類推。"
|
||||
|
||||
msgid "Filter out tiny gaps"
|
||||
msgstr "忽略微小間隙"
|
||||
@@ -15236,8 +15359,16 @@ msgid ""
|
||||
"below the one you know it can actually spool at.\n"
|
||||
"Set to 0 to deactivate."
|
||||
msgstr ""
|
||||
"某些物件冷卻風扇在指令值低於特定 PWM 工作週期時無法開始轉動。當設定為大於 0 時,任何非零的物件冷卻風扇指令都會被提高到至少此百分比,以確保風扇能可靠地啟動。風扇指令為 0(關閉風扇)時一律精確遵循。此限制會在所有其他風扇計算(首層漸增、層時間插值、懸空/橋接/支撐面/熨燙覆寫)之後套用,因此縮放仍會在 [此值, 100%] 範圍內運作。\n"
|
||||
"如果您的韌體已經在低於某個閾值時停用風扇(例如 Klipper 的 [fan] off_below: 0.10 會在指令工作週期低於 10% 時關閉風扇),則此選項與韌體閾值最好設定為相同的值。讓兩者相符(例如 Klipper 中的 off_below: 0.10 與此處的 10%)可確保切片軟體永遠不會發出韌體會默默捨棄的非零值,且風扇永遠不會收到低於您已知它實際能啟動轉動的值。\n"
|
||||
"某些物件冷卻風扇在指令值低於特定 PWM 工作週期時無法開始轉動。當設定為大於 0 "
|
||||
"時,任何非零的物件冷卻風扇指令都會被提高到至少此百分比,以確保風扇能可靠地啟"
|
||||
"動。風扇指令為 0(關閉風扇)時一律精確遵循。此限制會在所有其他風扇計算(首層"
|
||||
"漸增、層時間插值、懸空/橋接/支撐面/熨燙覆寫)之後套用,因此縮放仍會在 [此值, "
|
||||
"100%] 範圍內運作。\n"
|
||||
"如果您的韌體已經在低於某個閾值時停用風扇(例如 Klipper 的 [fan] off_below: "
|
||||
"0.10 會在指令工作週期低於 10% 時關閉風扇),則此選項與韌體閾值最好設定為相同"
|
||||
"的值。讓兩者相符(例如 Klipper 中的 off_below: 0.10 與此處的 10%)可確保切片"
|
||||
"軟體永遠不會發出韌體會默默捨棄的非零值,且風扇永遠不會收到低於您已知它實際能"
|
||||
"啟動轉動的值。\n"
|
||||
"設定為 0 以停用。"
|
||||
|
||||
msgid "%"
|
||||
@@ -16122,8 +16253,10 @@ msgid ""
|
||||
"in which case the fan will run at maximum allowed speed at layer \"For the "
|
||||
"first\" + 1."
|
||||
msgstr ""
|
||||
"輔助風扇速度會從「在最初的」所設定的層線性提升,至「滿速風扇在」所設定的層達到最大值。\n"
|
||||
"若「滿速風扇在」低於「在最初的」,則會忽略「滿速風扇在」,此時風扇會在「在最初的」+ 1 層以允許的最大速度運轉。"
|
||||
"輔助風扇速度會從「在最初的」所設定的層線性提升,至「滿速風扇在」所設定的層達"
|
||||
"到最大值。\n"
|
||||
"若「滿速風扇在」低於「在最初的」,則會忽略「滿速風扇在」,此時風扇會在「在最"
|
||||
"初的」+ 1 層以允許的最大速度運轉。"
|
||||
|
||||
msgid ""
|
||||
"Special auxiliary cooling fan speed, effective only for the first x layers."
|
||||
@@ -16350,7 +16483,8 @@ msgstr "變更擠出模式 G-code(列印參數)"
|
||||
msgid ""
|
||||
"This G-code is inserted when the extrusion role is changed. It runs after "
|
||||
"the machine and filament extrusion role G-code."
|
||||
msgstr "此 G-code 會在擠出模式變更時插入。它會在機器和線材擠出模式 G-code 之後執行。"
|
||||
msgstr ""
|
||||
"此 G-code 會在擠出模式變更時插入。它會在機器和線材擠出模式 G-code 之後執行。"
|
||||
|
||||
msgid "Printer type"
|
||||
msgstr "列印設備類型"
|
||||
@@ -17131,7 +17265,11 @@ msgid ""
|
||||
"can result in the Tx command being issued above the printed part. Enable "
|
||||
"this option if you want the tool change to always be issued above the wipe "
|
||||
"tower instead."
|
||||
msgstr "強制工具頭在發出換刀指令 (Tx) 之前先移動到換料塔。僅適用於使用 Type 2 換料塔的多擠出機(多工具頭)列印設備。預設情況下,Orca 會在多工具頭機器上略過此空駛,因為韌體會處理工具頭交換,這可能導致 Tx 指令在已列印零件上方發出。若您希望換刀一律改在換料塔上方發出,請啟用此選項。"
|
||||
msgstr ""
|
||||
"強制工具頭在發出換刀指令 (Tx) 之前先移動到換料塔。僅適用於使用 Type 2 換料塔"
|
||||
"的多擠出機(多工具頭)列印設備。預設情況下,Orca 會在多工具頭機器上略過此空"
|
||||
"駛,因為韌體會處理工具頭交換,這可能導致 Tx 指令在已列印零件上方發出。若您希"
|
||||
"望換刀一律改在換料塔上方發出,請啟用此選項。"
|
||||
|
||||
msgid "No sparse layers (beta)"
|
||||
msgstr "取消稀疏層(Beta)"
|
||||
@@ -18230,7 +18368,10 @@ msgid ""
|
||||
"accurate, but the G-Code will be smaller. 'Maximum wall deviation' limits "
|
||||
"'Maximum wall resolution', so if the two conflict, 'Maximum wall deviation' "
|
||||
"takes precedence."
|
||||
msgstr "「最大牆解析度」設定在降低解析度時所允許的最大偏差。若增加此值,列印會較不精確,但 G-Code 會更小。「最大牆偏差」會限制「最大牆解析度」,因此若兩者衝突,將以「最大牆偏差」為準。"
|
||||
msgstr ""
|
||||
"「最大牆解析度」設定在降低解析度時所允許的最大偏差。若增加此值,列印會較不精"
|
||||
"確,但 G-Code 會更小。「最大牆偏差」會限制「最大牆解析度」,因此若兩者衝突,"
|
||||
"將以「最大牆偏差」為準。"
|
||||
|
||||
msgid "First layer minimum wall width"
|
||||
msgstr "首層牆最小線寬"
|
||||
@@ -18524,8 +18665,7 @@ msgid "Log file"
|
||||
msgstr "記錄檔"
|
||||
|
||||
msgid "Redirects debug logging to file.\n"
|
||||
msgstr ""
|
||||
"將除錯記錄重新導向至檔案。\n"
|
||||
msgstr "將除錯記錄重新導向至檔案。\n"
|
||||
|
||||
msgid "Enable timelapse for print"
|
||||
msgstr "啟用列印過程縮時錄影"
|
||||
@@ -19504,7 +19644,9 @@ msgid ""
|
||||
"each filament's nozzle temperature must be within the recommended nozzle "
|
||||
"temperature range of the other filaments. Otherwise, nozzle clogging or "
|
||||
"printer damage may occur."
|
||||
msgstr "所選的噴嘴溫度不相容。進行多材料列印時,每種線材的噴嘴溫度都必須在其他線材的建議噴嘴溫度範圍內。否則可能會發生噴嘴堵塞或列印設備損壞。"
|
||||
msgstr ""
|
||||
"所選的噴嘴溫度不相容。進行多材料列印時,每種線材的噴嘴溫度都必須在其他線材的"
|
||||
"建議噴嘴溫度範圍內。否則可能會發生噴嘴堵塞或列印設備損壞。"
|
||||
|
||||
msgid "Sync AMS and nozzle information"
|
||||
msgstr "同步 AMS 和噴嘴資訊"
|
||||
@@ -21572,7 +21714,9 @@ msgstr "上傳失敗"
|
||||
msgid ""
|
||||
"The file has been transferred, but some unknown errors occurred. Please "
|
||||
"check the device page for the file and try to start printing again."
|
||||
msgstr "檔案已傳輸完成,但發生了一些未知的錯誤。請至裝置頁面確認該檔案,然後再次嘗試開始列印。"
|
||||
msgstr ""
|
||||
"檔案已傳輸完成,但發生了一些未知的錯誤。請至裝置頁面確認該檔案,然後再次嘗試"
|
||||
"開始列印。"
|
||||
|
||||
msgid "Failed to open file for upload."
|
||||
msgstr "無法開啟要上傳的檔案。"
|
||||
@@ -21624,7 +21768,8 @@ msgstr "無法連線至 CrealityPrint"
|
||||
msgid ""
|
||||
"Connection timed out. Please check if the printer and computer network are "
|
||||
"functioning properly, and confirm that they are on the same network."
|
||||
msgstr "連線逾時。請檢查列印設備與電腦的網路是否正常運作,並確認兩者位於相同網路。"
|
||||
msgstr ""
|
||||
"連線逾時。請檢查列印設備與電腦的網路是否正常運作,並確認兩者位於相同網路。"
|
||||
|
||||
msgid "The Hostname/IP/URL could not be parsed, please check it and try again."
|
||||
msgstr "無法解析 Hostname/IP/URL,請檢查後重試。"
|
||||
@@ -21902,12 +22047,15 @@ msgstr "執行桌面整合失敗,因為找不到應用程式目錄。"
|
||||
msgid ""
|
||||
"Performing desktop integration failed - could not create Gcodeviewer desktop "
|
||||
"file. OrcaSlicer desktop file was probably created successfully."
|
||||
msgstr "執行桌面整合失敗 - 無法建立 Gcodeviewer 桌面檔案。OrcaSlicer 桌面檔案可能已成功建立。"
|
||||
msgstr ""
|
||||
"執行桌面整合失敗 - 無法建立 Gcodeviewer 桌面檔案。OrcaSlicer 桌面檔案可能已成"
|
||||
"功建立。"
|
||||
|
||||
msgid ""
|
||||
"Performing downloader desktop integration failed - "
|
||||
"boost::filesystem::canonical did not return appimage path."
|
||||
msgstr "執行下載器桌面整合失敗 - boost::filesystem::canonical 未傳回 appimage 路徑。"
|
||||
msgstr ""
|
||||
"執行下載器桌面整合失敗 - boost::filesystem::canonical 未傳回 appimage 路徑。"
|
||||
|
||||
msgid ""
|
||||
"Performing downloader desktop integration failed - Could not find executable."
|
||||
@@ -22052,7 +22200,8 @@ msgid ""
|
||||
"inconsistencies so use carefully!"
|
||||
msgstr ""
|
||||
"偶數層反向\n"
|
||||
"您知道嗎?<b>偶數層反向</b>功能可以大幅提升懸空表面的品質。不過,它可能造成牆面不一致,請謹慎使用!"
|
||||
"您知道嗎?<b>偶數層反向</b>功能可以大幅提升懸空表面的品質。不過,它可能造成牆"
|
||||
"面不一致,請謹慎使用!"
|
||||
|
||||
#: resources/data/hints.ini: [hint:Cut Tool]
|
||||
msgid ""
|
||||
@@ -22329,6 +22478,26 @@ msgstr ""
|
||||
"您知道嗎?當列印容易翹曲的材料(如 ABS)時,適當提高熱床溫度\n"
|
||||
"可以降低翹曲的機率。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "Since version 2.4.0, OrcaSlicer syncs user profiles through Orca Cloud "
|
||||
#~ "instead of Bambu Cloud.\n"
|
||||
#~ "\n"
|
||||
#~ "To migrate your existing profiles, log in to Orca Cloud and they will be "
|
||||
#~ "transferred automatically. If any profiles are still missing afterwards, "
|
||||
#~ "follow the guide in our wiki to restore them.\n"
|
||||
#~ "\n"
|
||||
#~ "If you did not use Bambu Cloud to sync profiles, this change does not "
|
||||
#~ "affect you and you can safely ignore this message."
|
||||
#~ msgstr ""
|
||||
#~ "自 2.4.0 版本起,OrcaSlicer 透過 Orca Cloud(而非 Bambu Cloud)同步使用者"
|
||||
#~ "設定檔。\n"
|
||||
#~ "\n"
|
||||
#~ "若要移轉您現有的設定檔,請登入 Orca Cloud,設定檔將會自動轉移。若之後仍有"
|
||||
#~ "設定檔遺失,請依照我們 wiki 中的指南進行還原。\n"
|
||||
#~ "\n"
|
||||
#~ "若您先前並未使用 Bambu Cloud 同步設定檔,則此變更不會影響您,您可以放心忽"
|
||||
#~ "略此訊息。"
|
||||
|
||||
#~ msgid ""
|
||||
#~ "It is recommended to assemble objects first,\n"
|
||||
#~ "because the objects is restriced to bed \n"
|
||||
|
||||
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 218 KiB After Width: | Height: | Size: 811 B |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 811 B |
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 16 KiB |
BIN
resources/images/OrcaSlicer_gradient.png
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
resources/images/OrcaSlicer_gradient_circle.png
Normal file
|
After Width: | Height: | Size: 46 KiB |